12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903 |
- /* onsenui v2.10.8 - 2019-04-01 */
-
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.ons = factory());
- }(this, (function () { 'use strict';
-
- var onsElements = {};
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Add vendor prefix.
- *
- * @param {String} name
- * @return {String}
- */
- var prefix = function () {
- var styles = window.getComputedStyle(document.documentElement, '');
- var prefix = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || styles.OLink === '' && ['', 'o'])[1];
-
- return function (name) {
- return '-' + prefix + '-' + util$1.hyphenate(name);
- };
- }();
-
- /**
- * Minimal utility library for manipulating element's style.
- * Set element's style.
- *
- * @param {Element} element
- * @param {Object} styles
- * @return {Element}
- */
- var styler = function styler(element, style) {
- Object.keys(style).forEach(function (key) {
- if (key in element.style) {
- element.style[key] = style[key];
- } else if (prefix(key) in element.style) {
- element.style[prefix(key)] = style[key];
- } else {
- util$1.warn('No such style property: ' + key);
- }
- });
- return element;
- };
-
- /**
- * @param {Element} element
- * @param {String} styles Space-separated CSS properties to remove
- */
- styler.clear = function (element) {
- var styles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
-
- var clearlist = styles.split(/\s+/).reduce(function (r, s) {
- return r.concat([util$1.hyphenate(s), prefix(s)]);
- }, []),
- keys = [];
-
- var _loop = function _loop(i) {
- var key = element.style[i];
- if (clearlist.length === 0 || clearlist.some(function (s) {
- return key.indexOf(s) === 0;
- })) {
- keys.push(key); // Store the key to fix Safari style indexes
- }
- };
-
- for (var i = element.style.length - 1; i >= 0; i--) {
- _loop(i);
- }
-
- keys.forEach(function (key) {
- return element.style[key] = '';
- });
- element.getAttribute('style') === '' && element.removeAttribute('style');
- };
-
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
- return typeof obj;
- } : function (obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
-
-
-
-
-
-
-
-
-
-
-
- var classCallCheck = function (instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- };
-
- var createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
-
- return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
- if (staticProps) defineProperties(Constructor, staticProps);
- return Constructor;
- };
- }();
-
-
-
-
-
- var defineProperty = function (obj, key, value) {
- if (key in obj) {
- Object.defineProperty(obj, key, {
- value: value,
- enumerable: true,
- configurable: true,
- writable: true
- });
- } else {
- obj[key] = value;
- }
-
- return obj;
- };
-
- var _extends = Object.assign || function (target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
-
- for (var key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- }
-
- return target;
- };
-
- var get = function get(object, property, receiver) {
- if (object === null) object = Function.prototype;
- var desc = Object.getOwnPropertyDescriptor(object, property);
-
- if (desc === undefined) {
- var parent = Object.getPrototypeOf(object);
-
- if (parent === null) {
- return undefined;
- } else {
- return get(parent, property, receiver);
- }
- } else if ("value" in desc) {
- return desc.value;
- } else {
- var getter = desc.get;
-
- if (getter === undefined) {
- return undefined;
- }
-
- return getter.call(receiver);
- }
- };
-
- var inherits = function (subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- }
-
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
- };
-
-
-
-
-
-
-
-
-
- var objectWithoutProperties = function (obj, keys) {
- var target = {};
-
- for (var i in obj) {
- if (keys.indexOf(i) >= 0) continue;
- if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
- target[i] = obj[i];
- }
-
- return target;
- };
-
- var possibleConstructorReturn = function (self, call) {
- if (!self) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
-
- return call && (typeof call === "object" || typeof call === "function") ? call : self;
- };
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- var toConsumableArray = function (arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
-
- return arr2;
- } else {
- return Array.from(arr);
- }
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- // Save HTMLElement object before Custom Elements polyfill patch global HTMLElement.
- var NativeHTMLElement = window.HTMLElement;
-
- /**
- * @object ons.platform
- * @category util
- * @description
- * [en]Utility methods to detect current platform.[/en]
- * [ja]現在実行されているプラットフォームを検知するためのユーティリティメソッドを収めたオブジェクトです。[/ja]
- */
-
- var Platform = function () {
-
- /**
- * All elements will be rendered as if the app was running on this platform.
- * @type {String}
- */
- function Platform() {
- classCallCheck(this, Platform);
-
- this._selectedPlatform = null;
- this._ignorePlatformSelect = false;
- }
-
- /**
- * @method select
- * @signature select(platform)
- * @param {string} platform Name of the platform.
- * [en]Possible values are: "opera", "firefox", "safari", "chrome", "ie", "android", "blackberry", "ios" or "wp".[/en]
- * [ja]"opera", "firefox", "safari", "chrome", "ie", "android", "blackberry", "ios", "wp"のいずれかを指定します。[/ja]
- * @description
- * [en]Sets the platform used to render the elements. Useful for testing.[/en]
- * [ja]要素を描画するために利用するプラットフォーム名を設定します。テストに便利です。[/ja]
- */
-
-
- createClass(Platform, [{
- key: 'select',
- value: function select(platform) {
- if (typeof platform === 'string') {
- this._selectedPlatform = platform.trim().toLowerCase();
- }
- }
- }, {
- key: '_getSelectedPlatform',
- value: function _getSelectedPlatform() {
- return this._ignorePlatformSelect ? null : this._selectedPlatform;
- }
- }, {
- key: '_runOnActualPlatform',
- value: function _runOnActualPlatform(fn) {
- this._ignorePlatformSelect = true;
- var result = fn();
- this._ignorePlatformSelect = false;
-
- return result;
- }
-
- //----------------
- // General
- //----------------
- /**
- * @method isWebView
- * @signature isWebView()
- * @description
- * [en]Returns whether app is running in Cordova.[/en]
- * [ja]Cordova内で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isWebView',
- value: function isWebView() {
- if (document.readyState === 'loading' || document.readyState == 'uninitialized') {
- throw new Error('isWebView() method is available after dom contents loaded.');
- }
-
- return !!(window.cordova || window.phonegap || window.PhoneGap);
- }
-
- //----------------
- // iOS devices
- //----------------
- /**
- * @method isIPhone
- * @signature isIPhone()
- * @description
- * [en]Returns whether the device is iPhone.[/en]
- * [ja]iPhone上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIPhone',
- value: function isIPhone() {
- return (/iPhone/i.test(navigator.userAgent)
- );
- }
-
- /**
- * @method isIPhoneX
- * @signature isIPhoneX()
- * @description
- * [en]Returns whether the device is iPhone X, XS, XS Max, or XR.[/en]
- * [ja]iPhone X や XS、XS Max、または XR 上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIPhoneX',
- value: function isIPhoneX() {
- // iOS WebViews on the same iOS version have the same user agent.
- // We cannot avoid using window.screen.
- // We also cannot use cordova-plugin-device since its behavior is different between simulators and real devices.
- // This works well both in iOS Safari and (UI|WK)WebView of iPhone X.
- return this.isIPhone() && (window.screen.width === 375 && window.screen.height === 812 || // X, XS portrait
- window.screen.width === 812 && window.screen.height === 375 || // X, XS landscape
- window.screen.width === 414 && window.screen.height === 896 || // XS Max, XR portrait
- window.screen.width === 896 && window.screen.height === 414); // XS Max, XR landscape
- }
-
- /**
- * @method isIPad
- * @signature isIPad()
- * @description
- * [en]Returns whether the device is iPad.[/en]
- * [ja]iPad上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIPad',
- value: function isIPad() {
- return (/iPad/i.test(navigator.userAgent)
- );
- }
-
- /**
- * @return {Boolean}
- */
-
- }, {
- key: 'isIPod',
- value: function isIPod() {
- return (/iPod/i.test(navigator.userAgent)
- );
- }
-
- //----------------
- // iOS versions
- //----------------
- /**
- * @method isIOS
- * @signature isIOS([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the OS is iOS. By default will return manually selected platform if it is set.[/en]
- * [ja]iOS上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIOS',
- value: function isIOS(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'ios';
- }
-
- if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
- return (/iOS/i.test(device.platform)
- );
- } else {
- return (/iPhone|iPad|iPod/i.test(navigator.userAgent)
- );
- }
- }
-
- /**
- * @method isIOS7above
- * @signature isIOS7above()
- * @description
- * [en]Returns whether the iOS version is 7 or above.[/en]
- * [ja]iOS7以上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIOS7above',
- value: function isIOS7above() {
- if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
- return (/iOS/i.test(device.platform) && parseInt(device.version.split('.')[0]) >= 7
- );
- } else if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
- var ver = (navigator.userAgent.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/) || [''])[0].replace(/_/g, '.');
- return parseInt(ver.split('.')[0]) >= 7;
- }
- return false;
- }
-
- //----------------
- // iOS browsers
- //----------------
- /**
- * @method isIOSSafari
- * @signature isIOSSafari()
- * @description
- * [en]Returns whether app is running in iOS Safari.[/en]
- * [ja]iOS Safariで実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIOSSafari',
- value: function isIOSSafari() {
- var navigator = window.navigator;
- var ua = navigator.userAgent;
-
- return !!(this.isIOS() && ua.indexOf('Safari') !== -1 && ua.indexOf('Version') !== -1 && !navigator.standalone);
- }
-
- /**
- * @method isWKWebView
- * @signature isWKWebView()
- * @description
- * [en]Returns whether app is running in WKWebView.[/en]
- * [ja]WKWebViewで実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isWKWebView',
- value: function isWKWebView() {
- var lte9 = /constructor/i.test(NativeHTMLElement);
- return !!(this.isIOS() && window.webkit && window.webkit.messageHandlers && window.indexedDB && !lte9);
- }
-
- /**
- * @method isUIWebView
- * @signature isUIWebView()
- * @description
- * [en]Returns whether app is running in UIWebView.[/en]
- * [ja]UIWebViewで実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isUIWebView',
- value: function isUIWebView() {
- return !!(this.isIOS() && !this.isIOSSafari() && !this.isWKWebView());
- }
-
- //----------------
- // Android devices
- //----------------
- /**
- * @method isAndroidPhone
- * @signature isAndroidPhone()
- * @description
- * [en]Returns whether the device is Android phone.[/en]
- * [ja]Android携帯上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isAndroidPhone',
- value: function isAndroidPhone() {
- return (/Android/i.test(navigator.userAgent) && /Mobile/i.test(navigator.userAgent)
- );
- }
-
- /**
- * @method isAndroidTablet
- * @signature isAndroidTablet()
- * @description
- * [en]Returns whether the device is Android tablet.[/en]
- * [ja]Androidタブレット上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isAndroidTablet',
- value: function isAndroidTablet() {
- return (/Android/i.test(navigator.userAgent) && !/Mobile/i.test(navigator.userAgent)
- );
- }
-
- //----------------
- // Android versions
- //----------------
- /**
- * @method isAndroid
- * @signature isAndroid([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the OS is Android. By default will return manually selected platform if it is set.[/en]
- * [ja]Android上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isAndroid',
- value: function isAndroid(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'android';
- }
-
- if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
- return (/Android/i.test(device.platform)
- );
- } else {
- return (/Android/i.test(navigator.userAgent)
- );
- }
- }
-
- //----------------
- // Other devices
- //----------------
- /**
- * @method isWP
- * @signature isWP([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the OS is Windows phone. By default will return manually selected platform if it is set.[/en]
- * [ja][/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isWP',
- value: function isWP(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'wp';
- }
-
- if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
- return (/Win32NT|WinCE/i.test(device.platform)
- );
- } else {
- return (/Windows Phone|IEMobile|WPDesktop/i.test(navigator.userAgent)
- );
- }
- }
-
- /**
- * @method isBlackBerry
- * @signature isBlackBerry([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the device is BlackBerry. By default will return manually selected platform if it is set.[/en]
- * [ja]BlackBerry上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isBlackBerry',
- value: function isBlackBerry(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'blackberry';
- }
-
- if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object' && !/browser/i.test(device.platform)) {
- return (/BlackBerry/i.test(device.platform)
- );
- } else {
- return (/BlackBerry|RIM Tablet OS|BB10/i.test(navigator.userAgent)
- );
- }
- }
-
- //----------------
- // Other browsers
- //----------------
- /**
- * @method isOpera
- * @signature isOpera([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the browser is Opera. By default will return manually selected platform if it is set.[/en]
- * [ja]Opera上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isOpera',
- value: function isOpera(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'opera';
- }
-
- return !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
- }
-
- /**
- * @method isFirefox
- * @signature isFirefox([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the browser is Firefox. By default will return manually selected platform if it is set.[/en]
- * [ja]Firefox上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isFirefox',
- value: function isFirefox(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'firefox';
- }
-
- return typeof InstallTrigger !== 'undefined';
- }
-
- /**
- * @method isSafari
- * @signature isSafari([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the browser is Safari. By default will return manually selected platform if it is set.[/en]
- * [ja]Safari上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isSafari',
- value: function isSafari(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'safari';
- }
-
- return Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 || function (p) {
- return p.toString() === '[object SafariRemoteNotification]';
- }(!window['safari'] || safari.pushNotification);
- }
-
- /**
- * @method isChrome
- * @signature isChrome([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the browser is Chrome. By default will return manually selected platform if it is set.[/en]
- * [ja]Chrome上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isChrome',
- value: function isChrome(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'chrome';
- }
-
- return !!window.chrome && !(!!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0) && !(navigator.userAgent.indexOf(' Edge/') >= 0);
- }
-
- /**
- * @method isIE
- * @signature isIE([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the browser is Internet Explorer. By default will return manually selected platform if it is set.[/en]
- * [ja]Internet Explorer上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isIE',
- value: function isIE(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'ie';
- }
-
- return false || !!document.documentMode;
- }
-
- /**
- * @method isEdge
- * @signature isEdge([forceActualPlatform])
- * @param {Boolean} forceActualPlatform
- * [en]If true, selected platform is ignored and the actual platform is returned.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns whether the browser is Edge. By default will return manually selected platform if it is set.[/en]
- * [ja]Edge上で実行されているかどうかを返します。[/ja]
- * @return {Boolean}
- */
-
- }, {
- key: 'isEdge',
- value: function isEdge(forceActualPlatform) {
- if (!forceActualPlatform && this._getSelectedPlatform()) {
- return this._getSelectedPlatform() === 'edge';
- }
-
- return navigator.userAgent.indexOf(' Edge/') >= 0;
- }
-
- //----------------
- // Utility functions
- //----------------
- /**
- * @return {String}
- */
-
- }, {
- key: 'getMobileOS',
- value: function getMobileOS() {
- if (this.isAndroid()) {
- return 'android';
- } else if (this.isIOS()) {
- return 'ios';
- } else if (this.isWP()) {
- return 'wp';
- } else {
- return 'other';
- }
- }
-
- /**
- * @return {String}
- */
-
- }, {
- key: 'getIOSDevice',
- value: function getIOSDevice() {
- if (this.isIPhone()) {
- return 'iphone';
- } else if (this.isIPad()) {
- return 'ipad';
- } else if (this.isIPod()) {
- return 'ipod';
- } else {
- return 'na';
- }
- }
- }]);
- return Platform;
- }();
-
- var platform = new Platform();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var error = function error(message) {
- return util$1.throw('In PageAttributeExpression: ' + message);
- };
-
- var pageAttributeExpression = {
- _variables: {},
-
- /**
- * Define a variable.
- *
- * @param {String} name Name of the variable
- * @param {String|Function} value Value of the variable. Can be a string or a function. The function must return a string.
- * @param {Boolean} overwrite If this value is false, an error will be thrown when trying to define a variable that has already been defined.
- */
- defineVariable: function defineVariable(name, value) {
- var overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
-
- if (typeof name !== 'string') {
- error('Variable name must be a string');
- } else if (typeof value !== 'string' && typeof value !== 'function') {
- error('Variable value must be a string or a function');
- } else if (this._variables.hasOwnProperty(name) && !overwrite) {
- error('"' + name + '" is already defined');
- }
- this._variables[name] = value;
- },
-
- /**
- * Get a variable.
- *
- * @param {String} name Name of the variable.
- * @return {String|Function|null}
- */
- getVariable: function getVariable(name) {
- if (!this._variables.hasOwnProperty(name)) {
- return null;
- }
-
- return this._variables[name];
- },
-
- /**
- * Remove a variable.
- *
- * @param {String} name Name of the varaible.
- */
- removeVariable: function removeVariable(name) {
- delete this._variables[name];
- },
-
- /**
- * Get all variables.
- *
- * @return {Object}
- */
- getAllVariables: function getAllVariables() {
- return this._variables;
- },
- _parsePart: function _parsePart(part) {
- var c = void 0,
- inInterpolation = false,
- currentIndex = 0;
-
- var tokens = [];
-
- if (part.length === 0) {
- error('Unable to parse empty string');
- }
-
- for (var i = 0; i < part.length; i++) {
- c = part.charAt(i);
-
- if (c === '$' && part.charAt(i + 1) === '{') {
- if (inInterpolation) {
- error('Nested interpolation not supported');
- }
-
- var token = part.substring(currentIndex, i);
- if (token.length > 0) {
- tokens.push(part.substring(currentIndex, i));
- }
-
- currentIndex = i;
- inInterpolation = true;
- } else if (c === '}') {
- if (!inInterpolation) {
- error('} must be preceeded by ${');
- }
-
- var _token = part.substring(currentIndex, i + 1);
- if (_token.length > 0) {
- tokens.push(part.substring(currentIndex, i + 1));
- }
-
- currentIndex = i + 1;
- inInterpolation = false;
- }
- }
-
- if (inInterpolation) {
- error('Unterminated interpolation');
- }
-
- tokens.push(part.substring(currentIndex, part.length));
-
- return tokens;
- },
- _replaceToken: function _replaceToken(token) {
- var re = /^\${(.*?)}$/,
- match = token.match(re);
-
- if (match) {
- var name = match[1].trim();
- var variable = this.getVariable(name);
-
- if (variable === null) {
- error('Variable "' + name + '" does not exist');
- } else if (typeof variable === 'string') {
- return variable;
- } else {
- var rv = variable();
-
- if (typeof rv !== 'string') {
- error('Must return a string');
- }
-
- return rv;
- }
- } else {
- return token;
- }
- },
- _replaceTokens: function _replaceTokens(tokens) {
- return tokens.map(this._replaceToken.bind(this));
- },
- _parseExpression: function _parseExpression(expression) {
- return expression.split(',').map(function (part) {
- return part.trim();
- }).map(this._parsePart.bind(this)).map(this._replaceTokens.bind(this)).map(function (part) {
- return part.join('');
- });
- },
-
- /**
- * Evaluate an expression.
- *
- * @param {String} expression An page attribute expression.
- * @return {Array}
- */
- evaluate: function evaluate(expression) {
- if (!expression) {
- return [];
- }
-
- return this._parseExpression(expression);
- }
- };
-
- // Define default variables.
- pageAttributeExpression.defineVariable('mobileOS', platform.getMobileOS());
- pageAttributeExpression.defineVariable('iOSDevice', platform.getIOSDevice());
- pageAttributeExpression.defineVariable('runtime', function () {
- return platform.isWebView() ? 'cordova' : 'browser';
- });
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var internal$1 = {};
-
- internal$1.config = {
- autoStatusBarFill: true,
- animationsDisabled: false,
- warningsDisabled: false
- };
-
- internal$1.nullElement = window.document.createElement('div');
-
- /**
- * @return {Boolean}
- */
- internal$1.isEnabledAutoStatusBarFill = function () {
- return !!internal$1.config.autoStatusBarFill;
- };
-
- /**
- * @param {String} html
- * @return {String}
- */
- internal$1.normalizePageHTML = function (html) {
- return ('' + html).trim();
- };
-
- internal$1.waitDOMContentLoaded = function (callback) {
- if (window.document.readyState === 'loading' || window.document.readyState == 'uninitialized') {
- var wrappedCallback = function wrappedCallback() {
- callback();
- window.document.removeEventListener('DOMContentLoaded', wrappedCallback);
- };
- window.document.addEventListener('DOMContentLoaded', wrappedCallback);
- } else {
- setImmediate(callback);
- }
- };
-
- internal$1.autoStatusBarFill = function (action) {
- var onReady = function onReady() {
- if (internal$1.shouldFillStatusBar()) {
- action();
- }
- document.removeEventListener('deviceready', onReady);
- };
-
- if ((typeof device === 'undefined' ? 'undefined' : _typeof(device)) === 'object') {
- document.addEventListener('deviceready', onReady);
- } else if (['complete', 'interactive'].indexOf(document.readyState) === -1) {
- internal$1.waitDOMContentLoaded(onReady);
- } else {
- onReady();
- }
- };
-
- internal$1.shouldFillStatusBar = function () {
- return internal$1.isEnabledAutoStatusBarFill() && (platform.isWebView() && platform.isIOS7above() && !platform.isIPhoneX() || document.body.querySelector('.ons-status-bar-mock.ios'));
- };
-
- internal$1.templateStore = {
- _storage: {},
-
- /**
- * @param {String} key
- * @return {String/null} template
- */
- get: function get$$1(key) {
- return internal$1.templateStore._storage[key] || null;
- },
-
-
- /**
- * @param {String} key
- * @param {String} template
- */
- set: function set$$1(key, template) {
- internal$1.templateStore._storage[key] = template;
- }
- };
-
- window.document.addEventListener('_templateloaded', function (e) {
- if (e.target.nodeName.toLowerCase() === 'ons-template') {
- internal$1.templateStore.set(e.templateId, e.template);
- }
- }, false);
-
- internal$1.waitDOMContentLoaded(function () {
- register('script[type="text/ons-template"]');
- register('script[type="text/template"]');
- register('script[type="text/ng-template"]');
- register('template');
-
- function register(query) {
- var templates = window.document.querySelectorAll(query);
- for (var i = 0; i < templates.length; i++) {
- internal$1.templateStore.set(templates[i].getAttribute('id'), templates[i].textContent || templates[i].content);
- }
- }
- });
-
- /**
- * @param {String} page
- * @return {Promise}
- */
- internal$1.getTemplateHTMLAsync = function (page) {
- return new Promise(function (resolve, reject) {
- internal$1.waitDOMContentLoaded(function () {
- var cache = internal$1.templateStore.get(page);
- if (cache) {
- if (cache instanceof DocumentFragment) {
- return resolve(cache);
- }
-
- var html = typeof cache === 'string' ? cache : cache[1];
- return resolve(internal$1.normalizePageHTML(html));
- }
-
- var local = window.document.getElementById(page);
- if (local) {
- var _html = local.textContent || local.content;
- return resolve(_html);
- }
-
- var xhr = new XMLHttpRequest();
- xhr.open('GET', page, true);
- xhr.onload = function () {
- var html = xhr.responseText;
- if (xhr.status >= 400 && xhr.status < 600) {
- reject(html);
- } else {
- // Refresh script tags
- var fragment = util$1.createFragment(html);
- util$1.arrayFrom(fragment.querySelectorAll('script')).forEach(function (el) {
- var script = document.createElement('script');
- script.type = el.type || 'text/javascript';
- script.appendChild(document.createTextNode(el.text || el.textContent || el.innerHTML));
- el.parentNode.replaceChild(script, el);
- });
-
- internal$1.templateStore.set(page, fragment);
- resolve(fragment);
- }
- };
- xhr.onerror = function () {
- util$1.throw('Page template not found: ' + page);
- };
- xhr.send(null);
- });
- });
- };
-
- /**
- * @param {String} page
- * @return {Promise}
- */
- internal$1.getPageHTMLAsync = function (page) {
- var pages = pageAttributeExpression.evaluate(page);
-
- var getPage = function getPage(page) {
- if (typeof page !== 'string') {
- return Promise.reject('Must specify a page.');
- }
-
- return internal$1.getTemplateHTMLAsync(page).catch(function (error) {
- if (pages.length === 0) {
- return Promise.reject(error);
- }
-
- return getPage(pages.shift());
- });
- };
-
- return getPage(pages.shift());
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var AnimatorFactory = function () {
-
- /**
- * @param {Object} opts
- * @param {Object} opts.animators The dictionary for animator classes
- * @param {Function} opts.baseClass The base class of animators
- * @param {String} [opts.baseClassName] The name of the base class of animators
- * @param {String} [opts.defaultAnimation] The default animation name
- * @param {Object} [opts.defaultAnimationOptions] The default animation options
- */
- function AnimatorFactory(opts) {
- classCallCheck(this, AnimatorFactory);
-
- this._animators = opts.animators;
- this._baseClass = opts.baseClass;
- this._baseClassName = opts.baseClassName || opts.baseClass.name;
- this._animation = opts.defaultAnimation || 'default';
- this._animationOptions = opts.defaultAnimationOptions || {};
-
- if (!this._animators[this._animation]) {
- util$1.throw('No such animation: ' + this._animation);
- }
- }
-
- /**
- * @param {String} jsonString
- * @return {Object/null}
- */
-
-
- createClass(AnimatorFactory, [{
- key: 'setAnimationOptions',
-
-
- /**
- * @param {Object} options
- */
- value: function setAnimationOptions(options) {
- this._animationOptions = options;
- }
-
- /**
- * @param {Object} options
- * @param {String} [options.animation] The animation name
- * @param {Object} [options.animationOptions] The animation options
- * @param {Object} defaultAnimator The default animator instance
- * @return {Object} An animator instance
- */
-
- }, {
- key: 'newAnimator',
- value: function newAnimator() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var defaultAnimator = arguments[1];
-
-
- var animator = null;
-
- if (options.animation instanceof this._baseClass) {
- return options.animation;
- }
-
- var Animator = null;
-
- if (typeof options.animation === 'string') {
- Animator = this._animators[options.animation];
- }
-
- if (!Animator && defaultAnimator) {
- animator = defaultAnimator;
- } else {
- Animator = Animator || this._animators[this._animation];
-
- var animationOpts = util$1.extend({}, this._animationOptions, options.animationOptions || {}, internal$1.config.animationsDisabled ? { duration: 0, delay: 0 } : {});
-
- animator = new Animator(animationOpts);
-
- if (typeof animator === 'function') {
- animator = new animator(animationOpts); // eslint-disable-line new-cap
- }
- }
-
- if (!(animator instanceof this._baseClass)) {
- util$1.throw('"animator" is not an instance of ' + this._baseClassName);
- }
-
- return animator;
- }
- }], [{
- key: 'parseAnimationOptionsString',
- value: function parseAnimationOptionsString(jsonString) {
- try {
- if (typeof jsonString === 'string') {
- var result = util$1.animationOptionsParse(jsonString);
- if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object' && result !== null) {
- return result;
- } else {
- console.error('"animation-options" attribute must be a JSON object string: ' + jsonString);
- }
- }
- return {};
- } catch (e) {
- console.error('"animation-options" attribute must be a JSON object string: ' + jsonString);
- return {};
- }
- }
- }]);
- return AnimatorFactory;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var autoStyleEnabled = true;
-
- // Modifiers
- var modifiersMap = {
- 'quiet': 'material--flat',
- 'light': 'material--flat',
- 'outline': 'material--flat',
- 'cta': '',
- 'large--quiet': 'material--flat large',
- 'large--cta': 'large',
- 'noborder': '',
- 'tappable': ''
- };
-
- var platforms = {};
-
- platforms.android = function (element) {
-
- var elementName = element.tagName.toLowerCase();
-
- if (!util$1.hasModifier(element, 'material')) {
- var oldModifier = element.getAttribute('modifier') || '';
-
- var newModifier = oldModifier.trim().split(/\s+/).map(function (e) {
- return modifiersMap.hasOwnProperty(e) ? modifiersMap[e] : e;
- });
- newModifier.unshift('material');
-
- element.setAttribute('modifier', newModifier.join(' ').trim());
- }
-
- var elements = ['ons-alert-dialog-button', 'ons-toolbar-button', 'ons-back-button', 'ons-button', 'ons-list-item', 'ons-fab', 'ons-speed-dial', 'ons-speed-dial-item', 'ons-tab'];
-
- // Effects
- if (elements.indexOf(elementName) !== -1 && !element.hasAttribute('ripple') && !element.querySelector('ons-ripple')) {
-
- if (elementName === 'ons-list-item') {
- if (element.hasAttribute('tappable')) {
- element.setAttribute('ripple', '');
- element.removeAttribute('tappable');
- }
- } else {
- element.setAttribute('ripple', '');
- }
- }
- };
-
- platforms.ios = function (element) {
-
- // Modifiers
- if (util$1.removeModifier(element, 'material')) {
- if (util$1.removeModifier(element, 'material--flat')) {
- util$1.addModifier(element, util$1.removeModifier(element, 'large') ? 'large--quiet' : 'quiet');
- }
-
- if (!element.getAttribute('modifier')) {
- element.removeAttribute('modifier');
- }
- }
-
- // Effects
- if (element.hasAttribute('ripple')) {
- if (element.tagName.toLowerCase() === 'ons-list-item') {
- element.setAttribute('tappable', '');
- }
-
- element.removeAttribute('ripple');
- }
- };
-
- var unlocked = {
- android: true
- };
-
- var getPlatform = function getPlatform(element, force) {
- if (autoStyleEnabled && !element.hasAttribute('disable-auto-styling')) {
- var mobileOS = platform.getMobileOS();
- if (platforms.hasOwnProperty(mobileOS) && (unlocked.hasOwnProperty(mobileOS) || force)) {
- return mobileOS;
- }
- }
- return null;
- };
-
- var prepare = function prepare(element, force) {
- var p = getPlatform(element, force);
- p && platforms[p](element);
- };
-
- var mapModifier = function mapModifier(modifier, element, force) {
- if (getPlatform(element, force)) {
- return modifier.split(/\s+/).map(function (m) {
- return modifiersMap.hasOwnProperty(m) ? modifiersMap[m] : m;
- }).join(' ');
- }
- return modifier;
- };
-
- var restoreModifier = function restoreModifier(element) {
- if (getPlatform(element) === 'android') {
- var modifier = element.getAttribute('modifier') || '';
- var newModifier = mapModifier(modifier, element);
-
- if (!/(^|\s+)material($|\s+)/i.test(modifier)) {
- newModifier = 'material ' + newModifier;
- }
-
- if (newModifier !== modifier) {
- element.setAttribute('modifier', newModifier.trim());
- return true;
- }
- }
- return false;
- };
-
- var autoStyle = {
- isEnabled: function isEnabled() {
- return autoStyleEnabled;
- },
- enable: function enable() {
- return autoStyleEnabled = true;
- },
- disable: function disable() {
- return autoStyleEnabled = false;
- },
- prepare: prepare,
- mapModifier: mapModifier,
- getPlatform: getPlatform,
- restoreModifier: restoreModifier
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var ModifierUtil = function () {
- function ModifierUtil() {
- classCallCheck(this, ModifierUtil);
- }
-
- createClass(ModifierUtil, null, [{
- key: 'diff',
-
- /**
- * @param {String} last
- * @param {String} current
- */
- value: function diff(last, current) {
- last = makeDict(('' + last).trim());
- current = makeDict(('' + current).trim());
-
- var removed = Object.keys(last).reduce(function (result, token) {
- if (!current[token]) {
- result.push(token);
- }
- return result;
- }, []);
-
- var added = Object.keys(current).reduce(function (result, token) {
- if (!last[token]) {
- result.push(token);
- }
- return result;
- }, []);
-
- return { added: added, removed: removed };
-
- function makeDict(modifier) {
- var dict = {};
- ModifierUtil.split(modifier).forEach(function (token) {
- return dict[token] = token;
- });
- return dict;
- }
- }
-
- /**
- * @param {Object} diff
- * @param {Array} diff.removed
- * @param {Array} diff.added
- * @param {Object} classList
- * @param {String} template
- */
-
- }, {
- key: 'applyDiffToClassList',
- value: function applyDiffToClassList(diff, classList, template) {
- diff.added.map(function (modifier) {
- return template.replace(/\*/g, modifier);
- }).forEach(function (klass) {
- return klass.split(/\s+/).forEach(function (k) {
- return classList.add(k);
- });
- });
-
- diff.removed.map(function (modifier) {
- return template.replace(/\*/g, modifier);
- }).forEach(function (klass) {
- return klass.split(/\s+/).forEach(function (k) {
- return classList.remove(k);
- });
- });
- }
-
- /**
- * @param {Object} diff
- * @param {Array} diff.removed
- * @param {Array} diff.added
- * @param {HTMLElement} element
- * @param {Object} scheme
- */
-
- }, {
- key: 'applyDiffToElement',
- value: function applyDiffToElement(diff, element, scheme) {
- Object.keys(scheme).forEach(function (selector) {
- var targetElements = !selector || util$1.match(element, selector) ? [element] : Array.prototype.filter.call(element.querySelectorAll(selector), function (targetElement) {
- return !util$1.findParent(targetElement, element.tagName, function (parent) {
- return parent === element;
- });
- });
-
- for (var i = 0; i < targetElements.length; i++) {
- ModifierUtil.applyDiffToClassList(diff, targetElements[i].classList, scheme[selector]);
- }
- });
- }
-
- /**
- * @param {String} last
- * @param {String} current
- * @param {HTMLElement} element
- * @param {Object} scheme
- */
-
- }, {
- key: 'onModifierChanged',
- value: function onModifierChanged(last, current, element, scheme) {
- ModifierUtil.applyDiffToElement(ModifierUtil.diff(last, current), element, scheme);
- autoStyle.restoreModifier(element);
- }
- }, {
- key: 'refresh',
- value: function refresh(element, scheme) {
- ModifierUtil.applyDiffToElement(ModifierUtil.diff('', element.getAttribute('modifier') || ''), element, scheme);
- }
-
- /**
- * @param {HTMLElement} element
- * @param {Object} scheme
- */
-
- }, {
- key: 'initModifier',
- value: function initModifier(element, scheme) {
- var modifier = element.getAttribute('modifier');
- if (typeof modifier !== 'string') {
- return;
- }
-
- ModifierUtil.applyDiffToElement({
- removed: [],
- added: ModifierUtil.split(modifier)
- }, element, scheme);
- }
- }, {
- key: 'split',
- value: function split(modifier) {
- if (typeof modifier !== 'string') {
- return [];
- }
-
- return modifier.trim().split(/ +/).filter(function (token) {
- return token !== '';
- });
- }
-
- /**
- * Add modifier token to an element.
- */
-
- }, {
- key: 'addModifier',
- value: function addModifier(element, modifierToken) {
- if (!element.hasAttribute('modifier')) {
- element.setAttribute('modifier', modifierToken);
- } else {
- var tokens = ModifierUtil.split(element.getAttribute('modifier'));
- if (tokens.indexOf(modifierToken) == -1) {
- tokens.push(modifierToken);
- element.setAttribute('modifier', tokens.join(' '));
- }
- }
- }
-
- /**
- * Remove modifier token from an element.
- */
-
- }, {
- key: 'removeModifier',
- value: function removeModifier(element, modifierToken) {
- if (element.hasAttribute('modifier')) {
- var tokens = ModifierUtil.split(element.getAttribute('modifier'));
- var index = tokens.indexOf(modifierToken);
- if (index !== -1) {
- tokens.splice(index, 1);
- element.setAttribute('modifier', tokens.join(' '));
- }
- }
- }
- }]);
- return ModifierUtil;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var util$3 = {
- _ready: false,
-
- _domContentLoaded: false,
-
- _onDOMContentLoaded: function _onDOMContentLoaded() {
- util$3._domContentLoaded = true;
-
- if (platform.isWebView()) {
- window.document.addEventListener('deviceready', function () {
- util$3._ready = true;
- }, false);
- } else {
- util$3._ready = true;
- }
- },
-
- addBackButtonListener: function addBackButtonListener(fn) {
- if (!this._domContentLoaded) {
- throw new Error('This method is available after DOMContentLoaded');
- }
-
- if (this._ready) {
- window.document.addEventListener('backbutton', fn, false);
- } else {
- window.document.addEventListener('deviceready', function () {
- window.document.addEventListener('backbutton', fn, false);
- });
- }
- },
-
- removeBackButtonListener: function removeBackButtonListener(fn) {
- if (!this._domContentLoaded) {
- throw new Error('This method is available after DOMContentLoaded');
- }
-
- if (this._ready) {
- window.document.removeEventListener('backbutton', fn, false);
- } else {
- window.document.addEventListener('deviceready', function () {
- window.document.removeEventListener('backbutton', fn, false);
- });
- }
- }
- };
- window.addEventListener('DOMContentLoaded', function () {
- return util$3._onDOMContentLoaded();
- }, false);
-
- var HandlerRepository = {
- _store: {},
-
- _genId: function () {
- var i = 0;
- return function () {
- return i++;
- };
- }(),
-
- set: function set$$1(element, handler) {
- if (element.dataset.deviceBackButtonHandlerId) {
- this.remove(element);
- }
- var id = element.dataset.deviceBackButtonHandlerId = HandlerRepository._genId();
- this._store[id] = handler;
- },
-
- remove: function remove(element) {
- if (element.dataset.deviceBackButtonHandlerId) {
- delete this._store[element.dataset.deviceBackButtonHandlerId];
- delete element.dataset.deviceBackButtonHandlerId;
- }
- },
-
- get: function get$$1(element) {
- if (!element.dataset.deviceBackButtonHandlerId) {
- return undefined;
- }
-
- var id = element.dataset.deviceBackButtonHandlerId;
-
- if (!this._store[id]) {
- throw new Error();
- }
-
- return this._store[id];
- },
-
- has: function has(element) {
- if (!element.dataset) {
- return false;
- }
-
- var id = element.dataset.deviceBackButtonHandlerId;
-
- return !!this._store[id];
- }
- };
-
- var DeviceBackButtonDispatcher = function () {
- function DeviceBackButtonDispatcher() {
- classCallCheck(this, DeviceBackButtonDispatcher);
-
- this._isEnabled = false;
- this._boundCallback = this._callback.bind(this);
- }
-
- /**
- * Enable to handle 'backbutton' events.
- */
-
-
- createClass(DeviceBackButtonDispatcher, [{
- key: 'enable',
- value: function enable() {
- if (!this._isEnabled) {
- util$3.addBackButtonListener(this._boundCallback);
- this._isEnabled = true;
- }
- }
-
- /**
- * Disable to handle 'backbutton' events.
- */
-
- }, {
- key: 'disable',
- value: function disable() {
- if (this._isEnabled) {
- util$3.removeBackButtonListener(this._boundCallback);
- this._isEnabled = false;
- }
- }
-
- /**
- * Fire a 'backbutton' event manually.
- */
-
- }, {
- key: 'fireDeviceBackButtonEvent',
- value: function fireDeviceBackButtonEvent() {
- var event = document.createEvent('Event');
- event.initEvent('backbutton', true, true);
- document.dispatchEvent(event);
- }
- }, {
- key: '_callback',
- value: function _callback() {
- this._dispatchDeviceBackButtonEvent();
- }
-
- /**
- * @param {HTMLElement} element
- * @param {Function} callback
- */
-
- }, {
- key: 'createHandler',
- value: function createHandler(element, callback) {
- if (!(element instanceof HTMLElement)) {
- throw new Error('element must be an instance of HTMLElement');
- }
-
- if (!(callback instanceof Function)) {
- throw new Error('callback must be an instance of Function');
- }
-
- var handler = {
- _callback: callback,
- _element: element,
-
- disable: function disable() {
- HandlerRepository.remove(element);
- },
-
- setListener: function setListener(callback) {
- this._callback = callback;
- },
-
- enable: function enable() {
- HandlerRepository.set(element, this);
- },
-
- isEnabled: function isEnabled() {
- return HandlerRepository.get(element) === this;
- },
-
- destroy: function destroy() {
- HandlerRepository.remove(element);
- this._callback = this._element = null;
- }
- };
-
- handler.enable();
-
- return handler;
- }
- }, {
- key: '_dispatchDeviceBackButtonEvent',
- value: function _dispatchDeviceBackButtonEvent() {
- var tree = this._captureTree();
-
- var element = this._findHandlerLeafElement(tree);
-
- var handler = HandlerRepository.get(element);
- handler._callback(createEvent(element));
-
- function createEvent(element) {
- return {
- _element: element,
- callParentHandler: function callParentHandler() {
- var parent = this._element.parentNode;
-
- while (parent) {
- handler = HandlerRepository.get(parent);
- if (handler) {
- return handler._callback(createEvent(parent));
- }
- parent = parent.parentNode;
- }
- }
- };
- }
- }
-
- /**
- * @return {Object}
- */
-
- }, {
- key: '_captureTree',
- value: function _captureTree() {
- return createTree(document.body);
-
- function createTree(element) {
- var tree = {
- element: element,
- children: Array.prototype.concat.apply([], arrayOf(element.children).map(function (childElement) {
-
- if (childElement.style.display === 'none' || childElement._isShown === false) {
- return [];
- }
-
- if (childElement.children.length === 0 && !HandlerRepository.has(childElement)) {
- return [];
- }
-
- var result = createTree(childElement);
-
- if (result.children.length === 0 && !HandlerRepository.has(result.element)) {
- return [];
- }
-
- return [result];
- }))
- };
-
- if (!HandlerRepository.has(tree.element)) {
- for (var i = 0; i < tree.children.length; i++) {
- var subTree = tree.children[i];
- if (HandlerRepository.has(subTree.element)) {
- return subTree;
- }
- }
- }
-
- return tree;
- }
-
- function arrayOf(target) {
- var result = [];
- for (var i = 0; i < target.length; i++) {
- result.push(target[i]);
- }
- return result;
- }
- }
-
- /**
- * @param {Object} tree
- * @return {HTMLElement}
- */
-
- }, {
- key: '_findHandlerLeafElement',
- value: function _findHandlerLeafElement(tree) {
- return find(tree);
-
- function find(node) {
- if (node.children.length === 0) {
- return node.element;
- }
-
- if (node.children.length === 1) {
- return find(node.children[0]);
- }
-
- return node.children.map(function (childNode) {
- return childNode.element;
- }).reduce(function (left, right) {
- if (!left) {
- return right;
- }
-
- var leftZ = parseInt(window.getComputedStyle(left, '').zIndex, 10);
- var rightZ = parseInt(window.getComputedStyle(right, '').zIndex, 10);
-
- if (!isNaN(leftZ) && !isNaN(rightZ)) {
- return leftZ > rightZ ? left : right;
- }
-
- throw new Error('Capturing backbutton-handler is failure.');
- }, null);
- }
- }
- }]);
- return DeviceBackButtonDispatcher;
- }();
-
- var deviceBackButtonDispatcher = new DeviceBackButtonDispatcher();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
- internal$1.AnimatorFactory = AnimatorFactory;
- internal$1.ModifierUtil = ModifierUtil;
- internal$1.dbbDispatcher = deviceBackButtonDispatcher;
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var startsWith = function startsWith(s, c) {
- return s.substr(0, c.length) === c;
- };
- var endsWith = function endsWith(s, c) {
- return s.substr(s.length - c.length, c.length) === c;
- };
- var unwrap = function unwrap(s) {
- return s.slice(1, -1);
- };
- var isObjectString = function isObjectString(s) {
- return startsWith(s, '{') && endsWith(s, '}');
- };
- var isArrayString = function isArrayString(s) {
- return startsWith(s, '[') && endsWith(s, ']');
- };
- var isQuotedString = function isQuotedString(s) {
- return startsWith(s, '\'') && endsWith(s, '\'') || startsWith(s, '"') && endsWith(s, '"');
- };
-
- var error$1 = function error(token, string, originalString) {
- throw new Error('Unexpected token \'' + token + '\' at position ' + (originalString.length - string.length - 1) + ' in string: \'' + originalString + '\'');
- };
-
- var processToken = function processToken(token, string, originalString) {
- if (token === 'true' || token === 'false') {
- return token === 'true';
- } else if (isQuotedString(token)) {
- return unwrap(token);
- } else if (!isNaN(token)) {
- return +token;
- } else if (isObjectString(token)) {
- return parseObject(unwrap(token));
- } else if (isArrayString(token)) {
- return parseArray(unwrap(token));
- } else {
- error$1(token, string, originalString);
- }
- };
-
- var nextToken = function nextToken(string) {
- string = string.trim();
- var limit = string.length;
-
- if (string[0] === ':' || string[0] === ',') {
-
- limit = 1;
- } else if (string[0] === '{' || string[0] === '[') {
-
- var c = string.charCodeAt(0);
- var nestedObject = 1;
- for (var i = 1; i < string.length; i++) {
- if (string.charCodeAt(i) === c) {
- nestedObject++;
- } else if (string.charCodeAt(i) === c + 2) {
- nestedObject--;
- if (nestedObject === 0) {
- limit = i + 1;
- break;
- }
- }
- }
- } else if (string[0] === '\'' || string[0] === '"') {
-
- for (var _i = 1; _i < string.length; _i++) {
- if (string[_i] === string[0]) {
- limit = _i + 1;
- break;
- }
- }
- } else {
-
- for (var _i2 = 1; _i2 < string.length; _i2++) {
- if ([' ', ',', ':'].indexOf(string[_i2]) !== -1) {
- limit = _i2;
- break;
- }
- }
- }
-
- return string.slice(0, limit);
- };
-
- var parseObject = function parseObject(string) {
- var isValidKey = function isValidKey(key) {
- return (/^[A-Z_$][A-Z0-9_$]*$/i.test(key)
- );
- };
-
- string = string.trim();
- var originalString = string;
- var object = {};
- var readingKey = true,
- key = void 0,
- previousToken = void 0,
- token = void 0;
-
- while (string.length > 0) {
- previousToken = token;
- token = nextToken(string);
- string = string.slice(token.length, string.length).trim();
-
- if (token === ':' && (!readingKey || !previousToken || previousToken === ',') || token === ',' && readingKey || token !== ':' && token !== ',' && previousToken && previousToken !== ',' && previousToken !== ':') {
- error$1(token, string, originalString);
- } else if (token === ':' && readingKey && previousToken) {
- previousToken = isQuotedString(previousToken) ? unwrap(previousToken) : previousToken;
- if (isValidKey(previousToken)) {
- key = previousToken;
- readingKey = false;
- } else {
- throw new Error('Invalid key token \'' + previousToken + '\' at position 0 in string: \'' + originalString + '\'');
- }
- } else if (token === ',' && !readingKey && previousToken) {
- object[key] = processToken(previousToken, string, originalString);
- readingKey = true;
- }
- }
-
- if (token) {
- object[key] = processToken(token, string, originalString);
- }
-
- return object;
- };
-
- var parseArray = function parseArray(string) {
- string = string.trim();
- var originalString = string;
- var array = [];
- var previousToken = void 0,
- token = void 0;
-
- while (string.length > 0) {
- previousToken = token;
- token = nextToken(string);
- string = string.slice(token.length, string.length).trim();
-
- if (token === ',' && (!previousToken || previousToken === ',')) {
- error$1(token, string, originalString);
- } else if (token === ',') {
- array.push(processToken(previousToken, string, originalString));
- }
- }
-
- if (token) {
- if (token !== ',') {
- array.push(processToken(token, string, originalString));
- } else {
- error$1(token, string, originalString);
- }
- }
-
- return array;
- };
-
- var parse = function parse(string) {
- string = string.trim();
-
- if (isObjectString(string)) {
- return parseObject(unwrap(string));
- } else if (isArrayString(string)) {
- return parseArray(unwrap(string));
- } else {
- throw new Error('Provided string must be object or array like: ' + string);
- }
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var util$1 = {};
- var errorPrefix = '[Onsen UI]';
-
- util$1.globals = {
- fabOffset: 0,
- errorPrefix: errorPrefix,
- supportsPassive: false
- };
-
- platform._runOnActualPlatform(function () {
- util$1.globals.actualMobileOS = platform.getMobileOS();
- util$1.globals.isUIWebView = platform.isUIWebView();
- util$1.globals.isWKWebView = platform.isWKWebView();
- });
-
- try {
- var opts = Object.defineProperty({}, 'passive', {
- get: function get$$1() {
- util$1.globals.supportsPassive = true;
- }
- });
- window.addEventListener('testPassive', null, opts);
- window.removeEventListener('testPassive', null, opts);
- } catch (e) {
-
- }
-
- /**
- * @param {Element} el Target
- * @param {String} name Event name
- * @param {Function} handler Event handler
- * @param {Object} [opt] Event options (passive, capture...)
- * @param {Boolean} [isGD] If comes from GestureDetector. Just for testing.
- */
- util$1.addEventListener = function (el, name, handler, opt, isGD) {
- el.addEventListener(name, handler, util$1.globals.supportsPassive ? opt : (opt || {}).capture);
- };
- util$1.removeEventListener = function (el, name, handler, opt, isGD) {
- el.removeEventListener(name, handler, util$1.globals.supportsPassive ? opt : (opt || {}).capture);
- };
-
- /**
- * @param {String/Function} query dot class name or node name or matcher function.
- * @return {Function}
- */
- util$1.prepareQuery = function (query) {
- return query instanceof Function ? query : function (element) {
- return util$1.match(element, query);
- };
- };
-
- /**
- * @param {Element} e
- * @param {String/Function} s CSS Selector.
- * @return {Boolean}
- */
- util$1.match = function (e, s) {
- return (e.matches || e.webkitMatchesSelector || e.mozMatchesSelector || e.msMatchesSelector).call(e, s);
- };
-
- /**
- * @param {Element} element
- * @param {String/Function} query dot class name or node name or matcher function.
- * @return {HTMLElement/null}
- */
- util$1.findChild = function (element, query) {
- var match = util$1.prepareQuery(query);
-
- // Caution: `element.children` is `undefined` in some environments if `element` is `svg`
- for (var i = 0; i < element.childNodes.length; i++) {
- var node = element.childNodes[i];
- if (node.nodeType !== Node.ELEMENT_NODE) {
- // process only element nodes
- continue;
- }
- if (match(node)) {
- return node;
- }
- }
- return null;
- };
-
- /**
- * @param {Element} element
- * @param {String/Function} query dot class name or node name or matcher function.
- * @return {HTMLElement/null}
- */
- util$1.findParent = function (element, query, until) {
- var match = util$1.prepareQuery(query);
-
- var parent = element.parentNode;
- for (;;) {
- if (!parent || parent === document || parent instanceof DocumentFragment || until && until(parent)) {
- return null;
- } else if (match(parent)) {
- return parent;
- }
- parent = parent.parentNode;
- }
- };
-
- /**
- * @param {Element} element
- * @return {boolean}
- */
- util$1.isAttached = function (element) {
- return document.body.contains(element);
- };
-
- /**
- * @param {Element} element
- * @return {boolean}
- */
- util$1.hasAnyComponentAsParent = function (element) {
- while (element && document.documentElement !== element) {
- element = element.parentNode;
- if (element && element.nodeName.toLowerCase().match(/(ons-navigator|ons-tabbar|ons-modal)/)) {
- return true;
- }
- }
- return false;
- };
-
- /**
- * @param {Object} element
- * @return {Array}
- */
- util$1.getAllChildNodes = function (element) {
- var _ref;
-
- return (_ref = [element]).concat.apply(_ref, toConsumableArray(Array.from(element.children).map(function (childEl) {
- return util$1.getAllChildNodes(childEl);
- })));
- };
-
- /**
- * @param {Element} element
- * @return {boolean}
- */
- util$1.isPageControl = function (element) {
- return element.nodeName.match(/^ons-(navigator|splitter|tabbar|page)$/i);
- };
-
- /**
- * @param {Element} element
- * @param {String} action to propagate
- */
- util$1.propagateAction = function (element, action) {
- for (var i = 0; i < element.childNodes.length; i++) {
- var child = element.childNodes[i];
- if (child[action] instanceof Function) {
- child[action]();
- } else {
- util$1.propagateAction(child, action);
- }
- }
- };
-
- /**
- * @param {String} string - string to be camelized
- * @return {String} Camelized string
- */
- util$1.camelize = function (string) {
- return string.toLowerCase().replace(/-([a-z])/g, function (m, l) {
- return l.toUpperCase();
- });
- };
-
- /**
- * @param {String} string - string to be hyphenated
- * @return {String} Hyphenated string
- */
- util$1.hyphenate = function (string) {
- return string.replace(/([a-zA-Z])([A-Z])/g, '$1-$2').toLowerCase();
- };
-
- /**
- * @param {String} selector - tag and class only
- * @param {Object} style
- * @param {Element}
- */
- util$1.create = function () {
- var selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
- var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var classList = selector.split('.');
- var element = document.createElement(classList.shift() || 'div');
-
- if (classList.length) {
- element.className = classList.join(' ');
- }
-
- styler(element, style);
-
- return element;
- };
-
- /**
- * @param {String} html
- * @return {Element}
- */
- util$1.createElement = function (html) {
- var wrapper = document.createElement('div');
-
- if (html instanceof DocumentFragment) {
- wrapper.appendChild(document.importNode(html, true));
- } else {
- wrapper.innerHTML = html.trim();
- }
-
- if (wrapper.children.length > 1) {
- util$1.throw('HTML template must contain a single root element');
- }
-
- var element = wrapper.children[0];
- wrapper.children[0].remove();
- return element;
- };
-
- /**
- * @param {String} html
- * @return {HTMLFragment}
- */
- util$1.createFragment = function (html) {
- var template = document.createElement('template');
- template.innerHTML = html;
- return document.importNode(template.content, true);
- };
-
- /*
- * @param {Object} dst Destination object.
- * @param {...Object} src Source object(s).
- * @returns {Object} Reference to `dst`.
- */
- util$1.extend = function (dst) {
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- args[_key - 1] = arguments[_key];
- }
-
- for (var i = 0; i < args.length; i++) {
- if (args[i]) {
- var keys = Object.keys(args[i]);
- for (var j = 0; j < keys.length; j++) {
- var key = keys[j];
- dst[key] = args[i][key];
- }
- }
- }
-
- return dst;
- };
-
- /**
- * @param {Object} arrayLike
- * @return {Array}
- */
- util$1.arrayFrom = function (arrayLike) {
- return Array.prototype.slice.apply(arrayLike);
- };
-
- /**
- * @param {String} jsonString
- * @param {Object} [failSafe]
- * @return {Object}
- */
- util$1.parseJSONObjectSafely = function (jsonString) {
- var failSafe = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- try {
- var result = JSON.parse('' + jsonString);
- if ((typeof result === 'undefined' ? 'undefined' : _typeof(result)) === 'object' && result !== null) {
- return result;
- }
- } catch (e) {
- return failSafe;
- }
- return failSafe;
- };
-
- /**
- * @param {String} path - path such as 'myApp.controllers.data.loadData'
- * @return {Any} - whatever is located at that path
- */
- util$1.findFromPath = function (path) {
- path = path.split('.');
- var el = window,
- key;
- while (key = path.shift()) {
- // eslint-disable-line no-cond-assign
- el = el[key];
- }
- return el;
- };
-
- /**
- * @param {HTMLElement} container - Page or page-container that implements 'topPage'
- * @return {HTMLElement|null} - Visible page element or null if not found.
- */
- util$1.getTopPage = function (container) {
- return container && (container.tagName.toLowerCase() === 'ons-page' ? container : container.topPage) || null;
- };
-
- /**
- * @param {HTMLElement} container - Element where the search begins
- * @return {HTMLElement|null} - Page element that contains the visible toolbar or null.
- */
- util$1.findToolbarPage = function (container) {
- var page = util$1.getTopPage(container);
-
- if (page) {
- if (page._canAnimateToolbar()) {
- return page;
- }
-
- for (var i = 0; i < page._contentElement.children.length; i++) {
- var nextPage = util$1.getTopPage(page._contentElement.children[i]);
- if (nextPage && !/ons-tabbar/i.test(page._contentElement.children[i].tagName)) {
- return util$1.findToolbarPage(nextPage);
- }
- }
- }
-
- return null;
- };
-
- /**
- * @param {Element} element
- * @param {String} eventName
- * @param {Object} [detail]
- * @return {CustomEvent}
- */
- util$1.triggerElementEvent = function (target, eventName) {
- var detail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
-
- var event = new CustomEvent(eventName, {
- bubbles: true,
- cancelable: true,
- detail: detail
- });
-
- Object.keys(detail).forEach(function (key) {
- event[key] = detail[key];
- });
-
- target.dispatchEvent(event);
-
- return event;
- };
-
- /**
- * @param {Element} target
- * @param {String} modifierName
- * @return {Boolean}
- */
- util$1.hasModifier = function (target, modifierName) {
- if (!target.hasAttribute('modifier')) {
- return false;
- }
-
- return RegExp('(^|\\s+)' + modifierName + '($|\\s+)', 'i').test(target.getAttribute('modifier'));
- };
-
- /**
- * @param {Element} target
- * @param {String} modifierName
- * @param {Object} options.autoStyle Maps the modifierName to the corresponding styled modifier.
- * @param {Object} options.forceAutoStyle Ignores platform limitation.
- * @return {Boolean} Whether it was added or not.
- */
- util$1.addModifier = function (target, modifierName) {
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- if (options.autoStyle) {
- modifierName = autoStyle.mapModifier(modifierName, target, options.forceAutoStyle);
- }
-
- if (util$1.hasModifier(target, modifierName)) {
- return false;
- }
-
- target.setAttribute('modifier', ((target.getAttribute('modifier') || '') + ' ' + modifierName).trim());
- return true;
- };
-
- /**
- * @param {Element} target
- * @param {String} modifierName
- * @param {Object} options.autoStyle Maps the modifierName to the corresponding styled modifier.
- * @param {Object} options.forceAutoStyle Ignores platform limitation.
- * @return {Boolean} Whether it was found or not.
- */
- util$1.removeModifier = function (target, modifierName) {
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- if (options.autoStyle) {
- modifierName = autoStyle.mapModifier(modifierName, target, options.forceAutoStyle);
- }
-
- if (!target.getAttribute('modifier') || !util$1.hasModifier(target, modifierName)) {
- return false;
- }
-
- var newModifiers = target.getAttribute('modifier').split(/\s+/).filter(function (m) {
- return m && m !== modifierName;
- });
- newModifiers.length ? target.setAttribute('modifier', newModifiers.join(' ')) : target.removeAttribute('modifier');
- return true;
- };
-
- /**
- * @param {Element} target
- * @param {String} modifierName
- * @param {Boolean} options.force Forces modifier to be added or removed.
- * @param {Object} options.autoStyle Maps the modifierName to the corresponding styled modifier.
- * @param {Boolean} options.forceAutoStyle Ignores platform limitation.
- * @return {Boolean} Whether it was found or not.
- */
- util$1.toggleModifier = function () {
- var options = arguments.length > 2 ? arguments.length <= 2 ? undefined : arguments[2] : {};
- var force = typeof options === 'boolean' ? options : options.force;
-
- var toggle = typeof force === 'boolean' ? force : !util$1.hasModifier.apply(util$1, arguments);
- toggle ? util$1.addModifier.apply(util$1, arguments) : util$1.removeModifier.apply(util$1, arguments);
- };
-
- /**
- * @param {Element} el
- * @param {String} defaultClass
- * @param {Object} scheme
- */
- util$1.restoreClass = function (el, defaultClass, scheme) {
- defaultClass.split(/\s+/).forEach(function (c) {
- return c !== '' && !el.classList.contains(c) && el.classList.add(c);
- });
- el.hasAttribute('modifier') && ModifierUtil.refresh(el, scheme);
- };
-
- // TODO: FIX
- util$1.updateParentPosition = function (el) {
- if (!el._parentUpdated && el.parentElement) {
- if (window.getComputedStyle(el.parentElement).getPropertyValue('position') === 'static') {
- el.parentElement.style.position = 'relative';
- }
- el._parentUpdated = true;
- }
- };
-
- util$1.toggleAttribute = function (element, name, value) {
- if (value) {
- element.setAttribute(name, typeof value === 'boolean' ? '' : value);
- } else {
- element.removeAttribute(name);
- }
- };
-
- util$1.bindListeners = function (element, listenerNames) {
- listenerNames.forEach(function (name) {
- var boundName = name.replace(/^_[a-z]/, '_bound' + name[1].toUpperCase());
- element[boundName] = element[boundName] || element[name].bind(element);
- });
- };
-
- util$1.each = function (obj, f) {
- return Object.keys(obj).forEach(function (key) {
- return f(key, obj[key]);
- });
- };
-
- /**
- * @param {Element} target
- * @param {boolean} hasRipple
- * @param {Object} attrs
- */
- util$1.updateRipple = function (target, hasRipple) {
- var attrs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- if (hasRipple === undefined) {
- hasRipple = target.hasAttribute('ripple');
- }
-
- var rippleElement = util$1.findChild(target, 'ons-ripple');
-
- if (hasRipple) {
- if (!rippleElement) {
- var element = document.createElement('ons-ripple');
- Object.keys(attrs).forEach(function (key) {
- return element.setAttribute(key, attrs[key]);
- });
- target.insertBefore(element, target.firstChild);
- }
- } else if (rippleElement) {
- rippleElement.remove();
- }
- };
-
- /**
- * @param {String}
- * @return {Object}
- */
- util$1.animationOptionsParse = parse;
-
- /**
- * @param {*} value
- */
- util$1.isInteger = function (value) {
- return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
- };
-
- /**
- * @return {Object} Deferred promise.
- */
- util$1.defer = function () {
- var deferred = {};
- deferred.promise = new Promise(function (resolve, reject) {
- deferred.resolve = resolve;
- deferred.reject = reject;
- });
- return deferred;
- };
-
- /**
- * Show warnings when they are enabled.
- *
- * @param {*} arguments to console.warn
- */
- util$1.warn = function () {
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- if (!internal$1.config.warningsDisabled) {
- var _console;
-
- (_console = console).warn.apply(_console, [errorPrefix].concat(args));
- }
- };
-
- util$1.throw = function (message) {
- throw new Error(errorPrefix + ' ' + message);
- };
-
- util$1.throwAbstract = function () {
- return util$1.throw('Cannot instantiate abstract class');
- };
- util$1.throwMember = function () {
- return util$1.throw('Class member must be implemented');
- };
- util$1.throwPageLoader = function () {
- return util$1.throw('First parameter should be an instance of PageLoader');
- };
- util$1.throwAnimator = function (el) {
- return util$1.throw('"Animator" param must inherit ' + el + 'Animator');
- };
-
- var prevent = function prevent(e) {
- return e.cancelable && e.preventDefault();
- };
-
- /**
- * Prevent scrolling while draging horizontally on iOS.
- *
- * @param {gd} GestureDetector instance
- */
- util$1.iosPreventScroll = function (gd) {
- if (util$1.globals.actualMobileOS === 'ios') {
- var clean = function clean(e) {
- gd.off('touchmove', prevent);
- gd.off('dragend', clean);
- };
-
- gd.on('touchmove', prevent);
- gd.on('dragend', clean);
- }
- };
-
- /**
- * Prevents scroll in underlying pages on iOS. See #2220 #2274 #1949
- *
- * @param {el} HTMLElement that prevents the events
- * @param {add} Boolean Add or remove event listeners
- */
- util$1.iosPageScrollFix = function (add) {
- // Full fix - May cause issues with UIWebView's momentum scroll
- if (util$1.globals.actualMobileOS === 'ios') {
- document.body.classList.toggle('ons-ios-scroll', add); // Allows custom and localized fixes (#2274)
- if (!util$1.globals.isUIWebView || internal$1.config.forceUIWebViewScrollFix) {
- document.body.classList.toggle('ons-ios-scroll-fix', add);
- }
- }
- };
- util$1.iosMaskScrollFix = function (el, add) {
- // Half fix - only prevents scroll on masks
- if (util$1.globals.isUIWebView) {
- var action = (add ? 'add' : 'remove') + 'EventListener';
- el[action]('touchmove', prevent, false);
- }
- };
-
- /**
- * Distance and deltaTime filter some weird dragstart events that are not fired immediately.
- *
- * @param {event}
- */
- util$1.isValidGesture = function (event) {
- return event.gesture !== undefined && (event.gesture.distance <= 15 || event.gesture.deltaTime <= 100);
- };
-
- util$1.checkMissingImport = function () {
- for (var _len3 = arguments.length, elementNames = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- elementNames[_key3] = arguments[_key3];
- }
-
- elementNames.forEach(function (name) {
- if (!onsElements[name]) {
- util$1.throw('Ons' + name + ' is required but was not imported (Custom Elements)');
- }
- });
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Minimal animation library for managing css transition on mobile browsers.
- */
- var TIMEOUT_RATIO = 1.4;
-
- var util$4 = {};
-
- // capitalize string
- util$4.capitalize = function (str) {
- return str.charAt(0).toUpperCase() + str.slice(1);
- };
-
- /**
- * @param {Object} params
- * @param {String} params.property
- * @param {Float} params.duration
- * @param {String} params.timing
- */
- util$4.buildTransitionValue = function (params) {
- params.property = params.property || 'all';
- params.duration = params.duration || 0.4;
- params.timing = params.timing || 'linear';
-
- var props = params.property.split(/ +/);
-
- return props.map(function (prop) {
- return prop + ' ' + params.duration + 's ' + params.timing;
- }).join(', ');
- };
-
- /**
- * Add an event handler on "transitionend" event.
- */
- util$4.onceOnTransitionEnd = function (element, callback) {
- if (!element) {
- return function () {};
- }
-
- var fn = function fn(event) {
- if (element == event.target) {
- event.stopPropagation();
- removeListeners();
-
- callback();
- }
- };
-
- var removeListeners = function removeListeners() {
- util$4._transitionEndEvents.forEach(function (eventName) {
- element.removeEventListener(eventName, fn, false);
- });
- };
-
- util$4._transitionEndEvents.forEach(function (eventName) {
- element.addEventListener(eventName, fn, false);
- });
-
- return removeListeners;
- };
-
- util$4._transitionEndEvents = function () {
-
- if ('ontransitionend' in window) {
- return ['transitionend'];
- }
-
- if ('onwebkittransitionend' in window) {
- return ['webkitTransitionEnd'];
- }
-
- if (util$4.vendorPrefix === 'webkit' || util$4.vendorPrefix === 'o' || util$4.vendorPrefix === 'moz' || util$4.vendorPrefix === 'ms') {
- return [util$4.vendorPrefix + 'TransitionEnd', 'transitionend'];
- }
-
- return [];
- }();
-
- util$4._cssPropertyDict = function () {
- var styles = window.getComputedStyle(document.documentElement, '');
- var dict = {};
- var a = 'A'.charCodeAt(0);
- var z = 'z'.charCodeAt(0);
-
- var upper = function upper(s) {
- return s.substr(1).toUpperCase();
- };
-
- for (var i = 0; i < styles.length; i++) {
-
- var key = styles[i].replace(/^[-]+/, '').replace(/[-][a-z]/g, upper).replace(/^moz/, 'Moz');
-
- if (a <= key.charCodeAt(0) && z >= key.charCodeAt(0)) {
- if (key !== 'cssText' && key !== 'parentText') {
- dict[key] = true;
- }
- }
- }
-
- return dict;
- }();
-
- util$4.hasCssProperty = function (name) {
- return name in util$4._cssPropertyDict;
- };
-
- /**
- * Vendor prefix for css property.
- */
- util$4.vendorPrefix = function () {
- var styles = window.getComputedStyle(document.documentElement, ''),
- pre = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || styles.OLink === '' && ['', 'o'])[1];
- return pre;
- }();
-
- util$4.forceLayoutAtOnce = function (elements, callback) {
- this.batchImmediate(function () {
- elements.forEach(function (element) {
- // force layout
- element.offsetHeight;
- });
- callback();
- });
- };
-
- util$4.batchImmediate = function () {
- var callbacks = [];
-
- return function (callback) {
- if (callbacks.length === 0) {
- setImmediate(function () {
- var concreateCallbacks = callbacks.slice(0);
- callbacks = [];
- concreateCallbacks.forEach(function (callback) {
- callback();
- });
- });
- }
-
- callbacks.push(callback);
- };
- }();
-
- util$4.batchAnimationFrame = function () {
- var callbacks = [];
-
- var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
- setTimeout(callback, 1000 / 60);
- };
-
- return function (callback) {
- if (callbacks.length === 0) {
- raf(function () {
- var concreateCallbacks = callbacks.slice(0);
- callbacks = [];
- concreateCallbacks.forEach(function (callback) {
- callback();
- });
- });
- }
-
- callbacks.push(callback);
- };
- }();
-
- util$4.transitionPropertyName = function () {
- if (util$4.hasCssProperty('transitionDuration')) {
- return 'transition';
- }
-
- if (util$4.hasCssProperty(util$4.vendorPrefix + 'TransitionDuration')) {
- return util$4.vendorPrefix + 'Transition';
- }
-
- throw new Error('Invalid state');
- }();
-
- /**
- * @param {HTMLElement} element
- */
- var Animit = function Animit(element, defaults) {
- if (!(this instanceof Animit)) {
- return new Animit(element, defaults);
- }
-
- if (element instanceof HTMLElement) {
- this.elements = [element];
- } else if (Object.prototype.toString.call(element) === '[object Array]') {
- this.elements = element;
- } else {
- throw new Error('First argument must be an array or an instance of HTMLElement.');
- }
-
- this.defaults = defaults;
- this.transitionQueue = [];
- this.lastStyleAttributeDict = [];
- };
-
- Animit.prototype = {
-
- /**
- * @property {Array}
- */
- transitionQueue: undefined,
-
- /**
- * @property {Array}
- */
- elements: undefined,
-
- /**
- * @property {Object}
- */
- defaults: undefined,
-
- /**
- * Start animation sequence with passed animations.
- *
- * @param {Function} callback
- */
- play: function play(callback) {
- if (typeof callback === 'function') {
- this.transitionQueue.push(function (done) {
- callback();
- done();
- });
- }
-
- this.startAnimation();
-
- return this;
- },
-
- /**
- * Most of the animations follow this default process.
- *
- * @param {from} css or options object containing css
- * @param {to} css or options object containing css
- * @param {delay} delay to wait
- */
- default: function _default(from, to, delay) {
- function step(params, duration, timing) {
- if (params.duration !== undefined) {
- duration = params.duration;
- }
- if (params.timing !== undefined) {
- timing = params.timing;
- }
-
- return {
- css: params.css || params,
- duration: duration,
- timing: timing
- };
- }
-
- return this.saveStyle().queue(step(from, 0, this.defaults.timing)).wait(delay === undefined ? this.defaults.delay : delay).queue(step(to, this.defaults.duration, this.defaults.timing)).restoreStyle();
- },
-
- /**
- * Queue transition animations or other function.
- *
- * e.g. animit(elt).queue({color: 'red'})
- * e.g. animit(elt).queue({color: 'red'}, {duration: 0.4})
- * e.g. animit(elt).queue({css: {color: 'red'}, duration: 0.2})
- *
- * @param {Object|Animit.Transition|Function} transition
- * @param {Object} [options]
- */
- queue: function queue(transition, options) {
- var queue = this.transitionQueue;
-
- if (transition && options) {
- options.css = transition;
- transition = new Animit.Transition(options);
- }
-
- if (!(transition instanceof Function || transition instanceof Animit.Transition)) {
- if (transition.css) {
- transition = new Animit.Transition(transition);
- } else {
- transition = new Animit.Transition({
- css: transition
- });
- }
- }
-
- if (transition instanceof Function) {
- queue.push(transition);
- } else if (transition instanceof Animit.Transition) {
- queue.push(transition.build());
- } else {
- throw new Error('Invalid arguments');
- }
-
- return this;
- },
-
- /**
- * Queue transition animations.
- *
- * @param {Float} seconds
- */
- wait: function wait(seconds) {
- if (seconds > 0) {
- this.transitionQueue.push(function (done) {
- setTimeout(done, 1000 * seconds);
- });
- }
-
- return this;
- },
-
- saveStyle: function saveStyle() {
-
- this.transitionQueue.push(function (done) {
- this.elements.forEach(function (element, index) {
- var css = this.lastStyleAttributeDict[index] = {};
-
- for (var i = 0; i < element.style.length; i++) {
- css[element.style[i]] = element.style[element.style[i]];
- }
- }.bind(this));
- done();
- }.bind(this));
-
- return this;
- },
-
- /**
- * Restore element's style.
- *
- * @param {Object} [options]
- * @param {Float} [options.duration]
- * @param {String} [options.timing]
- * @param {String} [options.transition]
- */
- restoreStyle: function restoreStyle(options) {
- options = options || {};
- var self = this;
-
- if (options.transition && !options.duration) {
- throw new Error('"options.duration" is required when "options.transition" is enabled.');
- }
-
- var transitionName = util$4.transitionPropertyName;
-
- if (options.transition || options.duration && options.duration > 0) {
- var transitionValue = options.transition || 'all ' + options.duration + 's ' + (options.timing || 'linear');
-
- this.transitionQueue.push(function (done) {
- var elements = this.elements;
- var timeoutId;
-
- var clearTransition = function clearTransition() {
- elements.forEach(function (element) {
- element.style[transitionName] = '';
- });
- };
-
- // add "transitionend" event handler
- var removeListeners = util$4.onceOnTransitionEnd(elements[0], function () {
- clearTimeout(timeoutId);
- clearTransition();
- done();
- });
-
- // for fail safe.
- timeoutId = setTimeout(function () {
- removeListeners();
- clearTransition();
- done();
- }, options.duration * 1000 * TIMEOUT_RATIO);
-
- // transition and style settings
- elements.forEach(function (element, index) {
-
- var css = self.lastStyleAttributeDict[index];
-
- if (!css) {
- throw new Error('restoreStyle(): The style is not saved. Invoke saveStyle() before.');
- }
-
- self.lastStyleAttributeDict[index] = undefined;
-
- var name;
- for (var i = 0, len = element.style.length; i < len; i++) {
- name = element.style[i];
- if (css[name] === undefined) {
- css[name] = '';
- }
- }
-
- element.style[transitionName] = transitionValue;
-
- Object.keys(css).forEach(function (key) {
- if (key !== transitionName) {
- element.style[key] = css[key];
- }
- });
-
- element.style[transitionName] = transitionValue;
- });
- });
- } else {
- this.transitionQueue.push(function (done) {
- reset();
- done();
- });
- }
-
- return this;
-
- function reset() {
- // Clear transition animation settings.
- self.elements.forEach(function (element, index) {
- element.style[transitionName] = 'none';
-
- var css = self.lastStyleAttributeDict[index];
-
- if (!css) {
- throw new Error('restoreStyle(): The style is not saved. Invoke saveStyle() before.');
- }
-
- self.lastStyleAttributeDict[index] = undefined;
-
- for (var i = 0, name = ''; i < element.style.length; i++) {
- name = element.style[i];
- if (typeof css[element.style[i]] === 'undefined') {
- css[element.style[i]] = '';
- }
- }
-
- Object.keys(css).forEach(function (key) {
- element.style[key] = css[key];
- });
- });
- }
- },
-
- /**
- * Start animation sequence.
- */
- startAnimation: function startAnimation() {
- this._dequeueTransition();
-
- return this;
- },
-
- _dequeueTransition: function _dequeueTransition() {
- var transition = this.transitionQueue.shift();
- if (this._currentTransition) {
- throw new Error('Current transition exists.');
- }
- this._currentTransition = transition;
- var self = this;
- var called = false;
-
- var done = function done() {
- if (!called) {
- called = true;
- self._currentTransition = undefined;
- self._dequeueTransition();
- } else {
- throw new Error('Invalid state: This callback is called twice.');
- }
- };
-
- if (transition) {
- transition.call(this, done);
- }
- }
-
- };
-
- /**
- * @param {Animit} arguments
- */
- Animit.runAll = function () /* arguments... */{
- for (var i = 0; i < arguments.length; i++) {
- arguments[i].play();
- }
- };
-
- /**
- * @param {Object} options
- * @param {Float} [options.duration]
- * @param {String} [options.property]
- * @param {String} [options.timing]
- */
- Animit.Transition = function (options) {
- this.options = options || {};
- this.options.duration = this.options.duration || 0;
- this.options.timing = this.options.timing || 'linear';
- this.options.css = this.options.css || {};
- this.options.property = this.options.property || 'all';
- };
-
- Animit.Transition.prototype = {
-
- /**
- * @param {HTMLElement} element
- * @return {Function}
- */
- build: function build() {
-
- if (Object.keys(this.options.css).length === 0) {
- throw new Error('options.css is required.');
- }
-
- var css = createActualCssProps(this.options.css);
-
- if (this.options.duration > 0) {
- var transitionValue = util$4.buildTransitionValue(this.options);
- var self = this;
-
- return function (callback) {
- var elements = this.elements;
- var timeout = self.options.duration * 1000 * TIMEOUT_RATIO;
- var timeoutId;
-
- var removeListeners = util$4.onceOnTransitionEnd(elements[0], function () {
- clearTimeout(timeoutId);
- callback();
- });
-
- timeoutId = setTimeout(function () {
- removeListeners();
- callback();
- }, timeout);
-
- elements.forEach(function (element) {
- element.style[util$4.transitionPropertyName] = transitionValue;
-
- Object.keys(css).forEach(function (name) {
- element.style[name] = css[name];
- });
- });
- };
- }
-
- if (this.options.duration <= 0) {
- return function (callback) {
- var elements = this.elements;
-
- elements.forEach(function (element) {
- element.style[util$4.transitionPropertyName] = '';
-
- Object.keys(css).forEach(function (name) {
- element.style[name] = css[name];
- });
- });
-
- if (elements.length > 0) {
- util$4.forceLayoutAtOnce(elements, function () {
- util$4.batchAnimationFrame(callback);
- });
- } else {
- util$4.batchAnimationFrame(callback);
- }
- };
- }
-
- function createActualCssProps(css) {
- var result = {};
-
- Object.keys(css).forEach(function (name) {
- var value = css[name];
-
- if (util$4.hasCssProperty(name)) {
- result[name] = value;
- return;
- }
-
- var prefixed = util$4.vendorPrefix + util$4.capitalize(name);
- if (util$4.hasCssProperty(prefixed)) {
- result[prefixed] = value;
- } else {
- result[prefixed] = value;
- result[name] = value;
- }
- });
-
- return result;
- }
- }
- };
-
- /*
- * Gesture detector library that forked from github.com/EightMedia/hammer.js.
- */
-
- var Event$1;
- var Utils;
- var Detection;
- var PointerEvent;
-
- /**
- * @object ons.GestureDetector
- * @category gesture
- * @description
- * [en]Utility class for gesture detection.[/en]
- * [ja]ジェスチャを検知するためのユーティリティクラスです。[/ja]
- */
-
- /**
- * @method constructor
- * @signature constructor(element[, options])
- * @description
- * [en]Create a new GestureDetector instance.[/en]
- * [ja]GestureDetectorのインスタンスを生成します。[/ja]
- * @param {Element} element
- * [en]Name of the event.[/en]
- * [ja]ジェスチャを検知するDOM要素を指定します。[/ja]
- * @param {Object} [options]
- * [en]Options object.[/en]
- * [ja]オプションを指定します。[/ja]
- * @return {ons.GestureDetector.Instance}
- */
- var GestureDetector = function GestureDetector(element, options) {
- return new GestureDetector.Instance(element, options || {});
- };
-
- /**
- * default settings.
- * more settings are defined per gesture at `/gestures`. Each gesture can be disabled/enabled
- * by setting it's name (like `swipe`) to false.
- * You can set the defaults for all instances by changing this object before creating an instance.
- * @example
- * ````
- * GestureDetector.defaults.drag = false;
- * GestureDetector.defaults.behavior.touchAction = 'pan-y';
- * delete GestureDetector.defaults.behavior.userSelect;
- * ````
- * @property defaults
- * @type {Object}
- */
- GestureDetector.defaults = {
- behavior: {
- // userSelect: 'none', // Also disables selection in `input` children
- touchAction: 'pan-y',
- touchCallout: 'none',
- contentZooming: 'none',
- userDrag: 'none',
- tapHighlightColor: 'rgba(0,0,0,0)'
- }
- };
-
- /**
- * GestureDetector document where the base events are added at
- * @property DOCUMENT
- * @type {HTMLElement}
- * @default window.document
- */
- GestureDetector.DOCUMENT = document;
-
- /**
- * detect support for pointer events
- * @property HAS_POINTEREVENTS
- * @type {Boolean}
- */
- GestureDetector.HAS_POINTEREVENTS = navigator.pointerEnabled || navigator.msPointerEnabled;
-
- /**
- * detect support for touch events
- * @property HAS_TOUCHEVENTS
- * @type {Boolean}
- */
- GestureDetector.HAS_TOUCHEVENTS = 'ontouchstart' in window;
-
- /**
- * detect mobile browsers
- * @property IS_MOBILE
- * @type {Boolean}
- */
- GestureDetector.IS_MOBILE = /mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent);
-
- /**
- * detect if we want to support mouseevents at all
- * @property NO_MOUSEEVENTS
- * @type {Boolean}
- */
- GestureDetector.NO_MOUSEEVENTS = GestureDetector.HAS_TOUCHEVENTS && GestureDetector.IS_MOBILE || GestureDetector.HAS_POINTEREVENTS;
-
- /**
- * interval in which GestureDetector recalculates current velocity/direction/angle in ms
- * @property CALCULATE_INTERVAL
- * @type {Number}
- * @default 25
- */
- GestureDetector.CALCULATE_INTERVAL = 25;
-
- /**
- * eventtypes per touchevent (start, move, end) are filled by `Event.determineEventTypes` on `setup`
- * the object contains the DOM event names per type (`EVENT_START`, `EVENT_MOVE`, `EVENT_END`)
- * @property EVENT_TYPES
- * @private
- * @writeOnce
- * @type {Object}
- */
- var EVENT_TYPES = {};
-
- /**
- * direction strings, for safe comparisons
- * @property DIRECTION_DOWN|LEFT|UP|RIGHT
- * @final
- * @type {String}
- * @default 'down' 'left' 'up' 'right'
- */
- var DIRECTION_DOWN = GestureDetector.DIRECTION_DOWN = 'down';
- var DIRECTION_LEFT = GestureDetector.DIRECTION_LEFT = 'left';
- var DIRECTION_UP = GestureDetector.DIRECTION_UP = 'up';
- var DIRECTION_RIGHT = GestureDetector.DIRECTION_RIGHT = 'right';
-
- /**
- * pointertype strings, for safe comparisons
- * @property POINTER_MOUSE|TOUCH|PEN
- * @final
- * @type {String}
- * @default 'mouse' 'touch' 'pen'
- */
- var POINTER_MOUSE = GestureDetector.POINTER_MOUSE = 'mouse';
- var POINTER_TOUCH = GestureDetector.POINTER_TOUCH = 'touch';
- var POINTER_PEN = GestureDetector.POINTER_PEN = 'pen';
-
- /**
- * eventtypes
- * @property EVENT_START|MOVE|END|RELEASE|TOUCH
- * @final
- * @type {String}
- * @default 'start' 'change' 'move' 'end' 'release' 'touch'
- */
- var EVENT_START = GestureDetector.EVENT_START = 'start';
- var EVENT_MOVE = GestureDetector.EVENT_MOVE = 'move';
- var EVENT_END = GestureDetector.EVENT_END = 'end';
- var EVENT_RELEASE = GestureDetector.EVENT_RELEASE = 'release';
- var EVENT_TOUCH = GestureDetector.EVENT_TOUCH = 'touch';
-
- /**
- * if the window events are set...
- * @property READY
- * @writeOnce
- * @type {Boolean}
- * @default false
- */
- GestureDetector.READY = false;
-
- /**
- * plugins namespace
- * @property plugins
- * @type {Object}
- */
- GestureDetector.plugins = GestureDetector.plugins || {};
-
- /**
- * gestures namespace
- * see `/gestures` for the definitions
- * @property gestures
- * @type {Object}
- */
- GestureDetector.gestures = GestureDetector.gestures || {};
-
- /**
- * setup events to detect gestures on the document
- * this function is called when creating an new instance
- * @private
- */
- function setup(opts) {
- if (GestureDetector.READY) {
- return;
- }
-
- // find what eventtypes we add listeners to
- Event$1.determineEventTypes();
-
- // Register all gestures inside GestureDetector.gestures
- Utils.each(GestureDetector.gestures, function (gesture) {
- Detection.register(gesture);
- });
-
- // Add touch events on the document
- Event$1.onTouch(GestureDetector.DOCUMENT, EVENT_MOVE, Detection.detect, opts);
- Event$1.onTouch(GestureDetector.DOCUMENT, EVENT_END, Detection.detect, opts);
-
- // GestureDetector is ready...!
- GestureDetector.READY = true;
- }
-
- /**
- * @module GestureDetector
- *
- * @class Utils
- * @static
- */
- Utils = GestureDetector.utils = {
- /**
- * extend method, could also be used for cloning when `dest` is an empty object.
- * changes the dest object
- * @param {Object} dest
- * @param {Object} src
- * @param {Boolean} [merge=false] do a merge
- * @return {Object} dest
- */
- extend: function extend(dest, src, merge) {
- for (var key in src) {
- if (src.hasOwnProperty(key) && (dest[key] === undefined || !merge)) {
- dest[key] = src[key];
- }
- }
- return dest;
- },
-
- /**
- * simple addEventListener wrapper
- * @param {HTMLElement} element
- * @param {String} type
- * @param {Function} handler
- */
- on: function on(element, type, handler, opt) {
- util$1.addEventListener(element, type, handler, opt, true);
- },
-
- /**
- * simple removeEventListener wrapper
- * @param {HTMLElement} element
- * @param {String} type
- * @param {Function} handler
- */
- off: function off(element, type, handler, opt) {
- util$1.removeEventListener(element, type, handler, opt, true);
- },
-
- /**
- * forEach over arrays and objects
- * @param {Object|Array} obj
- * @param {Function} iterator
- * @param {any} iterator.item
- * @param {Number} iterator.index
- * @param {Object|Array} iterator.obj the source object
- * @param {Object} context value to use as `this` in the iterator
- */
- each: function each(obj, iterator, context) {
- var i, len;
-
- // native forEach on arrays
- if ('forEach' in obj) {
- obj.forEach(iterator, context);
- // arrays
- } else if (obj.length !== undefined) {
- for (i = 0, len = obj.length; i < len; i++) {
- if (iterator.call(context, obj[i], i, obj) === false) {
- return;
- }
- }
- // objects
- } else {
- for (i in obj) {
- if (obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj) === false) {
- return;
- }
- }
- }
- },
-
- /**
- * find if a string contains the string using indexOf
- * @param {String} src
- * @param {String} find
- * @return {Boolean} found
- */
- inStr: function inStr(src, find) {
- return src.indexOf(find) > -1;
- },
-
- /**
- * find if a array contains the object using indexOf or a simple polyfill
- * @param {String} src
- * @param {String} find
- * @return {Boolean|Number} false when not found, or the index
- */
- inArray: function inArray(src, find, deep) {
- if (deep) {
- for (var i = 0, len = src.length; i < len; i++) {
- // Array.findIndex
- if (Object.keys(find).every(function (key) {
- return src[i][key] === find[key];
- })) {
- return i;
- }
- }
- return -1;
- }
-
- if (src.indexOf) {
- return src.indexOf(find);
- } else {
- for (var i = 0, len = src.length; i < len; i++) {
- if (src[i] === find) {
- return i;
- }
- }
- return -1;
- }
- },
-
- /**
- * convert an array-like object (`arguments`, `touchlist`) to an array
- * @param {Object} obj
- * @return {Array}
- */
- toArray: function toArray(obj) {
- return Array.prototype.slice.call(obj, 0);
- },
-
- /**
- * find if a node is in the given parent
- * @param {HTMLElement} node
- * @param {HTMLElement} parent
- * @return {Boolean} found
- */
- hasParent: function hasParent(node, parent) {
- while (node) {
- if (node == parent) {
- return true;
- }
- node = node.parentNode;
- }
- return false;
- },
-
- /**
- * get the center of all the touches
- * @param {Array} touches
- * @return {Object} center contains `pageX`, `pageY`, `clientX` and `clientY` properties
- */
- getCenter: function getCenter(touches) {
- var pageX = [],
- pageY = [],
- clientX = [],
- clientY = [],
- min = Math.min,
- max = Math.max;
-
- // no need to loop when only one touch
- if (touches.length === 1) {
- return {
- pageX: touches[0].pageX,
- pageY: touches[0].pageY,
- clientX: touches[0].clientX,
- clientY: touches[0].clientY
- };
- }
-
- Utils.each(touches, function (touch) {
- pageX.push(touch.pageX);
- pageY.push(touch.pageY);
- clientX.push(touch.clientX);
- clientY.push(touch.clientY);
- });
-
- return {
- pageX: (min.apply(Math, pageX) + max.apply(Math, pageX)) / 2,
- pageY: (min.apply(Math, pageY) + max.apply(Math, pageY)) / 2,
- clientX: (min.apply(Math, clientX) + max.apply(Math, clientX)) / 2,
- clientY: (min.apply(Math, clientY) + max.apply(Math, clientY)) / 2
- };
- },
-
- /**
- * calculate the velocity between two points. unit is in px per ms.
- * @param {Number} deltaTime
- * @param {Number} deltaX
- * @param {Number} deltaY
- * @return {Object} velocity `x` and `y`
- */
- getVelocity: function getVelocity(deltaTime, deltaX, deltaY) {
- return {
- x: Math.abs(deltaX / deltaTime) || 0,
- y: Math.abs(deltaY / deltaTime) || 0
- };
- },
-
- /**
- * calculate the angle between two coordinates
- * @param {Touch} touch1
- * @param {Touch} touch2
- * @return {Number} angle
- */
- getAngle: function getAngle(touch1, touch2) {
- var x = touch2.clientX - touch1.clientX,
- y = touch2.clientY - touch1.clientY;
-
- return Math.atan2(y, x) * 180 / Math.PI;
- },
-
- /**
- * do a small comparison to get the direction between two touches.
- * @param {Touch} touch1
- * @param {Touch} touch2
- * @return {String} direction matches `DIRECTION_LEFT|RIGHT|UP|DOWN`
- */
- getDirection: function getDirection(touch1, touch2) {
- var x = Math.abs(touch1.clientX - touch2.clientX),
- y = Math.abs(touch1.clientY - touch2.clientY);
-
- if (x >= y) {
- return touch1.clientX - touch2.clientX > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
- }
- return touch1.clientY - touch2.clientY > 0 ? DIRECTION_UP : DIRECTION_DOWN;
- },
-
- /**
- * calculate the distance between two touches
- * @param {Touch}touch1
- * @param {Touch} touch2
- * @return {Number} distance
- */
- getDistance: function getDistance(touch1, touch2) {
- var x = touch2.clientX - touch1.clientX,
- y = touch2.clientY - touch1.clientY;
-
- return Math.sqrt(x * x + y * y);
- },
-
- /**
- * calculate the scale factor between two touchLists
- * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
- * @param {Array} start array of touches
- * @param {Array} end array of touches
- * @return {Number} scale
- */
- getScale: function getScale(start, end) {
- // need two fingers...
- if (start.length >= 2 && end.length >= 2) {
- return this.getDistance(end[0], end[1]) / this.getDistance(start[0], start[1]);
- }
- return 1;
- },
-
- /**
- * calculate the rotation degrees between two touchLists
- * @param {Array} start array of touches
- * @param {Array} end array of touches
- * @return {Number} rotation
- */
- getRotation: function getRotation(start, end) {
- // need two fingers
- if (start.length >= 2 && end.length >= 2) {
- return this.getAngle(end[1], end[0]) - this.getAngle(start[1], start[0]);
- }
- return 0;
- },
-
- /**
- * find out if the direction is vertical *
- * @param {String} direction matches `DIRECTION_UP|DOWN`
- * @return {Boolean} is_vertical
- */
- isVertical: function isVertical(direction) {
- return direction == DIRECTION_UP || direction == DIRECTION_DOWN;
- },
-
- /**
- * set css properties with their prefixes
- * @param {HTMLElement} element
- * @param {String} prop
- * @param {String} value
- * @param {Boolean} [toggle=true]
- * @return {Boolean}
- */
- setPrefixedCss: function setPrefixedCss(element, prop, value, toggle) {
- var prefixes = ['', 'Webkit', 'Moz', 'O', 'ms'];
- prop = Utils.toCamelCase(prop);
-
- for (var i = 0; i < prefixes.length; i++) {
- var p = prop;
- // prefixes
- if (prefixes[i]) {
- p = prefixes[i] + p.slice(0, 1).toUpperCase() + p.slice(1);
- }
-
- // test the style
- if (p in element.style) {
- element.style[p] = (toggle === null || toggle) && value || '';
- break;
- }
- }
- },
-
- /**
- * toggle browser default behavior by setting css properties.
- * `userSelect='none'` also sets `element.onselectstart` to false
- * `userDrag='none'` also sets `element.ondragstart` to false
- *
- * @param {HtmlElement} element
- * @param {Object} props
- * @param {Boolean} [toggle=true]
- */
- toggleBehavior: function toggleBehavior(element, props, toggle) {
- if (!props || !element || !element.style) {
- return;
- }
-
- // set the css properties
- Utils.each(props, function (value, prop) {
- Utils.setPrefixedCss(element, prop, value, toggle);
- });
-
- var falseFn = toggle && function () {
- return false;
- };
-
- // also the disable onselectstart
- if (props.userSelect == 'none') {
- element.onselectstart = falseFn;
- }
- // and disable ondragstart
- if (props.userDrag == 'none') {
- element.ondragstart = falseFn;
- }
- },
-
- /**
- * convert a string with underscores to camelCase
- * so prevent_default becomes preventDefault
- * @param {String} str
- * @return {String} camelCaseStr
- */
- toCamelCase: function toCamelCase(str) {
- return str.replace(/[_-]([a-z])/g, function (s) {
- return s[1].toUpperCase();
- });
- }
- };
-
- /**
- * @module GestureDetector
- */
- /**
- * @class Event
- * @static
- */
- Event$1 = GestureDetector.event = {
- /**
- * when touch events have been fired, this is true
- * this is used to stop mouse events
- * @property prevent_mouseevents
- * @private
- * @type {Boolean}
- */
- preventMouseEvents: false,
-
- /**
- * if EVENT_START has been fired
- * @property started
- * @private
- * @type {Boolean}
- */
- started: false,
-
- /**
- * when the mouse is hold down, this is true
- * @property should_detect
- * @private
- * @type {Boolean}
- */
- shouldDetect: false,
-
- /**
- * simple event binder with a hook and support for multiple types
- * @param {HTMLElement} element
- * @param {String} type
- * @param {Function} handler
- * @param {Object} [opt]
- * @param {Function} [hook]
- * @param {Object} hook.type
- */
- on: function on(element, type, handler, opt, hook) {
- var types = type.split(' ');
- Utils.each(types, function (type) {
- Utils.on(element, type, handler, opt);
- hook && hook(type);
- });
- },
-
- /**
- * simple event unbinder with a hook and support for multiple types
- * @param {HTMLElement} element
- * @param {String} type
- * @param {Function} handler
- * @param {Object} [opt]
- * @param {Function} [hook]
- * @param {Object} hook.type
- */
- off: function off(element, type, handler, opt, hook) {
- var types = type.split(' ');
- Utils.each(types, function (type) {
- Utils.off(element, type, handler, opt);
- hook && hook(type);
- });
- },
-
- /**
- * the core touch event handler.
- * this finds out if we should to detect gestures
- * @param {HTMLElement} element
- * @param {String} eventType matches `EVENT_START|MOVE|END`
- * @param {Function} handler
- * @return onTouchHandler {Function} the core event handler
- */
- onTouch: function onTouch(element, eventType, handler, opt) {
- var self = this;
-
- var onTouchHandler = function onTouchHandler(ev) {
- var srcType = ev.type.toLowerCase(),
- isPointer = GestureDetector.HAS_POINTEREVENTS,
- isMouse = Utils.inStr(srcType, 'mouse'),
- triggerType;
-
- // if we are in a mouseevent, but there has been a touchevent triggered in this session
- // we want to do nothing. simply break out of the event.
- if (isMouse && self.preventMouseEvents) {
- return;
-
- // mousebutton must be down
- } else if (isMouse && eventType == EVENT_START && ev.button === 0) {
- self.preventMouseEvents = false;
- self.shouldDetect = true;
- } else if (isPointer && eventType == EVENT_START) {
- self.shouldDetect = ev.buttons === 1 || PointerEvent.matchType(POINTER_TOUCH, ev);
- // just a valid start event, but no mouse
- } else if (!isMouse && eventType == EVENT_START) {
- self.preventMouseEvents = true;
- self.shouldDetect = true;
- }
-
- // update the pointer event before entering the detection
- if (isPointer && eventType != EVENT_END) {
- PointerEvent.updatePointer(eventType, ev);
- }
-
- // we are in a touch/down state, so allowed detection of gestures
- if (self.shouldDetect) {
- triggerType = self.doDetect.call(self, ev, eventType, element, handler);
- }
-
- // ...and we are done with the detection
- // so reset everything to start each detection totally fresh
- if (triggerType == EVENT_END) {
- self.preventMouseEvents = false;
- self.shouldDetect = false;
- PointerEvent.reset();
- // update the pointerevent object after the detection
- }
-
- if (isPointer && eventType == EVENT_END) {
- PointerEvent.updatePointer(eventType, ev);
- }
- };
-
- this.on(element, EVENT_TYPES[eventType], onTouchHandler, opt);
- return onTouchHandler;
- },
-
- /**
- * the core detection method
- * this finds out what GestureDetector-touch-events to trigger
- * @param {Object} ev
- * @param {String} eventType matches `EVENT_START|MOVE|END`
- * @param {HTMLElement} element
- * @param {Function} handler
- * @return {String} triggerType matches `EVENT_START|MOVE|END`
- */
- doDetect: function doDetect(ev, eventType, element, handler) {
- var touchList = this.getTouchList(ev, eventType);
- var touchListLength = touchList.length;
- var triggerType = eventType;
- var triggerChange = touchList.trigger; // used by fakeMultitouch plugin
- var changedLength = touchListLength;
-
- // at each touchstart-like event we want also want to trigger a TOUCH event...
- if (eventType == EVENT_START) {
- triggerChange = EVENT_TOUCH;
- // ...the same for a touchend-like event
- } else if (eventType == EVENT_END) {
- triggerChange = EVENT_RELEASE;
-
- // keep track of how many touches have been removed
- changedLength = touchList.length - (ev.changedTouches ? ev.changedTouches.length : 1);
- }
-
- // after there are still touches on the screen,
- // we just want to trigger a MOVE event. so change the START or END to a MOVE
- // but only after detection has been started, the first time we actually want a START
- if (changedLength > 0 && this.started) {
- triggerType = EVENT_MOVE;
- }
-
- // detection has been started, we keep track of this, see above
- this.started = true;
-
- // generate some event data, some basic information
- var evData = this.collectEventData(element, triggerType, touchList, ev);
-
- // trigger the triggerType event before the change (TOUCH, RELEASE) events
- // but the END event should be at last
- if (eventType != EVENT_END) {
- handler.call(Detection, evData);
- }
-
- // trigger a change (TOUCH, RELEASE) event, this means the length of the touches changed
- if (triggerChange) {
- evData.changedLength = changedLength;
- evData.eventType = triggerChange;
-
- handler.call(Detection, evData);
-
- evData.eventType = triggerType;
- delete evData.changedLength;
- }
-
- // trigger the END event
- if (triggerType == EVENT_END) {
- handler.call(Detection, evData);
-
- // ...and we are done with the detection
- // so reset everything to start each detection totally fresh
- this.started = false;
- }
-
- return triggerType;
- },
-
- /**
- * we have different events for each device/browser
- * determine what we need and set them in the EVENT_TYPES constant
- * the `onTouch` method is bind to these properties.
- * @return {Object} events
- */
- determineEventTypes: function determineEventTypes() {
- var types;
- if (GestureDetector.HAS_POINTEREVENTS) {
- if (window.PointerEvent) {
- types = ['pointerdown', 'pointermove', 'pointerup pointercancel lostpointercapture'];
- } else {
- types = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp MSPointerCancel MSLostPointerCapture'];
- }
- } else if (GestureDetector.NO_MOUSEEVENTS) {
- types = ['touchstart', 'touchmove', 'touchend touchcancel'];
- } else {
- types = ['touchstart mousedown', 'touchmove mousemove', 'touchend touchcancel mouseup'];
- }
-
- EVENT_TYPES[EVENT_START] = types[0];
- EVENT_TYPES[EVENT_MOVE] = types[1];
- EVENT_TYPES[EVENT_END] = types[2];
- return EVENT_TYPES;
- },
-
- /**
- * create touchList depending on the event
- * @param {Object} ev
- * @param {String} eventType
- * @return {Array} touches
- */
- getTouchList: function getTouchList(ev, eventType) {
- // get the fake pointerEvent touchlist
- if (GestureDetector.HAS_POINTEREVENTS) {
- return PointerEvent.getTouchList();
- }
-
- // get the touchlist
- if (ev.touches) {
- if (eventType == EVENT_MOVE) {
- return ev.touches;
- }
-
- var identifiers = [];
- var concat = [].concat(Utils.toArray(ev.touches), Utils.toArray(ev.changedTouches));
- var touchList = [];
-
- Utils.each(concat, function (touch) {
- if (Utils.inArray(identifiers, touch.identifier) === -1) {
- touchList.push(touch);
- }
- identifiers.push(touch.identifier);
- });
-
- return touchList;
- }
-
- // make fake touchList from mouse position
- ev.identifier = 1;
- return [ev];
- },
-
- /**
- * collect basic event data
- * @param {HTMLElement} element
- * @param {String} eventType matches `EVENT_START|MOVE|END`
- * @param {Array} touches
- * @param {Object} ev
- * @return {Object} ev
- */
- collectEventData: function collectEventData(element, eventType, touches, ev) {
- // find out pointerType
- var pointerType = POINTER_TOUCH;
- if (Utils.inStr(ev.type, 'mouse') || PointerEvent.matchType(POINTER_MOUSE, ev)) {
- pointerType = POINTER_MOUSE;
- } else if (PointerEvent.matchType(POINTER_PEN, ev)) {
- pointerType = POINTER_PEN;
- }
-
- return {
- center: Utils.getCenter(touches),
- timeStamp: Date.now(),
- target: ev.target,
- touches: touches,
- eventType: eventType,
- pointerType: pointerType,
- srcEvent: ev,
-
- /**
- * prevent the browser default actions
- * mostly used to disable scrolling of the browser
- */
- preventDefault: function preventDefault() {
- var srcEvent = this.srcEvent;
- srcEvent.preventManipulation && srcEvent.preventManipulation();
- srcEvent.preventDefault && srcEvent.preventDefault();
- },
-
- /**
- * stop bubbling the event up to its parents
- */
- stopPropagation: function stopPropagation() {
- this.srcEvent.stopPropagation();
- },
-
- /**
- * immediately stop gesture detection
- * might be useful after a swipe was detected
- * @return {*}
- */
- stopDetect: function stopDetect() {
- return Detection.stopDetect();
- }
- };
- }
- };
-
- /**
- * @module GestureDetector
- *
- * @class PointerEvent
- * @static
- */
- PointerEvent = GestureDetector.PointerEvent = {
- /**
- * holds all pointers, by `identifier`
- * @property pointers
- * @type {Object}
- */
- pointers: {},
-
- /**
- * get the pointers as an array
- * @return {Array} touchlist
- */
- getTouchList: function getTouchList() {
- var touchlist = [];
- // we can use forEach since pointerEvents only is in IE10
- Utils.each(this.pointers, function (pointer) {
- touchlist.push(pointer);
- });
- return touchlist;
- },
-
- /**
- * update the position of a pointer
- * @param {String} eventType matches `EVENT_START|MOVE|END`
- * @param {Object} pointerEvent
- */
- updatePointer: function updatePointer(eventType, pointerEvent) {
- if (eventType == EVENT_END || eventType != EVENT_END && pointerEvent.buttons !== 1) {
- delete this.pointers[pointerEvent.pointerId];
- } else {
- pointerEvent.identifier = pointerEvent.pointerId;
- this.pointers[pointerEvent.pointerId] = pointerEvent;
- }
- },
-
- /**
- * check if ev matches pointertype
- * @param {String} pointerType matches `POINTER_MOUSE|TOUCH|PEN`
- * @param {PointerEvent} ev
- */
- matchType: function matchType(pointerType, ev) {
- if (!ev.pointerType) {
- return false;
- }
-
- var pt = ev.pointerType,
- types = {};
-
- types[POINTER_MOUSE] = pt === (ev.MSPOINTER_TYPE_MOUSE || POINTER_MOUSE);
- types[POINTER_TOUCH] = pt === (ev.MSPOINTER_TYPE_TOUCH || POINTER_TOUCH);
- types[POINTER_PEN] = pt === (ev.MSPOINTER_TYPE_PEN || POINTER_PEN);
- return types[pointerType];
- },
-
- /**
- * reset the stored pointers
- */
- reset: function resetList() {
- this.pointers = {};
- }
- };
-
- /**
- * @module GestureDetector
- *
- * @class Detection
- * @static
- */
- Detection = GestureDetector.detection = {
- // contains all registered GestureDetector.gestures in the correct order
- gestures: [],
-
- // data of the current GestureDetector.gesture detection session
- current: null,
-
- // the previous GestureDetector.gesture session data
- // is a full clone of the previous gesture.current object
- previous: null,
-
- // when this becomes true, no gestures are fired
- stopped: false,
-
- /**
- * start GestureDetector.gesture detection
- * @param {GestureDetector.Instance} inst
- * @param {Object} eventData
- */
- startDetect: function startDetect(inst, eventData) {
- // already busy with a GestureDetector.gesture detection on an element
- if (this.current) {
- return;
- }
-
- this.stopped = false;
-
- // holds current session
- this.current = {
- inst: inst, // reference to GestureDetectorInstance we're working for
- startEvent: Utils.extend({}, eventData), // start eventData for distances, timing etc
- lastEvent: false, // last eventData
- lastCalcEvent: false, // last eventData for calculations.
- futureCalcEvent: false, // last eventData for calculations.
- lastCalcData: {}, // last lastCalcData
- name: '' // current gesture we're in/detected, can be 'tap', 'hold' etc
- };
-
- this.detect(eventData);
- },
-
- /**
- * GestureDetector.gesture detection
- * @param {Object} eventData
- * @return {any}
- */
- detect: function detect(eventData) {
- if (!this.current || this.stopped) {
- return;
- }
-
- // extend event data with calculations about scale, distance etc
- eventData = this.extendEventData(eventData);
-
- // GestureDetector instance and instance options
- var inst = this.current.inst,
- instOptions = inst.options;
-
- // call GestureDetector.gesture handlers
- Utils.each(this.gestures, function triggerGesture(gesture) {
- // only when the instance options have enabled this gesture
- if (!this.stopped && inst.enabled && instOptions[gesture.name]) {
- gesture.handler.call(gesture, eventData, inst);
- }
- }, this);
-
- // store as previous event event
- if (this.current) {
- this.current.lastEvent = eventData;
- }
-
- if (eventData.eventType == EVENT_END) {
- this.stopDetect();
- }
-
- return eventData; // eslint-disable-line consistent-return
- },
-
- /**
- * clear the GestureDetector.gesture vars
- * this is called on endDetect, but can also be used when a final GestureDetector.gesture has been detected
- * to stop other GestureDetector.gestures from being fired
- */
- stopDetect: function stopDetect() {
- // clone current data to the store as the previous gesture
- // used for the double tap gesture, since this is an other gesture detect session
- this.previous = Utils.extend({}, this.current);
-
- // reset the current
- this.current = null;
- this.stopped = true;
- },
-
- /**
- * calculate velocity, angle and direction
- * @param {Object} ev
- * @param {Object} center
- * @param {Number} deltaTime
- * @param {Number} deltaX
- * @param {Number} deltaY
- */
- getCalculatedData: function getCalculatedData(ev, center, deltaTime, deltaX, deltaY) {
- var cur = this.current,
- recalc = false,
- calcEv = cur.lastCalcEvent,
- calcData = cur.lastCalcData;
-
- if (calcEv && ev.timeStamp - calcEv.timeStamp > GestureDetector.CALCULATE_INTERVAL) {
- center = calcEv.center;
- deltaTime = ev.timeStamp - calcEv.timeStamp;
- deltaX = ev.center.clientX - calcEv.center.clientX;
- deltaY = ev.center.clientY - calcEv.center.clientY;
- recalc = true;
- }
-
- if (ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) {
- cur.futureCalcEvent = ev;
- }
-
- if (!cur.lastCalcEvent || recalc) {
- calcData.velocity = Utils.getVelocity(deltaTime, deltaX, deltaY);
- calcData.angle = Utils.getAngle(center, ev.center);
- calcData.direction = Utils.getDirection(center, ev.center);
-
- cur.lastCalcEvent = cur.futureCalcEvent || ev;
- cur.futureCalcEvent = ev;
- }
-
- ev.velocityX = calcData.velocity.x;
- ev.velocityY = calcData.velocity.y;
- ev.interimAngle = calcData.angle;
- ev.interimDirection = calcData.direction;
- },
-
- /**
- * extend eventData for GestureDetector.gestures
- * @param {Object} ev
- * @return {Object} ev
- */
- extendEventData: function extendEventData(ev) {
- var cur = this.current,
- startEv = cur.startEvent,
- lastEv = cur.lastEvent || startEv;
-
- // update the start touchlist to calculate the scale/rotation
- if (ev.eventType == EVENT_TOUCH || ev.eventType == EVENT_RELEASE) {
- startEv.touches = [];
- Utils.each(ev.touches, function (touch) {
- startEv.touches.push({
- clientX: touch.clientX,
- clientY: touch.clientY
- });
- });
- }
-
- var deltaTime = ev.timeStamp - startEv.timeStamp,
- deltaX = ev.center.clientX - startEv.center.clientX,
- deltaY = ev.center.clientY - startEv.center.clientY;
-
- this.getCalculatedData(ev, lastEv.center, deltaTime, deltaX, deltaY);
-
- Utils.extend(ev, {
- startEvent: startEv,
-
- deltaTime: deltaTime,
- deltaX: deltaX,
- deltaY: deltaY,
-
- distance: Utils.getDistance(startEv.center, ev.center),
- angle: Utils.getAngle(startEv.center, ev.center),
- direction: Utils.getDirection(startEv.center, ev.center),
- scale: Utils.getScale(startEv.touches, ev.touches),
- rotation: Utils.getRotation(startEv.touches, ev.touches)
- });
-
- return ev;
- },
-
- /**
- * register new gesture
- * @param {Object} gesture object, see `gestures/` for documentation
- * @return {Array} gestures
- */
- register: function register(gesture) {
- // add an enable gesture options if there is no given
- var options = gesture.defaults || {};
- if (options[gesture.name] === undefined) {
- options[gesture.name] = true;
- }
-
- // extend GestureDetector default options with the GestureDetector.gesture options
- Utils.extend(GestureDetector.defaults, options, true);
-
- // set its index
- gesture.index = gesture.index || 1000;
-
- // add GestureDetector.gesture to the list
- this.gestures.push(gesture);
-
- // sort the list by index
- this.gestures.sort(function (a, b) {
- if (a.index < b.index) {
- return -1;
- }
- if (a.index > b.index) {
- return 1;
- }
- return 0;
- });
-
- return this.gestures;
- }
- };
-
- /**
- * @module GestureDetector
- */
-
- /**
- * create new GestureDetector instance
- * all methods should return the instance itself, so it is chainable.
- *
- * @class Instance
- * @constructor
- * @param {HTMLElement} element
- * @param {Object} [options={}] options are merged with `GestureDetector.defaults`
- * @return {GestureDetector.Instance}
- */
- GestureDetector.Instance = function (element, options) {
- var self = this;
- var listenerOptions = options && options.passive ? { passive: true } : undefined;
-
- // setup GestureDetectorJS window events and register all gestures
- // this also sets up the default options
- setup(listenerOptions);
-
- /**
- * @property element
- * @type {HTMLElement}
- */
- this.element = element;
-
- /**
- * @property enabled
- * @type {Boolean}
- * @protected
- */
- this.enabled = true;
-
- /**
- * options, merged with the defaults
- * options with an _ are converted to camelCase
- * @property options
- * @type {Object}
- */
- Utils.each(options, function (value, name) {
- delete options[name];
- options[Utils.toCamelCase(name)] = value;
- });
-
- this.options = Utils.extend(Utils.extend({}, GestureDetector.defaults), options || {});
- this.options.listenerOptions = listenerOptions;
-
- // add some css to the element to prevent the browser from doing its native behavior
- if (this.options.behavior) {
- Utils.toggleBehavior(this.element, this.options.behavior, true);
- }
-
- /**
- * event start handler on the element to start the detection
- * @property eventStartHandler
- * @type {Object}
- */
- this.eventStartHandler = Event$1.onTouch(element, EVENT_START, function (ev) {
- if (self.enabled && ev.eventType == EVENT_START) {
- Detection.startDetect(self, ev);
- } else if (ev.eventType == EVENT_TOUCH) {
- Detection.detect(ev);
- }
- }, listenerOptions);
-
- /**
- * keep a list of user event handlers which needs to be removed when calling 'dispose'
- * @property eventHandlers
- * @type {Array}
- */
- this.eventHandlers = [];
- };
-
- GestureDetector.Instance.prototype = {
- /**
- * @method on
- * @signature on(gestures, handler)
- * @description
- * [en]Adds an event handler for a gesture. Available gestures are: drag, dragleft, dragright, dragup, dragdown, hold, release, swipe, swipeleft, swiperight, swipeup, swipedown, tap, doubletap, touch, transform, pinch, pinchin, pinchout and rotate. [/en]
- * [ja]ジェスチャに対するイベントハンドラを追加します。指定できるジェスチャ名は、drag dragleft dragright dragup dragdown hold release swipe swipeleft swiperight swipeup swipedown tap doubletap touch transform pinch pinchin pinchout rotate です。[/ja]
- * @param {String} gestures
- * [en]A space separated list of gestures.[/en]
- * [ja]検知するジェスチャ名を指定します。スペースで複数指定することができます。[/ja]
- * @param {Function} handler
- * [en]An event handling function.[/en]
- * [ja]イベントハンドラとなる関数オブジェクトを指定します。[/ja]
- */
- on: function onEvent(gestures, handler, opt) {
- var self = this;
-
- Event$1.on(self.element, gestures, handler, util$1.extend({}, self.options.listenerOptions, opt), function (type) {
- self.eventHandlers.push({ gesture: type, handler: handler });
- });
- return self;
- },
-
- /**
- * @method off
- * @signature off(gestures, handler)
- * @description
- * [en]Remove an event listener.[/en]
- * [ja]イベントリスナーを削除します。[/ja]
- * @param {String} gestures
- * [en]A space separated list of gestures.[/en]
- * [ja]ジェスチャ名を指定します。スペースで複数指定することができます。[/ja]
- * @param {Function} handler
- * [en]An event handling function.[/en]
- * [ja]イベントハンドラとなる関数オブジェクトを指定します。[/ja]
- */
- off: function offEvent(gestures, handler, opt) {
- var self = this;
-
- Event$1.off(self.element, gestures, handler, util$1.extend({}, self.options.listenerOptions, opt), function (type) {
- var index = Utils.inArray(self.eventHandlers, { gesture: type, handler: handler }, true);
- if (index >= 0) {
- self.eventHandlers.splice(index, 1);
- }
- });
- return self;
- },
-
- /**
- * trigger gesture event
- * @method trigger
- * @signature trigger(gesture, eventData)
- * @param {String} gesture
- * @param {Object} [eventData]
- */
- trigger: function triggerEvent(gesture, eventData) {
- // optional
- if (!eventData) {
- eventData = {};
- }
-
- // create DOM event
- var event = GestureDetector.DOCUMENT.createEvent('Event');
- event.initEvent(gesture, true, true);
- event.gesture = eventData;
-
- // trigger on the target if it is in the instance element,
- // this is for event delegation tricks
- var element = this.element;
- if (Utils.hasParent(eventData.target, element)) {
- element = eventData.target;
- }
-
- element.dispatchEvent(event);
- return this;
- },
-
- /**
- * @method enable
- * @signature enable(state)
- * @description
- * [en]Enable or disable gesture detection.[/en]
- * [ja]ジェスチャ検知を有効化/無効化します。[/ja]
- * @param {Boolean} state
- * [en]Specify if it should be enabled or not.[/en]
- * [ja]有効にするかどうかを指定します。[/ja]
- */
- enable: function enable(state) {
- this.enabled = state;
- return this;
- },
-
- /**
- * @method dispose
- * @signature dispose()
- * @description
- * [en]Remove and destroy all event handlers for this instance.[/en]
- * [ja]このインスタンスでのジェスチャの検知や、イベントハンドラを全て解除して廃棄します。[/ja]
- */
- dispose: function dispose() {
- var i, eh;
-
- // undo all changes made by stop_browser_behavior
- Utils.toggleBehavior(this.element, this.options.behavior, false);
-
- // unbind all custom event handlers
- for (i = -1; eh = this.eventHandlers[++i];) {
- // eslint-disable-line no-cond-assign
- Utils.off(this.element, eh.gesture, eh.handler);
- }
-
- this.eventHandlers = [];
-
- // unbind the start event listener
- Event$1.off(this.element, EVENT_TYPES[EVENT_START], this.eventStartHandler);
-
- return null;
- }
- };
-
- /**
- * @module gestures
- */
- /**
- * Move with x fingers (default 1) around on the page.
- * Preventing the default browser behavior is a good way to improve feel and working.
- * ````
- * GestureDetectortime.on("drag", function(ev) {
- * console.log(ev);
- * ev.gesture.preventDefault();
- * });
- * ````
- *
- * @class Drag
- * @static
- */
- /**
- * @event drag
- * @param {Object} ev
- */
- /**
- * @event dragstart
- * @param {Object} ev
- */
- /**
- * @event dragend
- * @param {Object} ev
- */
- /**
- * @event drapleft
- * @param {Object} ev
- */
- /**
- * @event dragright
- * @param {Object} ev
- */
- /**
- * @event dragup
- * @param {Object} ev
- */
- /**
- * @event dragdown
- * @param {Object} ev
- */
-
- /**
- * @param {String} name
- */
- (function (name) {
- var triggered = false;
-
- function dragGesture(ev, inst) {
- var cur = Detection.current;
-
- // max touches
- if (inst.options.dragMaxTouches > 0 && ev.touches.length > inst.options.dragMaxTouches) {
- return;
- }
-
- switch (ev.eventType) {
- case EVENT_START:
- triggered = false;
- break;
-
- case EVENT_MOVE:
- // when the distance we moved is too small we skip this gesture
- // or we can be already in dragging
- if (ev.distance < inst.options.dragMinDistance && cur.name != name) {
- return;
- }
-
- var startCenter = cur.startEvent.center;
-
- // we are dragging!
- if (cur.name != name) {
- cur.name = name;
- if (inst.options.dragDistanceCorrection && ev.distance > 0) {
- // When a drag is triggered, set the event center to dragMinDistance pixels from the original event center.
- // Without this correction, the dragged distance would jumpstart at dragMinDistance pixels instead of at 0.
- // It might be useful to save the original start point somewhere
- var factor = Math.abs(inst.options.dragMinDistance / ev.distance);
- startCenter.pageX += ev.deltaX * factor;
- startCenter.pageY += ev.deltaY * factor;
- startCenter.clientX += ev.deltaX * factor;
- startCenter.clientY += ev.deltaY * factor;
-
- // recalculate event data using new start point
- ev = Detection.extendEventData(ev);
- }
- }
-
- // lock drag to axis?
- if (cur.lastEvent.dragLockToAxis || inst.options.dragLockToAxis && inst.options.dragLockMinDistance <= ev.distance) {
- ev.dragLockToAxis = true;
- }
-
- // keep direction on the axis that the drag gesture started on
- var lastDirection = cur.lastEvent.direction;
- if (ev.dragLockToAxis && lastDirection !== ev.direction) {
- if (Utils.isVertical(lastDirection)) {
- ev.direction = ev.deltaY < 0 ? DIRECTION_UP : DIRECTION_DOWN;
- } else {
- ev.direction = ev.deltaX < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
- }
- }
-
- // first time, trigger dragstart event
- if (!triggered) {
- inst.trigger(name + 'start', ev);
- triggered = true;
- }
-
- // trigger events
- inst.trigger(name, ev);
- inst.trigger(name + ev.direction, ev);
-
- var isVertical = Utils.isVertical(ev.direction);
-
- // block the browser events
- if (inst.options.dragBlockVertical && isVertical || inst.options.dragBlockHorizontal && !isVertical) {
- ev.preventDefault();
- }
- break;
-
- case EVENT_RELEASE:
- if (triggered && ev.changedLength <= inst.options.dragMaxTouches) {
- inst.trigger(name + 'end', ev);
- triggered = false;
- }
- break;
-
- case EVENT_END:
- triggered = false;
- break;
- }
- }
-
- GestureDetector.gestures.Drag = {
- name: name,
- index: 50,
- handler: dragGesture,
- defaults: {
- /**
- * minimal movement that have to be made before the drag event gets triggered
- * @property dragMinDistance
- * @type {Number}
- * @default 10
- */
- dragMinDistance: 10,
-
- /**
- * Set dragDistanceCorrection to true to make the starting point of the drag
- * be calculated from where the drag was triggered, not from where the touch started.
- * Useful to avoid a jerk-starting drag, which can make fine-adjustments
- * through dragging difficult, and be visually unappealing.
- * @property dragDistanceCorrection
- * @type {Boolean}
- * @default true
- */
- dragDistanceCorrection: true,
-
- /**
- * set 0 for unlimited, but this can conflict with transform
- * @property dragMaxTouches
- * @type {Number}
- * @default 1
- */
- dragMaxTouches: 1,
-
- /**
- * prevent default browser behavior when dragging occurs
- * be careful with it, it makes the element a blocking element
- * when you are using the drag gesture, it is a good practice to set this true
- * @property dragBlockHorizontal
- * @type {Boolean}
- * @default false
- */
- dragBlockHorizontal: false,
-
- /**
- * same as `dragBlockHorizontal`, but for vertical movement
- * @property dragBlockVertical
- * @type {Boolean}
- * @default false
- */
- dragBlockVertical: false,
-
- /**
- * dragLockToAxis keeps the drag gesture on the axis that it started on,
- * It disallows vertical directions if the initial direction was horizontal, and vice versa.
- * @property dragLockToAxis
- * @type {Boolean}
- * @default false
- */
- dragLockToAxis: false,
-
- /**
- * drag lock only kicks in when distance > dragLockMinDistance
- * This way, locking occurs only when the distance has become large enough to reliably determine the direction
- * @property dragLockMinDistance
- * @type {Number}
- * @default 25
- */
- dragLockMinDistance: 25
- }
- };
- })('drag');
-
- /**
- * @module gestures
- */
- /**
- * trigger a simple gesture event, so you can do anything in your handler.
- * only usable if you know what your doing...
- *
- * @class Gesture
- * @static
- */
- /**
- * @event gesture
- * @param {Object} ev
- */
- GestureDetector.gestures.Gesture = {
- name: 'gesture',
- index: 1337,
- handler: function releaseGesture(ev, inst) {
- inst.trigger(this.name, ev);
- }
- };
-
- /**
- * @module gestures
- */
- /**
- * Touch stays at the same place for x time
- *
- * @class Hold
- * @static
- */
- /**
- * @event hold
- * @param {Object} ev
- */
-
- /**
- * @param {String} name
- */
- (function (name) {
- var timer;
-
- function holdGesture(ev, inst) {
- var options = inst.options,
- current = Detection.current;
-
- switch (ev.eventType) {
- case EVENT_START:
- clearTimeout(timer);
-
- // set the gesture so we can check in the timeout if it still is
- current.name = name;
-
- // set timer and if after the timeout it still is hold,
- // we trigger the hold event
- timer = setTimeout(function () {
- if (current && current.name == name) {
- inst.trigger(name, ev);
- }
- }, options.holdTimeout);
- break;
-
- case EVENT_MOVE:
- if (ev.distance > options.holdThreshold) {
- clearTimeout(timer);
- }
- break;
-
- case EVENT_RELEASE:
- clearTimeout(timer);
- break;
- }
- }
-
- GestureDetector.gestures.Hold = {
- name: name,
- index: 10,
- defaults: {
- /**
- * @property holdTimeout
- * @type {Number}
- * @default 500
- */
- holdTimeout: 500,
-
- /**
- * movement allowed while holding
- * @property holdThreshold
- * @type {Number}
- * @default 2
- */
- holdThreshold: 2
- },
- handler: holdGesture
- };
- })('hold');
-
- /**
- * @module gestures
- */
- /**
- * when a touch is being released from the page
- *
- * @class Release
- * @static
- */
- /**
- * @event release
- * @param {Object} ev
- */
- GestureDetector.gestures.Release = {
- name: 'release',
- index: Infinity,
- handler: function releaseGesture(ev, inst) {
- if (ev.eventType == EVENT_RELEASE) {
- inst.trigger(this.name, ev);
- }
- }
- };
-
- /**
- * @module gestures
- */
- /**
- * triggers swipe events when the end velocity is above the threshold
- * for best usage, set `preventDefault` (on the drag gesture) to `true`
- * ````
- * GestureDetectortime.on("dragleft swipeleft", function(ev) {
- * console.log(ev);
- * ev.gesture.preventDefault();
- * });
- * ````
- *
- * @class Swipe
- * @static
- */
- /**
- * @event swipe
- * @param {Object} ev
- */
- /**
- * @event swipeleft
- * @param {Object} ev
- */
- /**
- * @event swiperight
- * @param {Object} ev
- */
- /**
- * @event swipeup
- * @param {Object} ev
- */
- /**
- * @event swipedown
- * @param {Object} ev
- */
- GestureDetector.gestures.Swipe = {
- name: 'swipe',
- index: 40,
- defaults: {
- /**
- * @property swipeMinTouches
- * @type {Number}
- * @default 1
- */
- swipeMinTouches: 1,
-
- /**
- * @property swipeMaxTouches
- * @type {Number}
- * @default 1
- */
- swipeMaxTouches: 1,
-
- /**
- * horizontal swipe velocity
- * @property swipeVelocityX
- * @type {Number}
- * @default 0.6
- */
- swipeVelocityX: 0.6,
-
- /**
- * vertical swipe velocity
- * @property swipeVelocityY
- * @type {Number}
- * @default 0.6
- */
- swipeVelocityY: 0.6
- },
-
- handler: function swipeGesture(ev, inst) {
- if (ev.eventType == EVENT_RELEASE) {
- var touches = ev.touches.length,
- options = inst.options;
-
- // max touches
- if (touches < options.swipeMinTouches || touches > options.swipeMaxTouches) {
- return;
- }
-
- // when the distance we moved is too small we skip this gesture
- // or we can be already in dragging
- if (ev.velocityX > options.swipeVelocityX || ev.velocityY > options.swipeVelocityY) {
- // trigger swipe events
- inst.trigger(this.name, ev);
- inst.trigger(this.name + ev.direction, ev);
- }
- }
- }
- };
-
- /**
- * @module gestures
- */
- /**
- * Single tap and a double tap on a place
- *
- * @class Tap
- * @static
- */
- /**
- * @event tap
- * @param {Object} ev
- */
- /**
- * @event doubletap
- * @param {Object} ev
- */
-
- /**
- * @param {String} name
- */
- (function (name) {
- var hasMoved = false;
-
- function tapGesture(ev, inst) {
- var options = inst.options,
- current = Detection.current,
- prev = Detection.previous,
- sincePrev,
- didDoubleTap;
-
- switch (ev.eventType) {
- case EVENT_START:
- hasMoved = false;
- break;
-
- case EVENT_MOVE:
- hasMoved = hasMoved || ev.distance > options.tapMaxDistance;
- break;
-
- case EVENT_END:
- if (!Utils.inStr(ev.srcEvent.type, 'cancel') && ev.deltaTime < options.tapMaxTime && !hasMoved) {
- // previous gesture, for the double tap since these are two different gesture detections
- sincePrev = prev && prev.lastEvent && ev.timeStamp - prev.lastEvent.timeStamp;
- didDoubleTap = false;
-
- // check if double tap
- if (prev && prev.name == name && sincePrev && sincePrev < options.doubleTapInterval && ev.distance < options.doubleTapDistance) {
- inst.trigger('doubletap', ev);
- didDoubleTap = true;
- }
-
- // do a single tap
- if (!didDoubleTap || options.tapAlways) {
- current.name = name;
- inst.trigger(current.name, ev);
- }
- }
- break;
- }
- }
-
- GestureDetector.gestures.Tap = {
- name: name,
- index: 100,
- handler: tapGesture,
- defaults: {
- /**
- * max time of a tap, this is for the slow tappers
- * @property tapMaxTime
- * @type {Number}
- * @default 250
- */
- tapMaxTime: 250,
-
- /**
- * max distance of movement of a tap, this is for the slow tappers
- * @property tapMaxDistance
- * @type {Number}
- * @default 10
- */
- tapMaxDistance: 10,
-
- /**
- * always trigger the `tap` event, even while double-tapping
- * @property tapAlways
- * @type {Boolean}
- * @default true
- */
- tapAlways: true,
-
- /**
- * max distance between two taps
- * @property doubleTapDistance
- * @type {Number}
- * @default 20
- */
- doubleTapDistance: 20,
-
- /**
- * max time between two taps
- * @property doubleTapInterval
- * @type {Number}
- * @default 300
- */
- doubleTapInterval: 300
- }
- };
- })('tap');
-
- /**
- * @module gestures
- */
- /**
- * when a touch is being touched at the page
- *
- * @class Touch
- * @static
- */
- /**
- * @event touch
- * @param {Object} ev
- */
- GestureDetector.gestures.Touch = {
- name: 'touch',
- index: -Infinity,
- defaults: {
- /**
- * call preventDefault at touchstart, and makes the element blocking by disabling the scrolling of the page,
- * but it improves gestures like transforming and dragging.
- * be careful with using this, it can be very annoying for users to be stuck on the page
- * @property preventDefault
- * @type {Boolean}
- * @default false
- */
- preventDefault: false,
-
- /**
- * disable mouse events, so only touch (or pen!) input triggers events
- * @property preventMouse
- * @type {Boolean}
- * @default false
- */
- preventMouse: false
- },
- handler: function touchGesture(ev, inst) {
- if (inst.options.preventMouse && ev.pointerType == POINTER_MOUSE) {
- ev.stopDetect();
- return;
- }
-
- if (inst.options.preventDefault) {
- ev.preventDefault();
- }
-
- if (ev.eventType == EVENT_TOUCH) {
- inst.trigger('touch', ev);
- }
- }
- };
-
- /**
- * @module gestures
- */
- /**
- * User want to scale or rotate with 2 fingers
- * Preventing the default browser behavior is a good way to improve feel and working. This can be done with the
- * `preventDefault` option.
- *
- * @class Transform
- * @static
- */
- /**
- * @event transform
- * @param {Object} ev
- */
- /**
- * @event transformstart
- * @param {Object} ev
- */
- /**
- * @event transformend
- * @param {Object} ev
- */
- /**
- * @event pinchin
- * @param {Object} ev
- */
- /**
- * @event pinchout
- * @param {Object} ev
- */
- /**
- * @event rotate
- * @param {Object} ev
- */
-
- /**
- * @param {String} name
- */
- (function (name) {
- var triggered = false;
-
- function transformGesture(ev, inst) {
- switch (ev.eventType) {
- case EVENT_START:
- triggered = false;
- break;
-
- case EVENT_MOVE:
- // at least multitouch
- if (ev.touches.length < 2) {
- return;
- }
-
- var scaleThreshold = Math.abs(1 - ev.scale);
- var rotationThreshold = Math.abs(ev.rotation);
-
- // when the distance we moved is too small we skip this gesture
- // or we can be already in dragging
- if (scaleThreshold < inst.options.transformMinScale && rotationThreshold < inst.options.transformMinRotation) {
- return;
- }
-
- // we are transforming!
- Detection.current.name = name;
-
- // first time, trigger dragstart event
- if (!triggered) {
- inst.trigger(name + 'start', ev);
- triggered = true;
- }
-
- inst.trigger(name, ev); // basic transform event
-
- // trigger rotate event
- if (rotationThreshold > inst.options.transformMinRotation) {
- inst.trigger('rotate', ev);
- }
-
- // trigger pinch event
- if (scaleThreshold > inst.options.transformMinScale) {
- inst.trigger('pinch', ev);
- inst.trigger('pinch' + (ev.scale < 1 ? 'in' : 'out'), ev);
- }
- break;
-
- case EVENT_RELEASE:
- if (triggered && ev.changedLength < 2) {
- inst.trigger(name + 'end', ev);
- triggered = false;
- }
- break;
- }
- }
-
- GestureDetector.gestures.Transform = {
- name: name,
- index: 45,
- defaults: {
- /**
- * minimal scale factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1
- * @property transformMinScale
- * @type {Number}
- * @default 0.01
- */
- transformMinScale: 0.01,
-
- /**
- * rotation in degrees
- * @property transformMinRotation
- * @type {Number}
- * @default 1
- */
- transformMinRotation: 1
- },
-
- handler: transformGesture
- };
- })('transform');
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var readyMap = void 0;
- var queueMap = void 0;
-
- function isContentReady(element) {
- if (element.childNodes.length > 0) {
- setContentReady(element);
- }
- return readyMap.has(element);
- }
-
- function setContentReady(element) {
- readyMap.set(element, true);
- }
-
- function addCallback(element, fn) {
- if (!queueMap.has(element)) {
- queueMap.set(element, []);
- }
- queueMap.get(element).push(fn);
- }
-
- function consumeQueue(element) {
- var callbacks = queueMap.get(element, []) || [];
- queueMap.delete(element);
- callbacks.forEach(function (callback) {
- return callback();
- });
- }
-
- function contentReady(element) {
- var fn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
-
- if (readyMap === undefined) {
- readyMap = new WeakMap();
- queueMap = new WeakMap();
- }
-
- addCallback(element, fn);
-
- if (isContentReady(element)) {
- consumeQueue(element);
- return;
- }
-
- var observer = new MutationObserver(function (changes) {
- setContentReady(element);
- consumeQueue(element);
- });
- observer.observe(element, { childList: true, characterData: true });
-
- // failback for elements has empty content.
- setImmediate(function () {
- setContentReady(element);
- consumeQueue(element);
- });
- }
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var ToastQueue = function () {
- function ToastQueue() {
- classCallCheck(this, ToastQueue);
-
- this.queue = [];
- }
-
- createClass(ToastQueue, [{
- key: "add",
- value: function add(fn, promise) {
- var _this = this;
-
- this.queue.push(fn);
-
- if (this.queue.length === 1) {
- setImmediate(this.queue[0]);
- }
-
- promise.then(function () {
- _this.queue.shift();
-
- if (_this.queue.length > 0) {
- setTimeout(_this.queue[0], 1000 / 30); // Apply some visual delay
- }
- });
- }
- }]);
- return ToastQueue;
- }();
-
- var ToastQueue$1 = new ToastQueue();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var _setAttributes = function _setAttributes(element, options) {
- ['id', 'class', 'animation'].forEach(function (a) {
- return options.hasOwnProperty(a) && element.setAttribute(a, options[a]);
- });
-
- if (options.modifier) {
- util$1.addModifier(element, options.modifier);
- }
- };
-
- var _normalizeArguments = function _normalizeArguments(message) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var defaults$$1 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- options = _extends({}, options);
- typeof message === 'string' ? options.message = message : options = message;
- if (!options || !options.message && !options.messageHTML) {
- util$1.throw('Notifications must contain a message');
- }
-
- if (options.hasOwnProperty('buttonLabels') || options.hasOwnProperty('buttonLabel')) {
- options.buttonLabels = options.buttonLabels || options.buttonLabel;
- if (!Array.isArray(options.buttonLabels)) {
- options.buttonLabels = [options.buttonLabels || ''];
- }
- }
-
- return util$1.extend({
- compile: function compile(param) {
- return param;
- },
- callback: function callback(param) {
- return param;
- },
- animation: 'default',
- cancelable: false,
- primaryButtonIndex: (options.buttonLabels || defaults$$1.buttonLabels || []).length - 1
- }, defaults$$1, options);
- };
-
- /**
- * @object ons.notification
- * @category dialog
- * @tutorial vanilla/Reference/notification
- * @description
- * [en]
- * Utility methods to create different kinds of notifications. There are three methods available:
- *
- * * `ons.notification.alert()`
- * * `ons.notification.confirm()`
- * * `ons.notification.prompt()`
- * * `ons.notification.toast()`
- *
- * It will automatically display a Material Design dialog on Android devices.
- * [/en]
- * [ja]いくつかの種類のアラートダイアログを作成するためのユーティリティメソッドを収めたオブジェクトです。[/ja]
- * @example
- * ons.notification.alert('Hello, world!');
- *
- * ons.notification.confirm('Are you ready?')
- * .then(
- * function(answer) {
- * if (answer === 1) {
- * ons.notification.alert('Let\'s go!');
- * }
- * }
- * );
- *
- * ons.notification.prompt('How old are ?')
- * .then(
- * function(age) {
- * ons.notification.alert('You are ' + age + ' years old.');
- * }
- * );
- */
- var notification = {};
-
- notification._createAlertDialog = function () {
- for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) {
- params[_key] = arguments[_key];
- }
-
- return new Promise(function (resolve) {
- var options = _normalizeArguments.apply(undefined, params);
- util$1.checkMissingImport('AlertDialog', 'AlertDialogButton');
-
- // Prompt input string
- var inputString = '';
- if (options.isPrompt) {
- inputString = '\n <input\n class="text-input text-input--underbar"\n type="' + (options.inputType || 'text') + '"\n placeholder="' + (options.placeholder || '') + '"\n value="' + (options.defaultValue || '') + '"\n style="width: 100%; margin-top: 10px;"\n />\n ';
- }
-
- // Buttons string
- var buttons = '';
- options.buttonLabels.forEach(function (label, index) {
- buttons += '\n <ons-alert-dialog-button\n class="\n ' + (index === options.primaryButtonIndex ? ' alert-dialog-button--primal' : '') + '\n ' + (options.buttonLabels.length <= 2 ? ' alert-dialog-button--rowfooter' : '') + '\n "\n style="position: relative;">\n ' + label + '\n </ons-alert-dialog-button>\n ';
- });
-
- // Dialog Element
- var el = {};
- var _destroyDialog = function _destroyDialog() {
- if (el.dialog.onDialogCancel) {
- el.dialog.removeEventListener('dialog-cancel', el.dialog.onDialogCancel);
- }
-
- Object.keys(el).forEach(function (key) {
- return delete el[key];
- });
- el = null;
-
- if (options.destroy instanceof Function) {
- options.destroy();
- }
- };
-
- el.dialog = document.createElement('ons-alert-dialog');
- el.dialog.innerHTML = '\n <div class="alert-dialog-mask"\n style="\n ' + (options.maskColor ? 'background-color: ' + options.maskColor : '') + '\n "></div>\n <div class="alert-dialog">\n <div class="alert-dialog-container">\n <div class="alert-dialog-title">\n ' + (options.title || '') + '\n </div>\n <div class="alert-dialog-content">\n ' + (options.message || options.messageHTML) + '\n ' + inputString + '\n </div>\n <div class="\n alert-dialog-footer\n ' + (options.buttonLabels.length <= 2 ? ' alert-dialog-footer--rowfooter' : '') + '\n ">\n ' + buttons + '\n </div>\n </div>\n </div>\n ';
- contentReady(el.dialog);
-
- // Set attributes
- _setAttributes(el.dialog, options);
-
- // Prompt events
- if (options.isPrompt && options.submitOnEnter) {
- el.input = el.dialog.querySelector('.text-input');
- el.input.onkeypress = function (event) {
- if (event.keyCode === 13) {
- el.dialog.hide().then(function () {
- if (el) {
- var resolveValue = el.input.value;
- _destroyDialog();
- options.callback(resolveValue);
- resolve(resolveValue);
- }
- });
- }
- };
- }
-
- // Button events
- el.footer = el.dialog.querySelector('.alert-dialog-footer');
- util$1.arrayFrom(el.dialog.querySelectorAll('.alert-dialog-button')).forEach(function (buttonElement, index) {
- buttonElement.onclick = function () {
- el.dialog.hide().then(function () {
- if (el) {
- var resolveValue = index;
- if (options.isPrompt) {
- resolveValue = index === options.primaryButtonIndex ? el.input.value : null;
- }
- el.dialog.remove();
- _destroyDialog();
- options.callback(resolveValue);
- resolve(resolveValue);
- }
- });
- };
-
- el.footer.appendChild(buttonElement);
- });
-
- // Cancel events
- if (options.cancelable) {
- el.dialog.cancelable = true;
- el.dialog.onDialogCancel = function () {
- setImmediate(function () {
- el.dialog.remove();
- _destroyDialog();
- });
- var resolveValue = options.isPrompt ? null : -1;
- options.callback(resolveValue);
- resolve(resolveValue);
- };
- el.dialog.addEventListener('dialog-cancel', el.dialog.onDialogCancel, false);
- }
-
- // Show dialog
- document.body.appendChild(el.dialog);
- options.compile(el.dialog);
- setImmediate(function () {
- el.dialog.show().then(function () {
- if (el.input && options.isPrompt && options.autofocus) {
- var strLength = el.input.value.length;
- el.input.focus();
- el.input.setSelectionRange(strLength, strLength);
- }
- });
- });
- });
- };
-
- /**
- * @method alert
- * @signature alert(message [, options] | options)
- * @return {Promise}
- * [en]Will resolve to the index of the button that was pressed or `-1` when canceled.[/en]
- * [ja][/ja]
- * @param {String} message
- * [en]Notification message. This argument is optional but if it's not defined either `options.message` or `options.messageHTML` must be defined instead.[/en]
- * [ja][/ja]
- * @param {Object} options
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクトです。[/ja]
- * @param {String} [options.message]
- * [en]Notification message.[/en]
- * [ja]アラートダイアログに表示する文字列を指定します。[/ja]
- * @param {String} [options.messageHTML]
- * [en]Notification message in HTML.[/en]
- * [ja]アラートダイアログに表示するHTMLを指定します。[/ja]
- * @param {String | Array} [options.buttonLabels]
- * [en]Labels for the buttons. Default is `"OK"`.[/en]
- * [ja]確認ボタンのラベルを指定します。"OK"がデフォルトです。[/ja]
- * @param {Number} [options.primaryButtonIndex]
- * [en]Index of primary button. Default is the last one.[/en]
- * [ja]プライマリボタンのインデックスを指定します。デフォルトは 0 です。[/ja]
- * @param {Boolean} [options.cancelable]
- * [en]Whether the dialog is cancelable or not. Default is `false`. If the dialog is cancelable it can be closed by clicking the background or pressing the Android back button.[/en]
- * [ja]ダイアログがキャンセル可能かどうかを指定します。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `none` and `fade`. Default is `fade`.[/en]
- * [ja]アラートダイアログを表示する際のアニメーション名を指定します。"none", "fade"のいずれかを指定できます。[/ja]
- * @param {String} [options.id]
- * [en]The `<ons-alert-dialog>` element's ID.[/en]
- * [ja]ons-alert-dialog要素のID。[/ja]
- * @param {String} [options.class]
- * [en]The `<ons-alert-dialog>` element's class.[/en]
- * [ja]ons-alert-dialog要素のclass。[/ja]
- * @param {String} [options.title]
- * [en]Dialog title. Default is `"Alert"`.[/en]
- * [ja]アラートダイアログの上部に表示するタイトルを指定します。"Alert"がデフォルトです。[/ja]
- * @param {String} [options.modifier]
- * [en]Modifier for the dialog.[/en]
- * [ja]アラートダイアログのmodifier属性の値を指定します。[/ja]
- * @param {String} [options.maskColor]
- * [en]Color of the background mask. Default is "rgba(0, 0, 0, 0.2)" ("rgba(0, 0, 0, 0.3)" for Material).[/en]
- * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
- * @param {Function} [options.callback]
- * [en]Function that executes after dialog has been closed.[/en]
- * [ja]アラートダイアログが閉じられた時に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]
- * Display an alert dialog to show the user a message.
- *
- * The content of the message can be either simple text or HTML.
- *
- * It can be called in the following ways:
- *
- * ```
- * ons.notification.alert(message, options);
- * ons.notification.alert(options);
- * ```
- *
- * Must specify either `message` or `messageHTML`.
- * [/en]
- * [ja]
- * ユーザーへメッセージを見せるためのアラートダイアログを表示します。
- * 表示するメッセージは、テキストかもしくはHTMLを指定できます。
- * このメソッドの引数には、options.messageもしくはoptions.messageHTMLのどちらかを必ず指定する必要があります。
- * [/ja]
- */
- notification.alert = function (message, options) {
- return notification._createAlertDialog(message, options, {
- buttonLabels: ['OK'],
- title: 'Alert'
- });
- };
-
- /**
- * @method confirm
- * @signature confirm(message [, options] | options)
- * @return {Promise}
- * [en]Will resolve to the index of the button that was pressed or `-1` when canceled.[/en]
- * [ja][/ja]
- * @param {String} message
- * [en]Notification message. This argument is optional but if it's not defined either `options.message` or `options.messageHTML` must be defined instead.[/en]
- * [ja][/ja]
- * @param {Object} options
- * [en]Parameter object.[/en]
- * @param {Array} [options.buttonLabels]
- * [en]Labels for the buttons. Default is `["Cancel", "OK"]`.[/en]
- * [ja]ボタンのラベルの配列を指定します。["Cancel", "OK"]がデフォルトです。[/ja]
- * @param {Number} [options.primaryButtonIndex]
- * [en]Index of primary button. Default is the last one.[/en]
- * [ja]プライマリボタンのインデックスを指定します。デフォルトは 1 です。[/ja]
- * @description
- * [en]
- * Display a dialog to ask the user for confirmation. Extends `alert()` parameters.
- * The default button labels are `"Cancel"` and `"OK"` but they can be customized.
- *
- * It can be called in the following ways:
- *
- * ```
- * ons.notification.confirm(message, options);
- * ons.notification.confirm(options);
- * ```
- *
- * Must specify either `message` or `messageHTML`.
- * [/en]
- * [ja]
- * ユーザに確認を促すダイアログを表示します。
- * デオルとのボタンラベルは、"Cancel"と"OK"ですが、これはこのメソッドの引数でカスタマイズできます。
- * このメソッドの引数には、options.messageもしくはoptions.messageHTMLのどちらかを必ず指定する必要があります。
- * [/ja]
- */
- notification.confirm = function (message, options) {
- return notification._createAlertDialog(message, options, {
- buttonLabels: ['Cancel', 'OK'],
- title: 'Confirm'
- });
- };
-
- /**
- * @method prompt
- * @signature prompt(message [, options] | options)
- * @param {String} message
- * [en]Notification message. This argument is optional but if it's not defined either `options.message` or `options.messageHTML` must be defined instead.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Will resolve to the input value when the dialog is closed or `null` when canceled.[/en]
- * [ja][/ja]
- * @param {Object} options
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクトです。[/ja]
- * @param {String | Array} [options.buttonLabels]
- * [en]Labels for the buttons. Default is `"OK"`.[/en]
- * [ja]確認ボタンのラベルを指定します。"OK"がデフォルトです。[/ja]
- * @param {Number} [options.primaryButtonIndex]
- * [en]Index of primary button. Default is the last one.[/en]
- * [ja]プライマリボタンのインデックスを指定します。デフォルトは 0 です。[/ja]
- * @param {String} [options.placeholder]
- * [en]Placeholder for the text input.[/en]
- * [ja]テキスト欄のプレースホルダに表示するテキストを指定します。[/ja]
- * @param {String} [options.defaultValue]
- * [en]Default value for the text input.[/en]
- * [ja]テキスト欄のデフォルトの値を指定します。[/ja]
- * @param {String} [options.inputType]
- * [en]Type of the input element (`password`, `date`...). Default is `text`.[/en]
- * [ja][/ja]
- * @param {Boolean} [options.autofocus]
- * [en]Autofocus the input element. Default is `true`. In Cordova, `KeyboardDisplayRequiresUserAction` in `config.xml` must be `false` to activate this feature.[/en]
- * [ja]input要素に自動的にフォーカスするかどうかを指定します。デフォルトはtrueです。Cordova環境では、この機能を有効にするためには `config.xml` で `KeyboardDisplayRequiresUserAction` を `false` に設定する必要があります。[/ja]
- * @param {Boolean} [options.submitOnEnter]
- * [en]Submit automatically when enter is pressed. Default is `true`.[/en]
- * [ja]Enterが押された際にそのformをsubmitするかどうかを指定します。デフォルトはtrueです。[/ja]
- * @description
- * [en]
- * Display a dialog with a prompt to ask the user a question. Extends `alert()` parameters.
- *
- * It can be called in the following ways:
- *
- * ```
- * ons.notification.prompt(message, options);
- * ons.notification.prompt(options);
- * ```
- *
- * Must specify either `message` or `messageHTML`.
- * [/en]
- * [ja]
- * ユーザーに入力を促すダイアログを表示します。
- * このメソッドの引数には、options.messageもしくはoptions.messageHTMLのどちらかを必ず指定する必要があります。
- * [/ja]
- */
- notification.prompt = function (message, options) {
- return notification._createAlertDialog(message, options, {
- buttonLabels: ['OK'],
- title: 'Alert',
- isPrompt: true,
- autofocus: true,
- submitOnEnter: true
- });
- };
-
- /**
- * @method toast
- * @signature toast(message [, options] | options)
- * @return {Promise}
- * [en]Will resolve when the toast is hidden.[/en]
- * [ja][/ja]
- * @param {String} message
- * [en]Toast message. This argument is optional but if it's not defined then `options.message` must be defined instead.[/en]
- * [ja][/ja]
- * @param {Object} options
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクトです。[/ja]
- * @param {String} [options.message]
- * [en]Notification message.[/en]
- * [ja]トーストに表示する文字列を指定します。[/ja]
- * @param {String} [options.buttonLabel]
- * [en]Label for the button.[/en]
- * [ja]確認ボタンのラベルを指定します。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `none`, `fade`, `ascend`, `lift` and `fall`. Default is `ascend` for Android and `lift` for iOS.[/en]
- * [ja]トーストを表示する際のアニメーション名を指定します。"none", "fade", "ascend", "lift", "fall"のいずれかを指定できます。[/ja]
- * @param {Number} [options.timeout]
- * [en]Number of miliseconds where the toast is visible before hiding automatically.[/en]
- * [ja][/ja]
- * @param {Boolean} [options.force]
- * [en]If `true`, the toast skips the notification queue and is shown immediately. Defaults to `false`.[/en]
- * [ja][/ja]
- * @param {String} [options.id]
- * [en]The `<ons-toast>` element's ID.[/en]
- * [ja]ons-toast要素のID。[/ja]
- * @param {String} [options.class]
- * [en]The `<ons-toast>` element's class.[/en]
- * [ja]ons-toast要素のclass。[/ja]
- * @param {String} [options.modifier]
- * [en]Modifier for the element.[/en]
- * [ja]トーストのmodifier属性の値を指定します。[/ja]
- * @param {Function} [options.callback]
- * [en]Function that executes after toast has been hidden.[/en]
- * [ja]トーストが閉じられた時に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]
- * Display a simple notification toast with an optional button that can be used for simple actions.
- *
- * It can be called in the following ways:
- *
- * ```
- * ons.notification.toast(message, options);
- * ons.notification.toast(options);
- * ```
- * [/en]
- * [ja][/ja]
- */
- notification.toast = function (message, options) {
- var promise = new Promise(function (resolve) {
- util$1.checkMissingImport('Toast'); // Throws error, must be inside promise
-
- options = _normalizeArguments(message, options, {
- timeout: 0,
- force: false
- });
-
- var toast = util$1.createElement('\n <ons-toast>\n ' + options.message + '\n ' + (options.buttonLabels ? '<button>' + options.buttonLabels[0] + '</button>' : '') + '\n </ons-toast>\n ');
-
- _setAttributes(toast, options);
-
- var finish = function finish(value) {
- if (toast) {
- toast.hide().then(function () {
- if (toast) {
- toast.remove();
- toast = null;
- options.callback(value);
- resolve(value);
- }
- });
- }
- };
-
- if (options.buttonLabels) {
- util$1.findChild(toast._toast, 'button').onclick = function () {
- return finish(0);
- };
- }
-
- document.body.appendChild(toast);
- options.compile(toast);
-
- var show = function show() {
- toast.parentElement && toast.show(options).then(function () {
- if (options.timeout) {
- setTimeout(function () {
- return finish(-1);
- }, options.timeout);
- }
- });
- };
-
- setImmediate(function () {
- return options.force ? show() : ToastQueue$1.add(show, promise);
- });
- });
-
- return promise;
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- // Validate parameters
- var checkOptions = function checkOptions(options) {
- var err = function err(prop) {
- var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Function';
- return util$1.throw('"options.' + prop + '" must be an instance of ' + type);
- };
- var hasOwnProperty = function hasOwnProperty(prop) {
- return Object.hasOwnProperty.call(options, prop);
- };
- var instanceOf = function instanceOf(prop) {
- var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Function;
- return options[prop] instanceof type;
- };
-
- var b = 'buttons',
- cb = 'callback',
- c = 'compile',
- d = 'destroy';
- (!hasOwnProperty(b) || !instanceOf(b, Array)) && err(b, 'Array');
- hasOwnProperty(cb) && !instanceOf(cb) && err(cb);
- hasOwnProperty(c) && !instanceOf(c) && err(c);
- hasOwnProperty(d) && !instanceOf(d) && err(d);
- };
-
- // Action Sheet
- var actionSheet = (function () {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- return new Promise(function (resolve) {
- util$1.checkMissingImport('ActionSheet');
- checkOptions(options);
-
- // Main component
- var actionSheet = util$1.createElement('\n <ons-action-sheet\n ' + (options.title ? 'title="' + options.title + '"' : '') + '\n ' + (options.cancelable ? 'cancelable' : '') + '\n ' + (options.modifier ? 'modifier="' + options.modifier + '"' : '') + '\n ' + (options.maskColor ? 'mask-color="' + options.maskColor + '"' : '') + '\n ' + (options.id ? 'id="' + options.id + '"' : '') + '\n ' + (options.class ? 'class="' + options.class + '"' : '') + '\n >\n <div class="action-sheet"></div>\n </ons-action-sheet>\n ');
-
- // Resolve action and clean up
- var finish = function finish(event) {
- var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1;
-
- if (actionSheet) {
- options.destroy && options.destroy(actionSheet);
-
- actionSheet.removeEventListener('dialog-cancel', finish, false);
- actionSheet.remove();
- actionSheet = null;
-
- options.callback && options.callback(index);
- resolve(index);
- }
- };
-
- // Link cancel handler
- actionSheet.addEventListener('dialog-cancel', finish, false);
-
- // Create buttons and link action handler
- var buttons = document.createDocumentFragment();
- options.buttons.forEach(function (item, index) {
- var buttonOptions = typeof item === 'string' ? { label: item } : _extends({}, item);
- if (options.destructive === index) {
- buttonOptions.modifier = (buttonOptions.modifier || '') + ' destructive';
- }
-
- var button = util$1.createElement('\n <ons-action-sheet-button\n ' + (buttonOptions.icon ? 'icon="' + buttonOptions.icon + '"' : '') + '\n ' + (buttonOptions.modifier ? 'modifier="' + buttonOptions.modifier + '"' : '') + '\n >\n ' + buttonOptions.label + '\n </ons-action-sheet-button>\n ');
-
- button.onclick = function (event) {
- return actionSheet.hide().then(function () {
- return finish(event, index);
- });
- };
- buttons.appendChild(button);
- });
-
- // Finish component and attach
- util$1.findChild(actionSheet, '.action-sheet').appendChild(buttons);
- document.body.appendChild(actionSheet);
- options.compile && options.compile(el.dialog);
-
- // Show
- setImmediate(function () {
- return actionSheet.show({
- animation: options.animation,
- animationOptions: options.animationOptions
- });
- });
- });
- });
-
- /**
- * MicroEvent - to make any js object an event emitter (server or browser)
- *
- * - pure javascript - server compatible, browser compatible
- * - dont rely on the browser doms
- * - super simple - you get it immediately, no mystery, no magic involved
- *
- * - create a MicroEventDebug with goodies to debug
- * - make it safer to use
- */
-
- /** NOTE: This library is customized for Onsen UI. */
-
- var MicroEvent = function MicroEvent() {};
- MicroEvent.prototype = {
- on: function on(event, fct) {
- this._events = this._events || {};
- this._events[event] = this._events[event] || [];
- this._events[event].push(fct);
- },
- once: function once(event, fct) {
- var self = this;
- var wrapper = function wrapper() {
- self.off(event, wrapper);
- return fct.apply(null, arguments);
- };
- this.on(event, wrapper);
- },
- off: function off(event, fct) {
- this._events = this._events || {};
- if (event in this._events === false) {
- return;
- }
-
- this._events[event] = this._events[event].filter(function (_fct) {
- if (fct) {
- return fct !== _fct;
- } else {
- return false;
- }
- });
- },
- emit: function emit(event /* , args... */) {
- this._events = this._events || {};
- if (event in this._events === false) {
- return;
- }
- for (var i = 0; i < this._events[event].length; i++) {
- this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1));
- }
- }
- };
-
- /**
- * mixin will delegate all MicroEvent.js function in the destination object
- *
- * - require('MicroEvent').mixin(Foobar) will make Foobar able to use MicroEvent
- *
- * @param {Object} the object which will support MicroEvent
- */
- MicroEvent.mixin = function (destObject) {
- var props = ['on', 'once', 'off', 'emit'];
- for (var i = 0; i < props.length; i++) {
- if (typeof destObject === 'function') {
- destObject.prototype[props[i]] = MicroEvent.prototype[props[i]];
- } else {
- destObject[props[i]] = MicroEvent.prototype[props[i]];
- }
- }
- };
-
- window.MicroEvent = MicroEvent;
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var create = function create() {
-
- /**
- * @object ons.orientation
- * @category util
- * @description
- * [en]Utility methods for orientation detection.[/en]
- * [ja]画面のオリエンテーション検知のためのユーティリティメソッドを収めているオブジェクトです。[/ja]
- */
- var obj = {
- /**
- * @event change
- * @description
- * [en]Fired when the device orientation changes.[/en]
- * [ja]デバイスのオリエンテーションが変化した際に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Boolean} event.isPortrait
- * [en]Will be true if the current orientation is portrait mode.[/en]
- * [ja]現在のオリエンテーションがportraitの場合にtrueを返します。[/ja]
- */
-
- /**
- * @method on
- * @signature on(eventName, listener)
- * @description
- * [en]Add an event listener.[/en]
- * [ja]イベントリスナーを追加します。[/ja]
- * @param {String} eventName
- * [en]Name of the event.[/en]
- * [ja]イベント名を指定します。[/ja]
- * @param {Function} listener
- * [en]Function to execute when the event is triggered.[/en]
- * [ja]このイベントが発火された際に呼び出される関数オブジェクトを指定します。[/ja]
- */
-
- /**
- * @method once
- * @signature once(eventName, listener)
- * @description
- * [en]Add an event listener that's only triggered once.[/en]
- * [ja]一度だけ呼び出されるイベントリスナーを追加します。[/ja]
- * @param {String} eventName
- * [en]Name of the event.[/en]
- * [ja]イベント名を指定します。[/ja]
- * @param {Function} listener
- * [en]Function to execute when the event is triggered.[/en]
- * [ja]イベントが発火した際に呼び出される関数オブジェクトを指定します。[/ja]
- */
-
- /**
- * @method off
- * @signature off(eventName, [listener])
- * @description
- * [en]Remove an event listener. If the listener is not specified all listeners for the event type will be removed.[/en]
- * [ja]イベントリスナーを削除します。もしイベントリスナーを指定しなかった場合には、そのイベントに紐づく全てのイベントリスナーが削除されます。[/ja]
- * @param {String} eventName
- * [en]Name of the event.[/en]
- * [ja]イベント名を指定します。[/ja]
- * @param {Function} listener
- * [en]Function to execute when the event is triggered.[/en]
- * [ja]削除するイベントリスナーを指定します。[/ja]
- */
-
- // actual implementation to detect if whether current screen is portrait or not
- _isPortrait: false,
-
- /**
- * @method isPortrait
- * @signature isPortrait()
- * @return {Boolean}
- * [en]Will be true if the current orientation is portrait mode.[/en]
- * [ja]オリエンテーションがportraitモードの場合にtrueになります。[/ja]
- * @description
- * [en]Returns whether the current screen orientation is portrait or not.[/en]
- * [ja]オリエンテーションがportraitモードかどうかを返します。[/ja]
- */
- isPortrait: function isPortrait() {
- return this._isPortrait();
- },
-
- /**
- * @method isLandscape
- * @signature isLandscape()
- * @return {Boolean}
- * [en]Will be true if the current orientation is landscape mode.[/en]
- * [ja]オリエンテーションがlandscapeモードの場合にtrueになります。[/ja]
- * @description
- * [en]Returns whether the current screen orientation is landscape or not.[/en]
- * [ja]オリエンテーションがlandscapeモードかどうかを返します。[/ja]
- */
- isLandscape: function isLandscape() {
- return !this.isPortrait();
- },
-
- _init: function _init() {
- document.addEventListener('DOMContentLoaded', this._onDOMContentLoaded.bind(this), false);
-
- if ('orientation' in window) {
- window.addEventListener('orientationchange', this._onOrientationChange.bind(this), false);
- } else {
- window.addEventListener('resize', this._onResize.bind(this), false);
- }
-
- this._isPortrait = function () {
- return window.innerHeight > window.innerWidth;
- };
-
- return this;
- },
-
- _onDOMContentLoaded: function _onDOMContentLoaded() {
- this._installIsPortraitImplementation();
- this.emit('change', { isPortrait: this.isPortrait() });
- },
-
- _installIsPortraitImplementation: function _installIsPortraitImplementation() {
- var isPortrait = window.innerWidth < window.innerHeight;
-
- if (!('orientation' in window)) {
- this._isPortrait = function () {
- return window.innerHeight > window.innerWidth;
- };
- } else if (window.orientation % 180 === 0) {
- this._isPortrait = function () {
- return Math.abs(window.orientation % 180) === 0 ? isPortrait : !isPortrait;
- };
- } else {
- this._isPortrait = function () {
- return Math.abs(window.orientation % 180) === 90 ? isPortrait : !isPortrait;
- };
- }
- },
-
- _onOrientationChange: function _onOrientationChange() {
- var _this = this;
-
- var isPortrait = this._isPortrait();
-
- // Wait for the dimensions to change because
- // of Android inconsistency.
- var nIter = 0;
- var interval = setInterval(function () {
- nIter++;
-
- var w = window.innerWidth;
- var h = window.innerHeight;
-
- if (isPortrait && w <= h || !isPortrait && w >= h) {
- _this.emit('change', { isPortrait: isPortrait });
- clearInterval(interval);
- } else if (nIter === 50) {
- _this.emit('change', { isPortrait: isPortrait });
- clearInterval(interval);
- }
- }, 20);
- },
-
- // Run on not mobile browser.
- _onResize: function _onResize() {
- this.emit('change', { isPortrait: this.isPortrait() });
- }
- };
-
- MicroEvent.mixin(obj);
-
- return obj;
- };
-
- var orientation = create()._init();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @object ons.modifier
- * @category visual
- * @description
- * [en]
- * Utility methods to change modifier attributes of Onsen UI elements..
- * [/en]
- * [ja][/ja]
- * @example
- * ons.modifier.add(myOnsInputElement, 'underbar');
- * ons.modifier.toggle(myOnsToastElement, 'custom-modifier');
- *
- */
- var modifier = {
- /**
- * @method add
- * @signature add(element, modifier [, modifier])
- * @description
- * [en]Add the specified modifiers to the element if they are not already included.[/en]
- * [ja][/ja]
- * @param {HTMLElement} element
- * [en]Target element.[/en]
- * [ja][/ja]
- * @param {String} modifier
- * [en]Name of the modifier.[/en]
- * [ja][/ja]
- */
- add: function add(element) {
- for (var _len = arguments.length, modifiers = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- modifiers[_key - 1] = arguments[_key];
- }
-
- return modifiers.forEach(function (modifier) {
- return util$1.addModifier(element, modifier);
- });
- },
- /**
- * @method remove
- * @signature remove(element, modifier [, modifier])
- * @description
- * [en]Remove the specified modifiers from the element if they are included.[/en]
- * [ja][/ja]
- * @param {HTMLElement} element
- * [en]Target element.[/en]
- * [ja][/ja]
- * @param {String} modifier
- * [en]Name of the modifier.[/en]
- * [ja][/ja]
- */
- remove: function remove(element) {
- for (var _len2 = arguments.length, modifiers = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
- modifiers[_key2 - 1] = arguments[_key2];
- }
-
- return modifiers.forEach(function (modifier) {
- return util$1.removeModifier(element, modifier);
- });
- },
- /**
- * @method contains
- * @signature contains(element, modifier)
- * @description
- * [en]Check whether the specified modifier is included in the element.[/en]
- * [ja][/ja]
- * @param {HTMLElement} element
- * [en]Target element.[/en]
- * [ja][/ja]
- * @param {String} modifier
- * [en]Name of the modifier.[/en]
- * [ja][/ja]
- * @return {Boolean}
- * [en]`true` when the specified modifier is found in the element's `modifier` attribute. `false` otherwise.[/en]
- * [ja][/ja]
- */
- contains: util$1.hasModifier,
- /**
- * @method toggle
- * @signature toggle(element, modifier [, force])
- * @description
- * [en]Toggle the specified modifier.[/en]
- * [ja][/ja]
- * @param {HTMLElement} element
- * [en]Target element.[/en]
- * [ja][/ja]
- * @param {String} modifier
- * [en]Name of the modifier.[/en]
- * [ja][/ja]
- * @param {String} force
- * [en]If it evaluates to true, add specified modifier value, and if it evaluates to false, remove it.[/en]
- * [ja][/ja]
- */
- toggle: util$1.toggleModifier
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var softwareKeyboard = new MicroEvent();
- softwareKeyboard._visible = false;
-
- var onShow = function onShow() {
- softwareKeyboard._visible = true;
- softwareKeyboard.emit('show');
- };
-
- var onHide = function onHide() {
- softwareKeyboard._visible = false;
- softwareKeyboard.emit('hide');
- };
-
- var bindEvents = function bindEvents() {
- if (typeof Keyboard !== 'undefined') {
- // https://github.com/martinmose/cordova-keyboard/blob/95f3da3a38d8f8e1fa41fbf40145352c13535a00/README.md
- Keyboard.onshow = onShow;
- Keyboard.onhide = onHide;
- softwareKeyboard.emit('init', { visible: Keyboard.isVisible });
-
- return true;
- } else if (typeof cordova.plugins !== 'undefined' && typeof cordova.plugins.Keyboard !== 'undefined') {
- // https://github.com/driftyco/ionic-plugins-keyboard/blob/ca27ecf/README.md
- window.addEventListener('native.keyboardshow', onShow);
- window.addEventListener('native.keyboardhide', onHide);
- softwareKeyboard.emit('init', { visible: cordova.plugins.Keyboard.isVisible });
-
- return true;
- }
-
- return false;
- };
-
- var noPluginError = function noPluginError() {
- util$1.warn('ons-keyboard: Cordova Keyboard plugin is not present.');
- };
-
- document.addEventListener('deviceready', function () {
- if (!bindEvents()) {
- if (document.querySelector('[ons-keyboard-active]') || document.querySelector('[ons-keyboard-inactive]')) {
- noPluginError();
- }
-
- softwareKeyboard.on = noPluginError;
- }
- });
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var generateId = function () {
- var i = 0;
- return function () {
- return i++;
- };
- }();
-
- /**
- * Door locking system.
- *
- * @param {Object} [options]
- * @param {Function} [options.log]
- */
-
- var DoorLock = function () {
- function DoorLock() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, DoorLock);
-
- this._lockList = [];
- this._waitList = [];
- this._log = options.log || function () {};
- }
-
- /**
- * Register a lock.
- *
- * @return {Function} Callback for unlocking.
- */
-
-
- createClass(DoorLock, [{
- key: 'lock',
- value: function lock() {
- var _this = this;
-
- var unlock = function unlock() {
- _this._unlock(unlock);
- };
- unlock.id = generateId();
- this._lockList.push(unlock);
- this._log('lock: ' + unlock.id);
-
- return unlock;
- }
- }, {
- key: '_unlock',
- value: function _unlock(fn) {
- var index = this._lockList.indexOf(fn);
- if (index === -1) {
- throw new Error('This function is not registered in the lock list.');
- }
-
- this._lockList.splice(index, 1);
- this._log('unlock: ' + fn.id);
-
- this._tryToFreeWaitList();
- }
- }, {
- key: '_tryToFreeWaitList',
- value: function _tryToFreeWaitList() {
- while (!this.isLocked() && this._waitList.length > 0) {
- this._waitList.shift()();
- }
- }
-
- /**
- * Register a callback for waiting unlocked door.
- *
- * @params {Function} callback Callback on unlocking the door completely.
- */
-
- }, {
- key: 'waitUnlock',
- value: function waitUnlock(callback) {
- if (!(callback instanceof Function)) {
- throw new Error('The callback param must be a function.');
- }
-
- if (this.isLocked()) {
- this._waitList.push(callback);
- } else {
- callback();
- }
- }
-
- /**
- * @return {Boolean}
- */
-
- }, {
- key: 'isLocked',
- value: function isLocked() {
- return this._lockList.length > 0;
- }
- }]);
- return DoorLock;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
- // Default implementation for global PageLoader.
- function loadPage(_ref, done) {
- var page = _ref.page,
- parent = _ref.parent,
- _ref$params = _ref.params;
-
- internal$1.getPageHTMLAsync(page).then(function (html) {
- var pageElement = util$1.createElement(html);
- parent.appendChild(pageElement);
-
- done(pageElement);
- });
- }
-
- function unloadPage(element) {
- if (element._destroy instanceof Function) {
- element._destroy();
- } else {
- element.remove();
- }
- }
-
- var PageLoader = function () {
- /**
- * @param {Function} [fn] Returns an object that has "element" property and "unload" function.
- */
- function PageLoader(loader, unloader) {
- classCallCheck(this, PageLoader);
-
- this._loader = loader instanceof Function ? loader : loadPage;
- this._unloader = unloader instanceof Function ? unloader : unloadPage;
- }
-
- /**
- * Set internal loader implementation.
- */
-
-
- createClass(PageLoader, [{
- key: 'load',
-
-
- /**
- * @param {any} options.page
- * @param {Element} options.parent A location to load page.
- * @param {Object} [options.params] Extra parameters for ons-page.
- * @param {Function} done Take an object that has "element" property and "unload" function.
- */
- value: function load(_ref2, done) {
- var page = _ref2.page,
- parent = _ref2.parent,
- _ref2$params = _ref2.params,
- params = _ref2$params === undefined ? {} : _ref2$params;
-
- this._loader({ page: page, parent: parent, params: params }, function (pageElement) {
- if (!(pageElement instanceof Element)) {
- throw Error('pageElement must be an instance of Element.');
- }
-
- done(pageElement);
- });
- }
- }, {
- key: 'unload',
- value: function unload(pageElement) {
- if (!(pageElement instanceof Element)) {
- throw Error('pageElement must be an instance of Element.');
- }
-
- this._unloader(pageElement);
- }
- }, {
- key: 'internalLoader',
- set: function set$$1(fn) {
- if (!(fn instanceof Function)) {
- throw Error('First parameter must be an instance of Function');
- }
- this._loader = fn;
- },
- get: function get$$1() {
- return this._loader;
- }
- }]);
- return PageLoader;
- }();
-
- var defaultPageLoader = new PageLoader();
-
- var instantPageLoader = new PageLoader(function (_ref3, done) {
- var page = _ref3.page,
- parent = _ref3.parent,
- _ref3$params = _ref3.params;
-
- var element = util$1.createElement(page.trim());
- parent.appendChild(element);
-
- done(element);
- }, unloadPage);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @object ons
- * @category util
- * @description
- * [ja]Onsen UIで利用できるグローバルなオブジェクトです。[/ja]
- * [en]A global object that's used in Onsen UI. [/en]
- */
- var ons$1 = {
- animit: Animit,
- defaultPageLoader: defaultPageLoader,
- elements: onsElements,
- GestureDetector: GestureDetector,
- modifier: modifier,
- notification: notification,
- orientation: orientation,
- pageAttributeExpression: pageAttributeExpression,
- PageLoader: PageLoader,
- platform: platform,
- softwareKeyboard: softwareKeyboard,
- _autoStyle: autoStyle,
- _internal: internal$1,
- _readyLock: new DoorLock(),
- _util: util$1
- };
-
- ons$1.platform.select((window.location.search.match(/platform=([\w-]+)/) || [])[1]);
-
- waitDeviceReady();
-
- var readyError = function readyError(after) {
- return util$1.throw('This method must be called ' + (after ? 'after' : 'before') + ' ons.isReady() is true');
- };
-
- /**
- * @method isReady
- * @signature isReady()
- * @return {Boolean}
- * [en]Will be true if Onsen UI is initialized.[/en]
- * [ja]初期化されているかどうかを返します。[/ja]
- * @description
- * [en]Returns true if Onsen UI is initialized.[/en]
- * [ja]Onsen UIがすでに初期化されているかどうかを返すメソッドです。[/ja]
- */
- ons$1.isReady = function () {
- return !ons$1._readyLock.isLocked();
- };
-
- /**
- * @method isWebView
- * @signature isWebView()
- * @return {Boolean}
- * [en]Will be true if the app is running in Cordova.[/en]
- * [ja]Cordovaで実行されている場合にtrueになります。[/ja]
- * @description
- * [en]Returns true if running inside Cordova.[/en]
- * [ja]Cordovaで実行されているかどうかを返すメソッドです。[/ja]
- */
- ons$1.isWebView = ons$1.platform.isWebView;
-
- /**
- * @method ready
- * @signature ready(callback)
- * @description
- * [ja]アプリの初期化に利用するメソッドです。渡された関数は、Onsen UIの初期化が終了している時点で必ず呼ばれます。[/ja]
- * [en]Method used to wait for app initialization. Waits for `DOMContentLoaded` and `deviceready`, when necessary, before executing the callback.[/en]
- * @param {Function} callback
- * [en]Function that executes after Onsen UI has been initialized.[/en]
- * [ja]Onsen UIが初期化が完了した後に呼び出される関数オブジェクトを指定します。[/ja]
- */
- ons$1.ready = function (callback) {
- if (ons$1.isReady()) {
- callback();
- } else {
- ons$1._readyLock.waitUnlock(callback);
- }
- };
-
- /**
- * @method setDefaultDeviceBackButtonListener
- * @signature setDefaultDeviceBackButtonListener(listener)
- * @param {Function} listener
- * [en]Function that executes when device back button is pressed. Must be called on `ons.ready`.[/en]
- * [ja]デバイスのバックボタンが押された時に実行される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Set default handler for device back button.[/en]
- * [ja]デバイスのバックボタンのためのデフォルトのハンドラを設定します。[/ja]
- */
- ons$1.setDefaultDeviceBackButtonListener = function (listener) {
- if (!ons$1.isReady()) {
- readyError(true);
- }
- ons$1._defaultDeviceBackButtonHandler.setListener(listener);
- };
-
- /**
- * @method disableDeviceBackButtonHandler
- * @signature disableDeviceBackButtonHandler()
- * @description
- * [en]Disable device back button event handler. Must be called on `ons.ready`.[/en]
- * [ja]デバイスのバックボタンのイベントを受け付けないようにします。[/ja]
- */
- ons$1.disableDeviceBackButtonHandler = function () {
- if (!ons$1.isReady()) {
- readyError(true);
- }
- internal$1.dbbDispatcher.disable();
- };
-
- /**
- * @method enableDeviceBackButtonHandler
- * @signature enableDeviceBackButtonHandler()
- * @description
- * [en]Enable device back button event handler. Must be called on `ons.ready`.[/en]
- * [ja]デバイスのバックボタンのイベントを受け付けるようにします。[/ja]
- */
- ons$1.enableDeviceBackButtonHandler = function () {
- if (!ons$1.isReady()) {
- readyError(true);
- }
- internal$1.dbbDispatcher.enable();
- };
-
- ons$1.fireDeviceBackButtonEvent = function () {
- internal$1.dbbDispatcher.fireDeviceBackButtonEvent();
- };
-
- /**
- * @method enableAutoStatusBarFill
- * @signature enableAutoStatusBarFill()
- * @description
- * [en]Enable status bar fill feature on iOS7 and above (except for iPhone X). Must be called before `ons.ready`.[/en]
- * [ja]iOS7以上(iPhone Xは除く)で、ステータスバー部分の高さを自動的に埋める処理を有効にします。[/ja]
- */
- ons$1.enableAutoStatusBarFill = function () {
- if (ons$1.isReady()) {
- readyError(false);
- }
- internal$1.config.autoStatusBarFill = true;
- };
-
- /**
- * @method disableAutoStatusBarFill
- * @signature disableAutoStatusBarFill()
- * @description
- * [en]Disable status bar fill feature on iOS7 and above (except for iPhone X). Must be called before `ons.ready`.[/en]
- * [ja]iOS7以上(iPhone Xは除く)で、ステータスバー部分の高さを自動的に埋める処理を無効にします。[/ja]
- */
- ons$1.disableAutoStatusBarFill = function () {
- if (ons$1.isReady()) {
- readyError(false);
- }
- internal$1.config.autoStatusBarFill = false;
- };
-
- /**
- * @method mockStatusBar
- * @signature mockStatusBar()
- * @description
- * [en]Creates a static element similar to iOS status bar. Only useful for browser testing. Must be called before `ons.ready`.[/en]
- * [ja][/ja]
- */
- ons$1.mockStatusBar = function () {
- if (ons$1.isReady()) {
- readyError(false);
- }
-
- var mock = function mock() {
- if (!document.body.children[0] || !document.body.children[0].classList.contains('ons-status-bar-mock')) {
- var android = platform.isAndroid(),
- i = function i(_i) {
- return '<i class="' + _i.split('-')[0] + ' ' + _i + '"></i>';
- };
- var left = android ? i('zmdi-twitter') + ' ' + i('zmdi-google-play') : 'No SIM ' + i('fa-wifi'),
- center = android ? '' : '12:28 PM',
- right = android ? i('zmdi-network') + ' ' + i('zmdi-wifi') + ' ' + i('zmdi-battery') + ' 12:28 PM' : '80% ' + i('fa-battery-three-quarters');
-
- document.body.insertBefore(util$1.createElement('<div class="ons-status-bar-mock ' + (android ? 'android' : 'ios') + '">' + ('<div>' + left + '</div><div>' + center + '</div><div>' + right + '</div>') + '</div>'), document.body.firstChild);
- }
- };
-
- document.body ? mock() : internal$1.waitDOMContentLoaded(mock);
- };
-
- /**
- * @method disableAnimations
- * @signature disableAnimations()
- * @description
- * [en]Disable all animations. Could be handy for testing and older devices.[/en]
- * [ja]アニメーションを全て無効にします。テストの際に便利です。[/ja]
- */
- ons$1.disableAnimations = function () {
- internal$1.config.animationsDisabled = true;
- };
-
- /**
- * @method enableAnimations
- * @signature enableAnimations()
- * @description
- * [en]Enable animations (default).[/en]
- * [ja]アニメーションを有効にします。[/ja]
- */
- ons$1.enableAnimations = function () {
- internal$1.config.animationsDisabled = false;
- };
-
- ons$1._disableWarnings = function () {
- internal$1.config.warningsDisabled = true;
- };
-
- ons$1._enableWarnings = function () {
- internal$1.config.warningsDisabled = false;
- };
-
- /**
- * @method disableAutoStyling
- * @signature disableAutoStyling()
- * @description
- * [en]Disable automatic styling.[/en]
- * [ja][/ja]
- */
- ons$1.disableAutoStyling = autoStyle.disable;
-
- /**
- * @method enableAutoStyling
- * @signature enableAutoStyling()
- * @description
- * [en]Enable automatic styling based on OS (default).[/en]
- * [ja][/ja]
- */
- ons$1.enableAutoStyling = autoStyle.enable;
-
- /**
- * @method disableIconAutoPrefix
- * @signature disableIconAutoPrefix()
- * @description
- * [en]Disable adding `fa-` prefix automatically to `ons-icon` classes. Useful when including custom icon packs.[/en]
- * [ja][/ja]
- */
- ons$1.disableIconAutoPrefix = function () {
- util$1.checkMissingImport('Icon');
- onsElements.Icon.setAutoPrefix(false);
- };
-
- /**
- * @method forceUIWebViewScrollFix
- * @signature forceUIWebViewScrollFix()
- * @param {Boolean} force Enable or disable the fix.
- * @description
- * [en]Applies a fix for iOS UIWebView which prevents scroll events jumping to pages under the top layer. This may visually affect normal scrolling of UIWebView if you open a dialog/menu before the scroll momentum finished. Disabled by default.[/en]
- * [ja][/ja]
- */
- ons$1.forceUIWebViewScrollFix = function () {
- var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
-
- internal$1.config.forceUIWebViewScrollFix = force;
- };
-
- /**
- * @method forcePlatformStyling
- * @signature forcePlatformStyling(platform)
- * @description
- * [en]Refresh styling for the given platform. Only useful for demos. Use `ons.platform.select(...)` instead for development and production.[/en]
- * [ja][/ja]
- * @param {string} platform New platform to style the elements.
- */
- ons$1.forcePlatformStyling = function (newPlatform) {
- ons$1.enableAutoStyling();
- ons$1.platform.select(newPlatform || 'ios');
-
- ons$1._util.arrayFrom(document.querySelectorAll('*')).forEach(function (element) {
- if (element.tagName.toLowerCase() === 'ons-if') {
- element._platformUpdate();
- } else if (element.tagName.match(/^ons-/i)) {
- autoStyle.prepare(element, true);
- if (element.tagName.toLowerCase() === 'ons-tabbar') {
- element._updatePosition();
- }
- }
- });
- };
-
- /**
- * @method preload
- * @signature preload(templatePaths)
- * @param {String|Array} templatePaths
- * [en]Set of HTML file paths containing 'ons-page' elements.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Promise that resolves when all the templates are cached.[/en]
- * [ja][/ja]
- * @description
- * [en]Separated files need to be requested on demand and this can slightly delay pushing new pages. This method requests and caches templates for later use.[/en]
- * [ja][/ja]
- */
- ons$1.preload = function () {
- var templates = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
-
- return Promise.all((templates instanceof Array ? templates : [templates]).map(function (template) {
- if (typeof template !== 'string') {
- util$1.throw('Expected string arguments but got ' + (typeof template === 'undefined' ? 'undefined' : _typeof(template)));
- }
- return internal$1.getTemplateHTMLAsync(template);
- }));
- };
-
- /**
- * @method createElement
- * @signature createElement(template, options)
- * @param {String} template
- * [en]Either an HTML file path, a `<template>` id or an HTML string such as `'<div id="foo">hoge</div>'`.[/en]
- * [ja][/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {Boolean|HTMLElement} [options.append]
- * [en]Whether or not the element should be automatically appended to the DOM. Defaults to `false`. If `true` value is given, `document.body` will be used as the target.[/en]
- * [ja][/ja]
- * @param {HTMLElement} [options.insertBefore]
- * [en]Reference node that becomes the next sibling of the new node (`options.append` element).[/en]
- * [ja][/ja]
- * @return {HTMLElement|Promise}
- * [en]If the provided template was an inline HTML string, it returns the new element. Otherwise, it returns a promise that resolves to the new element.[/en]
- * [ja][/ja]
- * @description
- * [en]Create a new element from a template. Both inline HTML and external files are supported although the return value differs.[/en]
- * [ja][/ja]
- */
- ons$1.createElement = function (template) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- template = template.trim();
-
- var create = function create(html) {
- var element = ons$1._util.createElement(html);
- element.remove();
-
- if (options.append) {
- var target = options.append instanceof HTMLElement ? options.append : document.body;
- target.insertBefore(element, options.insertBefore || null);
- options.link instanceof Function && options.link(element);
- }
-
- return element;
- };
-
- return template.charAt(0) === '<' ? create(template) : internal$1.getPageHTMLAsync(template).then(create);
- };
-
- /**
- * @method createPopover
- * @signature createPopover(page, [options])
- * @param {String} page
- * [en]Page name. Can be either an HTML file or a <template> containing a <ons-dialog> component.[/en]
- * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {Object} [options.parentScope]
- * [en]Parent scope of the dialog. Used to bind models and access scope methods from the dialog.[/en]
- * [ja]ダイアログ内で利用する親スコープを指定します。ダイアログからモデルやスコープのメソッドにアクセスするのに使います。このパラメータはAngularJSバインディングでのみ利用できます。[/ja]
- * @return {Promise}
- * [en]Promise object that resolves to the popover component object.[/en]
- * [ja]ポップオーバーのコンポーネントオブジェクトを解決するPromiseオブジェクトを返します。[/ja]
- * @description
- * [en]Create a popover instance from a template.[/en]
- * [ja]テンプレートからポップオーバーのインスタンスを生成します。[/ja]
- */
- /**
- * @method createDialog
- * @signature createDialog(page, [options])
- * @param {String} page
- * [en]Page name. Can be either an HTML file or an `<template>` containing a <ons-dialog> component.[/en]
- * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @return {Promise}
- * [en]Promise object that resolves to the dialog component object.[/en]
- * [ja]ダイアログのコンポーネントオブジェクトを解決するPromiseオブジェクトを返します。[/ja]
- * @description
- * [en]Create a dialog instance from a template.[/en]
- * [ja]テンプレートからダイアログのインスタンスを生成します。[/ja]
- */
- /**
- * @method createAlertDialog
- * @signature createAlertDialog(page, [options])
- * @param {String} page
- * [en]Page name. Can be either an HTML file or an `<template>` containing a <ons-alert-dialog> component.[/en]
- * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @return {Promise}
- * [en]Promise object that resolves to the alert dialog component object.[/en]
- * [ja]ダイアログのコンポーネントオブジェクトを解決するPromiseオブジェクトを返します。[/ja]
- * @description
- * [en]Create a alert dialog instance from a template.[/en]
- * [ja]テンプレートからアラートダイアログのインスタンスを生成します。[/ja]
- */
- ons$1.createPopover = ons$1.createDialog = ons$1.createAlertDialog = function (template) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- return ons$1.createElement(template, _extends({ append: true }, options));
- };
-
- /**
- * @method openActionSheet
- * @signature openActionSheet(options)
- * @description
- * [en]Shows an instant Action Sheet and lets the user choose an action.[/en]
- * [ja][/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {Array} [options.buttons]
- * [en]Represent each button of the action sheet following the specified order. Every item can be either a string label or an object containing `label`, `icon` and `modifier` properties.[/en]
- * [ja][/ja]
- * @param {String} [options.title]
- * [en]Optional title for the action sheet.[/en]
- * [ja][/ja]
- * @param {Number} [options.destructive]
- * [en]Optional index of the "destructive" button (only for iOS). It can be specified in the button array as well.[/en]
- * [ja][/ja]
- * @param {Boolean} [options.cancelable]
- * [en]Whether the action sheet can be canceled by tapping on the background mask or not.[/en]
- * [ja][/ja]
- * @param {String} [options.modifier]
- * [en]Modifier attribute of the action sheet. E.g. `'destructive'`.[/en]
- * [ja][/ja]
- * @param {String} [options.maskColor]
- * [en]Optionally change the background mask color.[/en]
- * [ja][/ja]
- * @param {String} [options.id]
- * [en]The element's id attribute.[/en]
- * [ja][/ja]
- * @param {String} [options.class]
- * [en]The element's class attribute.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Will resolve when the action sheet is closed. The resolve value is either the index of the tapped button or -1 when canceled.[/en]
- * [ja][/ja]
- */
- ons$1.openActionSheet = actionSheet;
-
- /**
- * @method resolveLoadingPlaceholder
- * @signature resolveLoadingPlaceholder(page)
- * @param {String} page
- * [en]Page name. Can be either an HTML file or a `<template>` id.[/en]
- * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
- * @description
- * [en]If no page is defined for the `ons-loading-placeholder` attribute it will wait for this method being called before loading the page.[/en]
- * [ja]ons-loading-placeholderの属性値としてページが指定されていない場合は、ページロード前に呼ばれるons.resolveLoadingPlaceholder処理が行われるまで表示されません。[/ja]
- */
- ons$1.resolveLoadingPlaceholder = function (page, link) {
- var elements = ons$1._util.arrayFrom(window.document.querySelectorAll('[ons-loading-placeholder]'));
- if (elements.length === 0) {
- util$1.throw('No ons-loading-placeholder exists');
- }
-
- elements.filter(function (element) {
- return !element.getAttribute('page');
- }).forEach(function (element) {
- element.setAttribute('ons-loading-placeholder', page);
- ons$1._resolveLoadingPlaceholder(element, page, link);
- });
- };
-
- ons$1._setupLoadingPlaceHolders = function () {
- ons$1.ready(function () {
- var elements = ons$1._util.arrayFrom(window.document.querySelectorAll('[ons-loading-placeholder]'));
-
- elements.forEach(function (element) {
- var page = element.getAttribute('ons-loading-placeholder');
- if (typeof page === 'string') {
- ons$1._resolveLoadingPlaceholder(element, page);
- }
- });
- });
- };
-
- ons$1._resolveLoadingPlaceholder = function (parent, page) {
- var link = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (el, done) {
- return done();
- };
-
- page && ons$1.createElement(page).then(function (element) {
- element.style.display = 'none';
- parent.appendChild(element);
- link(element, function () {
- while (parent.firstChild && parent.firstChild !== element) {
- parent.removeChild(parent.firstChild);
- }
- element.style.display = '';
- });
- }).catch(function (error) {
- return Promise.reject('Unabled to resolve placeholder: ' + error);
- });
- };
-
- function waitDeviceReady() {
- var unlockDeviceReady = ons$1._readyLock.lock();
- window.addEventListener('DOMContentLoaded', function () {
- if (ons$1.isWebView()) {
- window.document.addEventListener('deviceready', unlockDeviceReady, false);
- } else {
- unlockDeviceReady();
- }
- }, false);
- }
-
- /**
- * @method getScriptPage
- * @signature getScriptPage()
- * @description
- * [en]Access the last created page from the current `script` scope. Only works inside `<script></script>` tags that are direct children of `ons-page` element. Use this to add lifecycle hooks to a page.[/en]
- * [ja][/ja]
- * @return {HTMLElement}
- * [en]Returns the corresponding page element.[/en]
- * [ja][/ja]
- */
- var getCS = 'currentScript' in document ? function () {
- return document.currentScript;
- } : function () {
- return document.scripts[document.scripts.length - 1];
- };
- ons$1.getScriptPage = function () {
- return getCS() && /ons-page/i.test(getCS().parentElement.tagName) && getCS().parentElement || null;
- };
-
- function createCommonjsModule(fn, module) {
- return module = { exports: {} }, fn(module, module.exports), module.exports;
- }
-
- var fastclick = createCommonjsModule(function (module) {
- (function () {
- function FastClick(layer, options) {
- var oldOnClick;
-
- options = options || {};
-
- /**
- * Whether a click is currently being tracked.
- *
- * @type boolean
- */
- this.trackingClick = false;
-
- /**
- * Timestamp for when click tracking started.
- *
- * @type number
- */
- this.trackingClickStart = 0;
-
- /**
- * The element being tracked for a click.
- *
- * @type EventTarget
- */
- this.targetElement = null;
-
- /**
- * X-coordinate of touch start event.
- *
- * @type number
- */
- this.touchStartX = 0;
-
- /**
- * Y-coordinate of touch start event.
- *
- * @type number
- */
- this.touchStartY = 0;
-
- /**
- * ID of the last touch, retrieved from Touch.identifier.
- *
- * @type number
- */
- this.lastTouchIdentifier = 0;
-
- /**
- * Touchmove boundary, beyond which a click will be cancelled.
- *
- * @type number
- */
- this.touchBoundary = options.touchBoundary || 10;
-
- /**
- * The FastClick layer.
- *
- * @type Element
- */
- this.layer = layer;
-
- /**
- * The minimum time between tap(touchstart and touchend) events
- *
- * @type number
- */
- this.tapDelay = options.tapDelay || 200;
-
- /**
- * The maximum time for a tap
- *
- * @type number
- */
- this.tapTimeout = options.tapTimeout || 700;
-
- if (FastClick.notNeeded(layer)) {
- return;
- }
-
- // Some old versions of Android don't have Function.prototype.bind
- function bind(method, context) {
- return function () {
- return method.apply(context, arguments);
- };
- }
-
- var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
- var context = this;
- for (var i = 0, l = methods.length; i < l; i++) {
- context[methods[i]] = bind(context[methods[i]], context);
- }
-
- // Set up event handlers as required
- if (deviceIsAndroid) {
- layer.addEventListener('mouseover', this.onMouse, true);
- layer.addEventListener('mousedown', this.onMouse, true);
- layer.addEventListener('mouseup', this.onMouse, true);
- }
-
- layer.addEventListener('click', this.onClick, true);
- layer.addEventListener('touchstart', this.onTouchStart, false);
- layer.addEventListener('touchmove', this.onTouchMove, false);
- layer.addEventListener('touchend', this.onTouchEnd, false);
- layer.addEventListener('touchcancel', this.onTouchCancel, false);
-
- // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
- // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
- // layer when they are cancelled.
- if (!Event.prototype.stopImmediatePropagation) {
- layer.removeEventListener = function (type, callback, capture) {
- var rmv = Node.prototype.removeEventListener;
- if (type === 'click') {
- rmv.call(layer, type, callback.hijacked || callback, capture);
- } else {
- rmv.call(layer, type, callback, capture);
- }
- };
-
- layer.addEventListener = function (type, callback, capture) {
- var adv = Node.prototype.addEventListener;
- if (type === 'click') {
- adv.call(layer, type, callback.hijacked || (callback.hijacked = function (event) {
- if (!event.propagationStopped) {
- callback(event);
- }
- }), capture);
- } else {
- adv.call(layer, type, callback, capture);
- }
- };
- }
-
- // If a handler is already declared in the element's onclick attribute, it will be fired before
- // FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
- // adding it as listener.
- if (typeof layer.onclick === 'function') {
-
- // Android browser on at least 3.2 requires a new reference to the function in layer.onclick
- // - the old one won't work if passed to addEventListener directly.
- oldOnClick = layer.onclick;
- layer.addEventListener('click', function (event) {
- oldOnClick(event);
- }, false);
- layer.onclick = null;
- }
- }
-
- /**
- * Windows Phone 8.1 fakes user agent string to look like Android and iPhone.
- *
- * @type boolean
- */
- var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
-
- /**
- * Android requires exceptions.
- *
- * @type boolean
- */
- var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;
-
- /**
- * iOS requires exceptions.
- *
- * @type boolean
- */
- var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
-
- /**
- * iOS 4 requires an exception for select elements.
- *
- * @type boolean
- */
- var deviceIsIOS4 = deviceIsIOS && /OS 4_\d(_\d)?/.test(navigator.userAgent);
-
- /**
- * iOS 6.0-7.* requires the target element to be manually derived
- *
- * @type boolean
- */
- var deviceIsIOSWithBadTarget = deviceIsIOS && /OS [6-7]_\d/.test(navigator.userAgent);
-
- /**
- * BlackBerry requires exceptions.
- *
- * @type boolean
- */
- var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
-
- /**
- * Valid types for text inputs
- *
- * @type array
- */
- var textFields = ['email', 'number', 'password', 'search', 'tel', 'text', 'url'];
-
- /**
- * Determine whether a given element requires a native click.
- *
- * @param {EventTarget|Element} target Target DOM element
- * @returns {boolean} Returns true if the element needs a native click
- */
- FastClick.prototype.needsClick = function (target) {
- switch (target.nodeName.toLowerCase()) {
-
- // Don't send a synthetic click to disabled inputs (issue #62)
- case 'button':
- case 'select':
- case 'textarea':
- if (target.disabled) {
- return true;
- }
-
- break;
- case 'input':
-
- // File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
- if (deviceIsIOS && target.type === 'file' || target.disabled) {
- return true;
- }
-
- break;
- case 'label':
- case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames
- case 'video':
- return true;
- }
-
- return (/\bneedsclick\b/.test(target.className)
- );
- };
-
- /**
- * Determine whether a given element requires a call to focus to simulate click into element.
- *
- * @param {EventTarget|Element} target Target DOM element
- * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
- */
- FastClick.prototype.needsFocus = function (target) {
- switch (target.nodeName.toLowerCase()) {
- case 'textarea':
- return true;
- case 'select':
- return !deviceIsAndroid;
- case 'input':
- switch (target.type) {
- case 'button':
- case 'checkbox':
- case 'file':
- case 'image':
- case 'radio':
- case 'submit':
- return false;
- }
-
- // No point in attempting to focus disabled inputs
- return !target.disabled && !target.readOnly;
- default:
- return (/\bneedsfocus\b/.test(target.className)
- );
- }
- };
-
- /**
- * Send a click event to the specified element.
- *
- * @param {EventTarget|Element} targetElement
- * @param {Event} event
- */
- FastClick.prototype.sendClick = function (targetElement, event) {
- var clickEvent, touch;
-
- // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
- if (document.activeElement && document.activeElement !== targetElement) {
- document.activeElement.blur();
- }
-
- touch = event.changedTouches[0];
-
- // Synthesise a click event, with an extra attribute so it can be tracked
- clickEvent = document.createEvent('MouseEvents');
- clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
- clickEvent.forwardedTouchEvent = true;
- targetElement.dispatchEvent(clickEvent);
- };
-
- FastClick.prototype.determineEventType = function (targetElement) {
-
- //Issue #159: Android Chrome Select Box does not open with a synthetic click event
- if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
- return 'mousedown';
- }
-
- return 'click';
- };
-
- /**
- * @param {EventTarget|Element} targetElement
- */
- FastClick.prototype.focus = function (targetElement) {
- var length;
-
- // Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
- if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month' && targetElement.type !== 'email' && targetElement.type !== 'number') {
- length = targetElement.value.length;
- targetElement.setSelectionRange(length, length);
- } else {
- targetElement.focus();
- }
- };
-
- /**
- * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
- *
- * @param {EventTarget|Element} targetElement
- */
- FastClick.prototype.updateScrollParent = function (targetElement) {
- var scrollParent, parentElement;
-
- scrollParent = targetElement.fastClickScrollParent;
-
- // Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
- // target element was moved to another parent.
- if (!scrollParent || !scrollParent.contains(targetElement)) {
- parentElement = targetElement;
- do {
- if (parentElement.scrollHeight > parentElement.offsetHeight) {
- scrollParent = parentElement;
- targetElement.fastClickScrollParent = parentElement;
- break;
- }
-
- parentElement = parentElement.parentElement;
- } while (parentElement);
- }
-
- // Always update the scroll top tracker if possible.
- if (scrollParent) {
- scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
- }
- };
-
- /**
- * @param {EventTarget} targetElement
- * @returns {Element|EventTarget}
- */
- FastClick.prototype.getTargetElementFromEventTarget = function (eventTarget) {
-
- // On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
- if (eventTarget.nodeType === Node.TEXT_NODE) {
- return eventTarget.parentNode;
- }
-
- return eventTarget;
- };
-
- /**
- * @param {EventTarget} targetElement
- * @returns {boolean}
- */
- FastClick.prototype.isTextField = function (targetElement) {
- return targetElement.tagName.toLowerCase() === 'textarea' || textFields.indexOf(targetElement.type) !== -1;
- };
-
- /**
- * On touch start, record the position and scroll offset.
- *
- * @param {Event} event
- * @returns {boolean}
- */
- FastClick.prototype.onTouchStart = function (event) {
- var targetElement, touch;
-
- // Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
- if (event.targetTouches.length > 1) {
- return true;
- }
-
- targetElement = this.getTargetElementFromEventTarget(event.target);
- touch = event.targetTouches[0];
-
- // Ignore touches on contenteditable elements to prevent conflict with text selection.
- // (For details: https://github.com/ftlabs/fastclick/pull/211 )
- if (targetElement.isContentEditable) {
- return true;
- }
-
- if (deviceIsIOS) {
- // Ignore touchstart in focused text field
- // Allows normal text selection and commands (select/paste/cut) when a field has focus, while still allowing fast tap-to-focus.
- // Without this fix, user needs to tap-and-hold a text field for context menu, and double-tap to select text doesn't work at all.
- if (targetElement === document.activeElement && this.isTextField(targetElement)) {
- return true;
- }
-
- if (!deviceIsIOS4) {
-
- // Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
- // when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
- // with the same identifier as the touch event that previously triggered the click that triggered the alert.
- // Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
- // immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
- // Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
- // which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
- // random integers, it's safe to to continue if the identifier is 0 here.
- if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
- event.preventDefault();
- return false;
- }
-
- this.lastTouchIdentifier = touch.identifier;
-
- // If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
- // 1) the user does a fling scroll on the scrollable layer
- // 2) the user stops the fling scroll with another tap
- // then the event.target of the last 'touchend' event will be the element that was under the user's finger
- // when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
- // is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
- this.updateScrollParent(targetElement);
- }
- }
-
- this.trackingClick = true;
- this.trackingClickStart = event.timeStamp;
- this.targetElement = targetElement;
-
- this.touchStartX = touch.pageX;
- this.touchStartY = touch.pageY;
-
- // Prevent phantom clicks on fast double-tap (issue #36)
- if (event.timeStamp - this.lastClickTime < this.tapDelay && event.timeStamp - this.lastClickTime > -1) {
- event.preventDefault();
- }
-
- return true;
- };
-
- /**
- * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
- *
- * @param {Event} event
- * @returns {boolean}
- */
- FastClick.prototype.touchHasMoved = function (event) {
- var touch = event.changedTouches[0],
- boundary = this.touchBoundary;
-
- if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
- return true;
- }
-
- return false;
- };
-
- /**
- * Update the last position.
- *
- * @param {Event} event
- * @returns {boolean}
- */
- FastClick.prototype.onTouchMove = function (event) {
- if (!this.trackingClick) {
- return true;
- }
-
- // If the touch has moved, cancel the click tracking
- if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
- this.trackingClick = false;
- this.targetElement = null;
- }
-
- return true;
- };
-
- /**
- * Attempt to find the labelled control for the given label element.
- *
- * @param {EventTarget|HTMLLabelElement} labelElement
- * @returns {Element|null}
- */
- FastClick.prototype.findControl = function (labelElement) {
-
- // Fast path for newer browsers supporting the HTML5 control attribute
- if (labelElement.control !== undefined) {
- return labelElement.control;
- }
-
- // All browsers under test that support touch events also support the HTML5 htmlFor attribute
- if (labelElement.htmlFor) {
- return document.getElementById(labelElement.htmlFor);
- }
-
- // If no for attribute exists, attempt to retrieve the first labellable descendant element
- // the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
- return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
- };
-
- /**
- * On touch end, determine whether to send a click event at once.
- *
- * @param {Event} event
- * @returns {boolean}
- */
- FastClick.prototype.onTouchEnd = function (event) {
- var forElement,
- trackingClickStart,
- targetTagName,
- scrollParent,
- touch,
- targetElement = this.targetElement;
-
- if (!this.trackingClick) {
- return true;
- }
-
- // Prevent phantom clicks on fast double-tap (issue #36)
- if (event.timeStamp - this.lastClickTime < this.tapDelay && event.timeStamp - this.lastClickTime > -1) {
- this.cancelNextClick = true;
- return true;
- }
-
- if (event.timeStamp - this.trackingClickStart > this.tapTimeout) {
- return true;
- }
-
- // Reset to prevent wrong click cancel on input (issue #156).
- this.cancelNextClick = false;
-
- this.lastClickTime = event.timeStamp;
-
- trackingClickStart = this.trackingClickStart;
- this.trackingClick = false;
- this.trackingClickStart = 0;
-
- // On some iOS devices, the targetElement supplied with the event is invalid if the layer
- // is performing a transition or scroll, and has to be re-detected manually. Note that
- // for this to function correctly, it must be called *after* the event target is checked!
- // See issue #57; also filed as rdar://13048589 .
- if (deviceIsIOSWithBadTarget) {
- touch = event.changedTouches[0];
-
- // In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
- targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
- targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
- }
-
- targetTagName = targetElement.tagName.toLowerCase();
- if (targetTagName === 'label') {
- forElement = this.findControl(targetElement);
- if (forElement) {
- this.focus(targetElement);
- if (deviceIsAndroid) {
- return false;
- }
-
- targetElement = forElement;
- }
- } else if (this.needsFocus(targetElement)) {
-
- // Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
- // Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
- if (event.timeStamp - trackingClickStart > 100 || deviceIsIOS && window.top !== window && targetTagName === 'input') {
- this.targetElement = null;
- return false;
- }
-
- this.focus(targetElement);
- this.sendClick(targetElement, event);
-
- // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
- // Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
- if (!deviceIsIOS4 || targetTagName !== 'select') {
- this.targetElement = null;
- event.preventDefault();
- }
-
- return false;
- }
-
- if (deviceIsIOS && !deviceIsIOS4) {
-
- // Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
- // and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
- scrollParent = targetElement.fastClickScrollParent;
- if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
- return true;
- }
- }
-
- // Prevent the actual click from going though - unless the target node is marked as requiring
- // real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
- if (!this.needsClick(targetElement)) {
- event.preventDefault();
- this.sendClick(targetElement, event);
- }
-
- return false;
- };
-
- /**
- * On touch cancel, stop tracking the click.
- *
- * @returns {void}
- */
- FastClick.prototype.onTouchCancel = function () {
- this.trackingClick = false;
- this.targetElement = null;
- };
-
- /**
- * Determine mouse events which should be permitted.
- *
- * @param {Event} event
- * @returns {boolean}
- */
- FastClick.prototype.onMouse = function (event) {
-
- // If a target element was never set (because a touch event was never fired) allow the event
- if (!this.targetElement) {
- return true;
- }
-
- if (event.forwardedTouchEvent) {
- return true;
- }
-
- // Programmatically generated events targeting a specific element should be permitted
- if (!event.cancelable) {
- return true;
- }
-
- // Derive and check the target element to see whether the mouse event needs to be permitted;
- // unless explicitly enabled, prevent non-touch click events from triggering actions,
- // to prevent ghost/doubleclicks.
- if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
-
- // Prevent any user-added listeners declared on FastClick element from being fired.
- if (event.stopImmediatePropagation) {
- event.stopImmediatePropagation();
- } else {
-
- // Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
- event.propagationStopped = true;
- }
-
- // Cancel the event
- event.stopPropagation();
- event.preventDefault();
-
- return false;
- }
-
- // If the mouse event is permitted, return true for the action to go through.
- return true;
- };
-
- /**
- * On actual clicks, determine whether this is a touch-generated click, a click action occurring
- * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
- * an actual click which should be permitted.
- *
- * @param {Event} event
- * @returns {boolean}
- */
- FastClick.prototype.onClick = function (event) {
- var permitted;
-
- // It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
- if (this.trackingClick) {
- this.targetElement = null;
- this.trackingClick = false;
- return true;
- }
-
- // Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
- if (event.target.type === 'submit' && event.detail === 0) {
- return true;
- }
-
- permitted = this.onMouse(event);
-
- // Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
- if (!permitted) {
- this.targetElement = null;
- }
-
- // If clicks are permitted, return true for the action to go through.
- return permitted;
- };
-
- /**
- * Remove all FastClick's event listeners.
- *
- * @returns {void}
- */
- FastClick.prototype.destroy = function () {
- var layer = this.layer;
-
- if (deviceIsAndroid) {
- layer.removeEventListener('mouseover', this.onMouse, true);
- layer.removeEventListener('mousedown', this.onMouse, true);
- layer.removeEventListener('mouseup', this.onMouse, true);
- }
-
- layer.removeEventListener('click', this.onClick, true);
- layer.removeEventListener('touchstart', this.onTouchStart, false);
- layer.removeEventListener('touchmove', this.onTouchMove, false);
- layer.removeEventListener('touchend', this.onTouchEnd, false);
- layer.removeEventListener('touchcancel', this.onTouchCancel, false);
- };
-
- /**
- * Check whether FastClick is needed.
- *
- * @param {Element} layer The layer to listen on
- */
- FastClick.notNeeded = function (layer) {
- var metaViewport;
- var chromeVersion;
- var blackberryVersion;
- var firefoxVersion;
-
- // Devices that don't support touch don't need FastClick
- if (typeof window.ontouchstart === 'undefined') {
- return true;
- }
-
- // Chrome version - zero for other browsers
- chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [, 0])[1];
-
- if (chromeVersion) {
-
- if (deviceIsAndroid) {
- metaViewport = document.querySelector('meta[name=viewport]');
-
- if (metaViewport) {
- // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
- if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
- return true;
- }
- // Chrome 32 and above with width=device-width or less don't need FastClick
- if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
- return true;
- }
- }
-
- // Chrome desktop doesn't need FastClick (issue #15)
- } else {
- return true;
- }
- }
-
- if (deviceIsBlackBerry10) {
- blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
-
- // BlackBerry 10.3+ does not require Fastclick library.
- // https://github.com/ftlabs/fastclick/issues/251
- if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
- metaViewport = document.querySelector('meta[name=viewport]');
-
- if (metaViewport) {
- // user-scalable=no eliminates click delay.
- if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
- return true;
- }
- // width=device-width (or less than device-width) eliminates click delay.
- if (document.documentElement.scrollWidth <= window.outerWidth) {
- return true;
- }
- }
- }
- }
-
- // IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)
- if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {
- return true;
- }
-
- // Firefox version - zero for other browsers
- firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [, 0])[1];
-
- if (firefoxVersion >= 27) {
- // Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896
-
- metaViewport = document.querySelector('meta[name=viewport]');
- if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
- return true;
- }
- }
-
- // IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version
- // http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx
- if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {
- return true;
- }
-
- return false;
- };
-
- /**
- * Factory method for creating a FastClick object
- *
- * @param {Element} layer The layer to listen on
- * @param {Object} [options={}] The options to override the defaults
- */
- FastClick.attach = function (layer, options) {
- return new FastClick(layer, options);
- };
-
- if (typeof undefined === 'function' && _typeof(undefined.amd) === 'object' && undefined.amd) {
-
- // AMD. Register as an anonymous module.
- undefined(function () {
- return FastClick;
- });
- } else if ('object' !== 'undefined' && module.exports) {
- module.exports = FastClick.attach;
- module.exports.FastClick = FastClick;
- } else {
- window.FastClick = FastClick;
- }
- })();
- });
-
- var fastclick_1 = fastclick.FastClick;
-
- // For @onsenui/custom-elements
- if (window.customElements) {
- // even if native CE1 impl exists, use polyfill
- window.customElements.forcePolyfill = true;
- }
-
- var _global = createCommonjsModule(function (module) {
- // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
- var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self
- // eslint-disable-next-line no-new-func
- : Function('return this')();
- if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
- });
-
- var _core = createCommonjsModule(function (module) {
- var core = module.exports = { version: '2.5.1' };
- if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
- });
-
- var _core_1 = _core.version;
-
- var _isObject = function _isObject(it) {
- return (typeof it === 'undefined' ? 'undefined' : _typeof(it)) === 'object' ? it !== null : typeof it === 'function';
- };
-
- var _anObject = function _anObject(it) {
- if (!_isObject(it)) throw TypeError(it + ' is not an object!');
- return it;
- };
-
- var _fails = function _fails(exec) {
- try {
- return !!exec();
- } catch (e) {
- return true;
- }
- };
-
- // Thank's IE8 for his funny defineProperty
- var _descriptors = !_fails(function () {
- return Object.defineProperty({}, 'a', { get: function get() {
- return 7;
- } }).a != 7;
- });
-
- var document$1 = _global.document;
- // typeof document.createElement is 'object' in old IE
- var is = _isObject(document$1) && _isObject(document$1.createElement);
- var _domCreate = function _domCreate(it) {
- return is ? document$1.createElement(it) : {};
- };
-
- var _ie8DomDefine = !_descriptors && !_fails(function () {
- return Object.defineProperty(_domCreate('div'), 'a', { get: function get() {
- return 7;
- } }).a != 7;
- });
-
- // 7.1.1 ToPrimitive(input [, PreferredType])
-
- // instead of the ES6 spec version, we didn't implement @@toPrimitive case
- // and the second argument - flag - preferred type is a string
- var _toPrimitive = function _toPrimitive(it, S) {
- if (!_isObject(it)) return it;
- var fn, val;
- if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
- if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
- if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
- throw TypeError("Can't convert object to primitive value");
- };
-
- var dP = Object.defineProperty;
-
- var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
- _anObject(O);
- P = _toPrimitive(P, true);
- _anObject(Attributes);
- if (_ie8DomDefine) try {
- return dP(O, P, Attributes);
- } catch (e) {/* empty */}
- if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
- if ('value' in Attributes) O[P] = Attributes.value;
- return O;
- };
-
- var _objectDp = {
- f: f
- };
-
- var _propertyDesc = function _propertyDesc(bitmap, value) {
- return {
- enumerable: !(bitmap & 1),
- configurable: !(bitmap & 2),
- writable: !(bitmap & 4),
- value: value
- };
- };
-
- var _hide = _descriptors ? function (object, key, value) {
- return _objectDp.f(object, key, _propertyDesc(1, value));
- } : function (object, key, value) {
- object[key] = value;
- return object;
- };
-
- var hasOwnProperty = {}.hasOwnProperty;
- var _has = function _has(it, key) {
- return hasOwnProperty.call(it, key);
- };
-
- var id = 0;
- var px = Math.random();
- var _uid = function _uid(key) {
- return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
- };
-
- var _redefine = createCommonjsModule(function (module) {
- var SRC = _uid('src');
- var TO_STRING = 'toString';
- var $toString = Function[TO_STRING];
- var TPL = ('' + $toString).split(TO_STRING);
-
- _core.inspectSource = function (it) {
- return $toString.call(it);
- };
-
- (module.exports = function (O, key, val, safe) {
- var isFunction = typeof val == 'function';
- if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
- if (O[key] === val) return;
- if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
- if (O === _global) {
- O[key] = val;
- } else if (!safe) {
- delete O[key];
- _hide(O, key, val);
- } else if (O[key]) {
- O[key] = val;
- } else {
- _hide(O, key, val);
- }
- // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
- })(Function.prototype, TO_STRING, function toString() {
- return typeof this == 'function' && this[SRC] || $toString.call(this);
- });
- });
-
- var _aFunction = function _aFunction(it) {
- if (typeof it != 'function') throw TypeError(it + ' is not a function!');
- return it;
- };
-
- // optional / simple context binding
-
- var _ctx = function _ctx(fn, that, length) {
- _aFunction(fn);
- if (that === undefined) return fn;
- switch (length) {
- case 1:
- return function (a) {
- return fn.call(that, a);
- };
- case 2:
- return function (a, b) {
- return fn.call(that, a, b);
- };
- case 3:
- return function (a, b, c) {
- return fn.call(that, a, b, c);
- };
- }
- return function () /* ...args */{
- return fn.apply(that, arguments);
- };
- };
-
- var PROTOTYPE = 'prototype';
-
- var $export = function $export(type, name, source) {
- var IS_FORCED = type & $export.F;
- var IS_GLOBAL = type & $export.G;
- var IS_STATIC = type & $export.S;
- var IS_PROTO = type & $export.P;
- var IS_BIND = type & $export.B;
- var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
- var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
- var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
- var key, own, out, exp;
- if (IS_GLOBAL) source = name;
- for (key in source) {
- // contains in native
- own = !IS_FORCED && target && target[key] !== undefined;
- // export native or passed
- out = (own ? target : source)[key];
- // bind timers to global for call from export context
- exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
- // extend global
- if (target) _redefine(target, key, out, type & $export.U);
- // export
- if (exports[key] != out) _hide(exports, key, exp);
- if (IS_PROTO && expProto[key] != out) expProto[key] = out;
- }
- };
- _global.core = _core;
- // type bitmap
- $export.F = 1; // forced
- $export.G = 2; // global
- $export.S = 4; // static
- $export.P = 8; // proto
- $export.B = 16; // bind
- $export.W = 32; // wrap
- $export.U = 64; // safe
- $export.R = 128; // real proto method for `library`
- var _export = $export;
-
- var f$2 = {}.propertyIsEnumerable;
-
- var _objectPie = {
- f: f$2
- };
-
- var toString = {}.toString;
-
- var _cof = function _cof(it) {
- return toString.call(it).slice(8, -1);
- };
-
- // fallback for non-array-like ES3 and non-enumerable old V8 strings
-
- // eslint-disable-next-line no-prototype-builtins
- var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
- return _cof(it) == 'String' ? it.split('') : Object(it);
- };
-
- // 7.2.1 RequireObjectCoercible(argument)
- var _defined = function _defined(it) {
- if (it == undefined) throw TypeError("Can't call method on " + it);
- return it;
- };
-
- // to indexed object, toObject with fallback for non-array-like ES3 strings
-
-
- var _toIobject = function _toIobject(it) {
- return _iobject(_defined(it));
- };
-
- var gOPD = Object.getOwnPropertyDescriptor;
-
- var f$1 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) {
- O = _toIobject(O);
- P = _toPrimitive(P, true);
- if (_ie8DomDefine) try {
- return gOPD(O, P);
- } catch (e) {/* empty */}
- if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]);
- };
-
- var _objectGopd = {
- f: f$1
- };
-
- // Works with __proto__ only. Old v8 can't work with null proto objects.
- /* eslint-disable no-proto */
-
- var check = function check(O, proto) {
- _anObject(O);
- if (!_isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
- };
- var _setProto = {
- set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
- function (test, buggy, set) {
- try {
- set = _ctx(Function.call, _objectGopd.f(Object.prototype, '__proto__').set, 2);
- set(test, []);
- buggy = !(test instanceof Array);
- } catch (e) {
- buggy = true;
- }
- return function setPrototypeOf(O, proto) {
- check(O, proto);
- if (buggy) O.__proto__ = proto;else set(O, proto);
- return O;
- };
- }({}, false) : undefined),
- check: check
- };
-
- // 19.1.3.19 Object.setPrototypeOf(O, proto)
-
- _export(_export.S, 'Object', { setPrototypeOf: _setProto.set });
-
- var setPrototypeOf = _core.Object.setPrototypeOf;
-
- var SHARED = '__core-js_shared__';
- var store = _global[SHARED] || (_global[SHARED] = {});
- var _shared = function _shared(key) {
- return store[key] || (store[key] = {});
- };
-
- var _wks = createCommonjsModule(function (module) {
- var store = _shared('wks');
-
- var _Symbol = _global.Symbol;
- var USE_SYMBOL = typeof _Symbol == 'function';
-
- var $exports = module.exports = function (name) {
- return store[name] || (store[name] = USE_SYMBOL && _Symbol[name] || (USE_SYMBOL ? _Symbol : _uid)('Symbol.' + name));
- };
-
- $exports.store = store;
- });
-
- // getting tag from 19.1.3.6 Object.prototype.toString()
-
- var TAG = _wks('toStringTag');
- // ES3 wrong here
- var ARG = _cof(function () {
- return arguments;
- }()) == 'Arguments';
-
- // fallback for IE11 Script Access Denied error
- var tryGet = function tryGet(it, key) {
- try {
- return it[key];
- } catch (e) {/* empty */}
- };
-
- var _classof = function _classof(it) {
- var O, T, B;
- return it === undefined ? 'Undefined' : it === null ? 'Null'
- // @@toStringTag case
- : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
- // builtinTag case
- : ARG ? _cof(O)
- // ES3 arguments fallback
- : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
- };
-
- // 19.1.3.6 Object.prototype.toString()
-
- var test = {};
- test[_wks('toStringTag')] = 'z';
- if (test + '' != '[object z]') {
- _redefine(Object.prototype, 'toString', function toString() {
- return '[object ' + _classof(this) + ']';
- }, true);
- }
-
- // 7.1.4 ToInteger
- var ceil = Math.ceil;
- var floor = Math.floor;
- var _toInteger = function _toInteger(it) {
- return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
- };
-
- // true -> String#at
- // false -> String#codePointAt
- var _stringAt = function _stringAt(TO_STRING) {
- return function (that, pos) {
- var s = String(_defined(that));
- var i = _toInteger(pos);
- var l = s.length;
- var a, b;
- if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
- a = s.charCodeAt(i);
- return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
- };
- };
-
- var _library = false;
-
- var _iterators = {};
-
- // 7.1.15 ToLength
-
- var min = Math.min;
- var _toLength = function _toLength(it) {
- return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
- };
-
- var max = Math.max;
- var min$1 = Math.min;
- var _toAbsoluteIndex = function _toAbsoluteIndex(index, length) {
- index = _toInteger(index);
- return index < 0 ? max(index + length, 0) : min$1(index, length);
- };
-
- // false -> Array#indexOf
- // true -> Array#includes
-
-
- var _arrayIncludes = function _arrayIncludes(IS_INCLUDES) {
- return function ($this, el, fromIndex) {
- var O = _toIobject($this);
- var length = _toLength(O.length);
- var index = _toAbsoluteIndex(fromIndex, length);
- var value;
- // Array#includes uses SameValueZero equality algorithm
- // eslint-disable-next-line no-self-compare
- if (IS_INCLUDES && el != el) while (length > index) {
- value = O[index++];
- // eslint-disable-next-line no-self-compare
- if (value != value) return true;
- // Array#indexOf ignores holes, Array#includes - not
- } else for (; length > index; index++) {
- if (IS_INCLUDES || index in O) {
- if (O[index] === el) return IS_INCLUDES || index || 0;
- }
- }return !IS_INCLUDES && -1;
- };
- };
-
- var shared = _shared('keys');
-
- var _sharedKey = function _sharedKey(key) {
- return shared[key] || (shared[key] = _uid(key));
- };
-
- var arrayIndexOf = _arrayIncludes(false);
- var IE_PROTO$1 = _sharedKey('IE_PROTO');
-
- var _objectKeysInternal = function _objectKeysInternal(object, names) {
- var O = _toIobject(object);
- var i = 0;
- var result = [];
- var key;
- for (key in O) {
- if (key != IE_PROTO$1) _has(O, key) && result.push(key);
- } // Don't enum bug & hidden keys
- while (names.length > i) {
- if (_has(O, key = names[i++])) {
- ~arrayIndexOf(result, key) || result.push(key);
- }
- }return result;
- };
-
- // IE 8- don't enum bug keys
- var _enumBugKeys = 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'.split(',');
-
- // 19.1.2.14 / 15.2.3.14 Object.keys(O)
-
-
- var _objectKeys = Object.keys || function keys(O) {
- return _objectKeysInternal(O, _enumBugKeys);
- };
-
- var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
- _anObject(O);
- var keys = _objectKeys(Properties);
- var length = keys.length;
- var i = 0;
- var P;
- while (length > i) {
- _objectDp.f(O, P = keys[i++], Properties[P]);
- }return O;
- };
-
- var document$2 = _global.document;
- var _html = document$2 && document$2.documentElement;
-
- // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
-
-
- var IE_PROTO = _sharedKey('IE_PROTO');
- var Empty = function Empty() {/* empty */};
- var PROTOTYPE$1 = 'prototype';
-
- // Create object with fake `null` prototype: use iframe Object with cleared prototype
- var _createDict = function createDict() {
- // Thrash, waste and sodomy: IE GC bug
- var iframe = _domCreate('iframe');
- var i = _enumBugKeys.length;
- var lt = '<';
- var gt = '>';
- var iframeDocument;
- iframe.style.display = 'none';
- _html.appendChild(iframe);
- iframe.src = 'javascript:'; // eslint-disable-line no-script-url
- // createDict = iframe.contentWindow.Object;
- // html.removeChild(iframe);
- iframeDocument = iframe.contentWindow.document;
- iframeDocument.open();
- iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
- iframeDocument.close();
- _createDict = iframeDocument.F;
- while (i--) {
- delete _createDict[PROTOTYPE$1][_enumBugKeys[i]];
- }return _createDict();
- };
-
- var _objectCreate = Object.create || function create(O, Properties) {
- var result;
- if (O !== null) {
- Empty[PROTOTYPE$1] = _anObject(O);
- result = new Empty();
- Empty[PROTOTYPE$1] = null;
- // add "__proto__" for Object.getPrototypeOf polyfill
- result[IE_PROTO] = O;
- } else result = _createDict();
- return Properties === undefined ? result : _objectDps(result, Properties);
- };
-
- var def = _objectDp.f;
-
- var TAG$1 = _wks('toStringTag');
-
- var _setToStringTag = function _setToStringTag(it, tag, stat) {
- if (it && !_has(it = stat ? it : it.prototype, TAG$1)) def(it, TAG$1, { configurable: true, value: tag });
- };
-
- var IteratorPrototype = {};
-
- // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
- _hide(IteratorPrototype, _wks('iterator'), function () {
- return this;
- });
-
- var _iterCreate = function _iterCreate(Constructor, NAME, next) {
- Constructor.prototype = _objectCreate(IteratorPrototype, { next: _propertyDesc(1, next) });
- _setToStringTag(Constructor, NAME + ' Iterator');
- };
-
- // 7.1.13 ToObject(argument)
-
- var _toObject = function _toObject(it) {
- return Object(_defined(it));
- };
-
- // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
-
-
- var IE_PROTO$2 = _sharedKey('IE_PROTO');
- var ObjectProto = Object.prototype;
-
- var _objectGpo = Object.getPrototypeOf || function (O) {
- O = _toObject(O);
- if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2];
- if (typeof O.constructor == 'function' && O instanceof O.constructor) {
- return O.constructor.prototype;
- }return O instanceof Object ? ObjectProto : null;
- };
-
- var ITERATOR = _wks('iterator');
- var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
- var FF_ITERATOR = '@@iterator';
- var KEYS = 'keys';
- var VALUES = 'values';
-
- var returnThis = function returnThis() {
- return this;
- };
-
- var _iterDefine = function _iterDefine(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
- _iterCreate(Constructor, NAME, next);
- var getMethod = function getMethod(kind) {
- if (!BUGGY && kind in proto) return proto[kind];
- switch (kind) {
- case KEYS:
- return function keys() {
- return new Constructor(this, kind);
- };
- case VALUES:
- return function values() {
- return new Constructor(this, kind);
- };
- }return function entries() {
- return new Constructor(this, kind);
- };
- };
- var TAG = NAME + ' Iterator';
- var DEF_VALUES = DEFAULT == VALUES;
- var VALUES_BUG = false;
- var proto = Base.prototype;
- var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
- var $default = $native || getMethod(DEFAULT);
- var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
- var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
- var methods, key, IteratorPrototype;
- // Fix native
- if ($anyNative) {
- IteratorPrototype = _objectGpo($anyNative.call(new Base()));
- if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
- // Set @@toStringTag to native iterators
- _setToStringTag(IteratorPrototype, TAG, true);
- // fix for some old engines
- if (!_library && !_has(IteratorPrototype, ITERATOR)) _hide(IteratorPrototype, ITERATOR, returnThis);
- }
- }
- // fix Array#{values, @@iterator}.name in V8 / FF
- if (DEF_VALUES && $native && $native.name !== VALUES) {
- VALUES_BUG = true;
- $default = function values() {
- return $native.call(this);
- };
- }
- // Define iterator
- if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
- _hide(proto, ITERATOR, $default);
- }
- // Plug for library
- _iterators[NAME] = $default;
- _iterators[TAG] = returnThis;
- if (DEFAULT) {
- methods = {
- values: DEF_VALUES ? $default : getMethod(VALUES),
- keys: IS_SET ? $default : getMethod(KEYS),
- entries: $entries
- };
- if (FORCED) for (key in methods) {
- if (!(key in proto)) _redefine(proto, key, methods[key]);
- } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
- }
- return methods;
- };
-
- var $at = _stringAt(true);
-
- // 21.1.3.27 String.prototype[@@iterator]()
- _iterDefine(String, 'String', function (iterated) {
- this._t = String(iterated); // target
- this._i = 0; // next index
- // 21.1.5.2.1 %StringIteratorPrototype%.next()
- }, function () {
- var O = this._t;
- var index = this._i;
- var point;
- if (index >= O.length) return { value: undefined, done: true };
- point = $at(O, index);
- this._i += point.length;
- return { value: point, done: false };
- });
-
- // 22.1.3.31 Array.prototype[@@unscopables]
- var UNSCOPABLES = _wks('unscopables');
- var ArrayProto = Array.prototype;
- if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {});
- var _addToUnscopables = function _addToUnscopables(key) {
- ArrayProto[UNSCOPABLES][key] = true;
- };
-
- var _iterStep = function _iterStep(done, value) {
- return { value: value, done: !!done };
- };
-
- // 22.1.3.4 Array.prototype.entries()
- // 22.1.3.13 Array.prototype.keys()
- // 22.1.3.29 Array.prototype.values()
- // 22.1.3.30 Array.prototype[@@iterator]()
- var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
- this._t = _toIobject(iterated); // target
- this._i = 0; // next index
- this._k = kind; // kind
- // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
- }, function () {
- var O = this._t;
- var kind = this._k;
- var index = this._i++;
- if (!O || index >= O.length) {
- this._t = undefined;
- return _iterStep(1);
- }
- if (kind == 'keys') return _iterStep(0, index);
- if (kind == 'values') return _iterStep(0, O[index]);
- return _iterStep(0, [index, O[index]]);
- }, 'values');
-
- // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
- _iterators.Arguments = _iterators.Array;
-
- _addToUnscopables('keys');
- _addToUnscopables('values');
- _addToUnscopables('entries');
-
- var ITERATOR$1 = _wks('iterator');
- var TO_STRING_TAG = _wks('toStringTag');
- var ArrayValues = _iterators.Array;
-
- var DOMIterables = {
- CSSRuleList: true, // TODO: Not spec compliant, should be false.
- CSSStyleDeclaration: false,
- CSSValueList: false,
- ClientRectList: false,
- DOMRectList: false,
- DOMStringList: false,
- DOMTokenList: true,
- DataTransferItemList: false,
- FileList: false,
- HTMLAllCollection: false,
- HTMLCollection: false,
- HTMLFormElement: false,
- HTMLSelectElement: false,
- MediaList: true, // TODO: Not spec compliant, should be false.
- MimeTypeArray: false,
- NamedNodeMap: false,
- NodeList: true,
- PaintRequestList: false,
- Plugin: false,
- PluginArray: false,
- SVGLengthList: false,
- SVGNumberList: false,
- SVGPathSegList: false,
- SVGPointList: false,
- SVGStringList: false,
- SVGTransformList: false,
- SourceBufferList: false,
- StyleSheetList: true, // TODO: Not spec compliant, should be false.
- TextTrackCueList: false,
- TextTrackList: false,
- TouchList: false
- };
-
- for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
- var NAME = collections[i];
- var explicit = DOMIterables[NAME];
- var Collection = _global[NAME];
- var proto = Collection && Collection.prototype;
- var key;
- if (proto) {
- if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues);
- if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME);
- _iterators[NAME] = ArrayValues;
- if (explicit) for (key in es6_array_iterator) {
- if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true);
- }
- }
- }
-
- var _redefineAll = function _redefineAll(target, src, safe) {
- for (var key in src) {
- _redefine(target, key, src[key], safe);
- }return target;
- };
-
- var _anInstance = function _anInstance(it, Constructor, name, forbiddenField) {
- if (!(it instanceof Constructor) || forbiddenField !== undefined && forbiddenField in it) {
- throw TypeError(name + ': incorrect invocation!');
- }return it;
- };
-
- // call something on iterator step with safe closing on error
-
- var _iterCall = function _iterCall(iterator, fn, value, entries) {
- try {
- return entries ? fn(_anObject(value)[0], value[1]) : fn(value);
- // 7.4.6 IteratorClose(iterator, completion)
- } catch (e) {
- var ret = iterator['return'];
- if (ret !== undefined) _anObject(ret.call(iterator));
- throw e;
- }
- };
-
- // check on default Array iterator
-
- var ITERATOR$2 = _wks('iterator');
- var ArrayProto$1 = Array.prototype;
-
- var _isArrayIter = function _isArrayIter(it) {
- return it !== undefined && (_iterators.Array === it || ArrayProto$1[ITERATOR$2] === it);
- };
-
- var ITERATOR$3 = _wks('iterator');
-
- var core_getIteratorMethod = _core.getIteratorMethod = function (it) {
- if (it != undefined) return it[ITERATOR$3] || it['@@iterator'] || _iterators[_classof(it)];
- };
-
- var _forOf = createCommonjsModule(function (module) {
- var BREAK = {};
- var RETURN = {};
- var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {
- var iterFn = ITERATOR ? function () {
- return iterable;
- } : core_getIteratorMethod(iterable);
- var f = _ctx(fn, that, entries ? 2 : 1);
- var index = 0;
- var length, step, iterator, result;
- if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
- // fast case for arrays with default iterator
- if (_isArrayIter(iterFn)) for (length = _toLength(iterable.length); length > index; index++) {
- result = entries ? f(_anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
- if (result === BREAK || result === RETURN) return result;
- } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
- result = _iterCall(iterator, f, step.value, entries);
- if (result === BREAK || result === RETURN) return result;
- }
- };
- exports.BREAK = BREAK;
- exports.RETURN = RETURN;
- });
-
- var SPECIES = _wks('species');
-
- var _setSpecies = function _setSpecies(KEY) {
- var C = _global[KEY];
- if (_descriptors && C && !C[SPECIES]) _objectDp.f(C, SPECIES, {
- configurable: true,
- get: function get() {
- return this;
- }
- });
- };
-
- var _meta = createCommonjsModule(function (module) {
- var META = _uid('meta');
-
- var setDesc = _objectDp.f;
- var id = 0;
- var isExtensible = Object.isExtensible || function () {
- return true;
- };
- var FREEZE = !_fails(function () {
- return isExtensible(Object.preventExtensions({}));
- });
- var setMeta = function setMeta(it) {
- setDesc(it, META, { value: {
- i: 'O' + ++id, // object ID
- w: {} // weak collections IDs
- } });
- };
- var fastKey = function fastKey(it, create) {
- // return primitive with prefix
- if (!_isObject(it)) return (typeof it === 'undefined' ? 'undefined' : _typeof(it)) == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
- if (!_has(it, META)) {
- // can't set metadata to uncaught frozen object
- if (!isExtensible(it)) return 'F';
- // not necessary to add metadata
- if (!create) return 'E';
- // add missing metadata
- setMeta(it);
- // return object ID
- }return it[META].i;
- };
- var getWeak = function getWeak(it, create) {
- if (!_has(it, META)) {
- // can't set metadata to uncaught frozen object
- if (!isExtensible(it)) return true;
- // not necessary to add metadata
- if (!create) return false;
- // add missing metadata
- setMeta(it);
- // return hash weak collections IDs
- }return it[META].w;
- };
- // add metadata on freeze-family methods calling
- var onFreeze = function onFreeze(it) {
- if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it);
- return it;
- };
- var meta = module.exports = {
- KEY: META,
- NEED: false,
- fastKey: fastKey,
- getWeak: getWeak,
- onFreeze: onFreeze
- };
- });
-
- var _meta_1 = _meta.KEY;
- var _meta_2 = _meta.NEED;
- var _meta_3 = _meta.fastKey;
- var _meta_4 = _meta.getWeak;
- var _meta_5 = _meta.onFreeze;
-
- var _validateCollection = function _validateCollection(it, TYPE) {
- if (!_isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');
- return it;
- };
-
- var dP$1 = _objectDp.f;
-
- var fastKey = _meta.fastKey;
-
- var SIZE = _descriptors ? '_s' : 'size';
-
- var getEntry = function getEntry(that, key) {
- // fast case
- var index = fastKey(key);
- var entry;
- if (index !== 'F') return that._i[index];
- // frozen object case
- for (entry = that._f; entry; entry = entry.n) {
- if (entry.k == key) return entry;
- }
- };
-
- var _collectionStrong = {
- getConstructor: function getConstructor(wrapper, NAME, IS_MAP, ADDER) {
- var C = wrapper(function (that, iterable) {
- _anInstance(that, C, NAME, '_i');
- that._t = NAME; // collection type
- that._i = _objectCreate(null); // index
- that._f = undefined; // first entry
- that._l = undefined; // last entry
- that[SIZE] = 0; // size
- if (iterable != undefined) _forOf(iterable, IS_MAP, that[ADDER], that);
- });
- _redefineAll(C.prototype, {
- // 23.1.3.1 Map.prototype.clear()
- // 23.2.3.2 Set.prototype.clear()
- clear: function clear() {
- for (var that = _validateCollection(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {
- entry.r = true;
- if (entry.p) entry.p = entry.p.n = undefined;
- delete data[entry.i];
- }
- that._f = that._l = undefined;
- that[SIZE] = 0;
- },
- // 23.1.3.3 Map.prototype.delete(key)
- // 23.2.3.4 Set.prototype.delete(value)
- 'delete': function _delete(key) {
- var that = _validateCollection(this, NAME);
- var entry = getEntry(that, key);
- if (entry) {
- var next = entry.n;
- var prev = entry.p;
- delete that._i[entry.i];
- entry.r = true;
- if (prev) prev.n = next;
- if (next) next.p = prev;
- if (that._f == entry) that._f = next;
- if (that._l == entry) that._l = prev;
- that[SIZE]--;
- }return !!entry;
- },
- // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
- // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
- forEach: function forEach(callbackfn /* , that = undefined */) {
- _validateCollection(this, NAME);
- var f = _ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
- var entry;
- while (entry = entry ? entry.n : this._f) {
- f(entry.v, entry.k, this);
- // revert to the last existing entry
- while (entry && entry.r) {
- entry = entry.p;
- }
- }
- },
- // 23.1.3.7 Map.prototype.has(key)
- // 23.2.3.7 Set.prototype.has(value)
- has: function has(key) {
- return !!getEntry(_validateCollection(this, NAME), key);
- }
- });
- if (_descriptors) dP$1(C.prototype, 'size', {
- get: function get() {
- return _validateCollection(this, NAME)[SIZE];
- }
- });
- return C;
- },
- def: function def(that, key, value) {
- var entry = getEntry(that, key);
- var prev, index;
- // change existing entry
- if (entry) {
- entry.v = value;
- // create new entry
- } else {
- that._l = entry = {
- i: index = fastKey(key, true), // <- index
- k: key, // <- key
- v: value, // <- value
- p: prev = that._l, // <- previous entry
- n: undefined, // <- next entry
- r: false // <- removed
- };
- if (!that._f) that._f = entry;
- if (prev) prev.n = entry;
- that[SIZE]++;
- // add to index
- if (index !== 'F') that._i[index] = entry;
- }return that;
- },
- getEntry: getEntry,
- setStrong: function setStrong(C, NAME, IS_MAP) {
- // add .keys, .values, .entries, [@@iterator]
- // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
- _iterDefine(C, NAME, function (iterated, kind) {
- this._t = _validateCollection(iterated, NAME); // target
- this._k = kind; // kind
- this._l = undefined; // previous
- }, function () {
- var that = this;
- var kind = that._k;
- var entry = that._l;
- // revert to the last existing entry
- while (entry && entry.r) {
- entry = entry.p;
- } // get next entry
- if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {
- // or finish the iteration
- that._t = undefined;
- return _iterStep(1);
- }
- // return step by kind
- if (kind == 'keys') return _iterStep(0, entry.k);
- if (kind == 'values') return _iterStep(0, entry.v);
- return _iterStep(0, [entry.k, entry.v]);
- }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
-
- // add [@@species], 23.1.2.2, 23.2.2.2
- _setSpecies(NAME);
- }
- };
-
- var ITERATOR$4 = _wks('iterator');
- var SAFE_CLOSING = false;
-
- try {
- var riter = [7][ITERATOR$4]();
- riter['return'] = function () {
- SAFE_CLOSING = true;
- };
- // eslint-disable-next-line no-throw-literal
-
- } catch (e) {/* empty */}
-
- var _iterDetect = function _iterDetect(exec, skipClosing) {
- if (!skipClosing && !SAFE_CLOSING) return false;
- var safe = false;
- try {
- var arr = [7];
- var iter = arr[ITERATOR$4]();
- iter.next = function () {
- return { done: safe = true };
- };
- arr[ITERATOR$4] = function () {
- return iter;
- };
- exec(arr);
- } catch (e) {/* empty */}
- return safe;
- };
-
- var setPrototypeOf$2 = _setProto.set;
- var _inheritIfRequired = function _inheritIfRequired(that, target, C) {
- var S = target.constructor;
- var P;
- if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && _isObject(P) && setPrototypeOf$2) {
- setPrototypeOf$2(that, P);
- }return that;
- };
-
- var _collection = function _collection(NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
- var Base = _global[NAME];
- var C = Base;
- var ADDER = IS_MAP ? 'set' : 'add';
- var proto = C && C.prototype;
- var O = {};
- var fixMethod = function fixMethod(KEY) {
- var fn = proto[KEY];
- _redefine(proto, KEY, KEY == 'delete' ? function (a) {
- return IS_WEAK && !_isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
- } : KEY == 'has' ? function has(a) {
- return IS_WEAK && !_isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
- } : KEY == 'get' ? function get(a) {
- return IS_WEAK && !_isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
- } : KEY == 'add' ? function add(a) {
- fn.call(this, a === 0 ? 0 : a);return this;
- } : function set(a, b) {
- fn.call(this, a === 0 ? 0 : a, b);return this;
- });
- };
- if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !_fails(function () {
- new C().entries().next();
- }))) {
- // create collection constructor
- C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
- _redefineAll(C.prototype, methods);
- _meta.NEED = true;
- } else {
- var instance = new C();
- // early implementations not supports chaining
- var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
- // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
- var THROWS_ON_PRIMITIVES = _fails(function () {
- instance.has(1);
- });
- // most early implementations doesn't supports iterables, most modern - not close it correctly
- var ACCEPT_ITERABLES = _iterDetect(function (iter) {
- new C(iter);
- }); // eslint-disable-line no-new
- // for early implementations -0 and +0 not the same
- var BUGGY_ZERO = !IS_WEAK && _fails(function () {
- // V8 ~ Chromium 42- fails only with 5+ elements
- var $instance = new C();
- var index = 5;
- while (index--) {
- $instance[ADDER](index, index);
- }return !$instance.has(-0);
- });
- if (!ACCEPT_ITERABLES) {
- C = wrapper(function (target, iterable) {
- _anInstance(target, C, NAME);
- var that = _inheritIfRequired(new Base(), target, C);
- if (iterable != undefined) _forOf(iterable, IS_MAP, that[ADDER], that);
- return that;
- });
- C.prototype = proto;
- proto.constructor = C;
- }
- if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
- fixMethod('delete');
- fixMethod('has');
- IS_MAP && fixMethod('get');
- }
- if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
- // weak collections should not contains .clear method
- if (IS_WEAK && proto.clear) delete proto.clear;
- }
-
- _setToStringTag(C, NAME);
-
- O[NAME] = C;
- _export(_export.G + _export.W + _export.F * (C != Base), O);
-
- if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);
-
- return C;
- };
-
- var SET = 'Set';
-
- // 23.2 Set Objects
- var es6_set = _collection(SET, function (get) {
- return function Set() {
- return get(this, arguments.length > 0 ? arguments[0] : undefined);
- };
- }, {
- // 23.2.3.1 Set.prototype.add(value)
- add: function add(value) {
- return _collectionStrong.def(_validateCollection(this, SET), value = value === 0 ? 0 : value, value);
- }
- }, _collectionStrong);
-
- var _arrayFromIterable = function _arrayFromIterable(iter, ITERATOR) {
- var result = [];
- _forOf(iter, false, result.push, result, ITERATOR);
- return result;
- };
-
- // https://github.com/DavidBruant/Map-Set.prototype.toJSON
-
-
- var _collectionToJson = function _collectionToJson(NAME) {
- return function toJSON() {
- if (_classof(this) != NAME) throw TypeError(NAME + "#toJSON isn't generic");
- return _arrayFromIterable(this);
- };
- };
-
- // https://github.com/DavidBruant/Map-Set.prototype.toJSON
-
-
- _export(_export.P + _export.R, 'Set', { toJSON: _collectionToJson('Set') });
-
- // https://tc39.github.io/proposal-setmap-offrom/
-
-
- var _setCollectionOf = function _setCollectionOf(COLLECTION) {
- _export(_export.S, COLLECTION, { of: function of() {
- var length = arguments.length;
- var A = Array(length);
- while (length--) {
- A[length] = arguments[length];
- }return new this(A);
- } });
- };
-
- // https://tc39.github.io/proposal-setmap-offrom/#sec-set.of
- _setCollectionOf('Set');
-
- // https://tc39.github.io/proposal-setmap-offrom/
-
-
- var _setCollectionFrom = function _setCollectionFrom(COLLECTION) {
- _export(_export.S, COLLECTION, { from: function from(source /* , mapFn, thisArg */) {
- var mapFn = arguments[1];
- var mapping, A, n, cb;
- _aFunction(this);
- mapping = mapFn !== undefined;
- if (mapping) _aFunction(mapFn);
- if (source == undefined) return new this();
- A = [];
- if (mapping) {
- n = 0;
- cb = _ctx(mapFn, arguments[2], 2);
- _forOf(source, false, function (nextItem) {
- A.push(cb(nextItem, n++));
- });
- } else {
- _forOf(source, false, A.push, A);
- }
- return new this(A);
- } });
- };
-
- // https://tc39.github.io/proposal-setmap-offrom/#sec-set.from
- _setCollectionFrom('Set');
-
- var set$1 = _core.Set;
-
- var MAP = 'Map';
-
- // 23.1 Map Objects
- var es6_map = _collection(MAP, function (get) {
- return function Map() {
- return get(this, arguments.length > 0 ? arguments[0] : undefined);
- };
- }, {
- // 23.1.3.6 Map.prototype.get(key)
- get: function get(key) {
- var entry = _collectionStrong.getEntry(_validateCollection(this, MAP), key);
- return entry && entry.v;
- },
- // 23.1.3.9 Map.prototype.set(key, value)
- set: function set(key, value) {
- return _collectionStrong.def(_validateCollection(this, MAP), key === 0 ? 0 : key, value);
- }
- }, _collectionStrong, true);
-
- // https://github.com/DavidBruant/Map-Set.prototype.toJSON
-
-
- _export(_export.P + _export.R, 'Map', { toJSON: _collectionToJson('Map') });
-
- // https://tc39.github.io/proposal-setmap-offrom/#sec-map.of
- _setCollectionOf('Map');
-
- // https://tc39.github.io/proposal-setmap-offrom/#sec-map.from
- _setCollectionFrom('Map');
-
- var map = _core.Map;
-
- // 7.2.2 IsArray(argument)
-
- var _isArray = Array.isArray || function isArray(arg) {
- return _cof(arg) == 'Array';
- };
-
- var SPECIES$1 = _wks('species');
-
- var _arraySpeciesConstructor = function _arraySpeciesConstructor(original) {
- var C;
- if (_isArray(original)) {
- C = original.constructor;
- // cross-realm fallback
- if (typeof C == 'function' && (C === Array || _isArray(C.prototype))) C = undefined;
- if (_isObject(C)) {
- C = C[SPECIES$1];
- if (C === null) C = undefined;
- }
- }return C === undefined ? Array : C;
- };
-
- // 9.4.2.3 ArraySpeciesCreate(originalArray, length)
-
-
- var _arraySpeciesCreate = function _arraySpeciesCreate(original, length) {
- return new (_arraySpeciesConstructor(original))(length);
- };
-
- // 0 -> Array#forEach
- // 1 -> Array#map
- // 2 -> Array#filter
- // 3 -> Array#some
- // 4 -> Array#every
- // 5 -> Array#find
- // 6 -> Array#findIndex
-
-
- var _arrayMethods = function _arrayMethods(TYPE, $create) {
- var IS_MAP = TYPE == 1;
- var IS_FILTER = TYPE == 2;
- var IS_SOME = TYPE == 3;
- var IS_EVERY = TYPE == 4;
- var IS_FIND_INDEX = TYPE == 6;
- var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
- var create = $create || _arraySpeciesCreate;
- return function ($this, callbackfn, that) {
- var O = _toObject($this);
- var self = _iobject(O);
- var f = _ctx(callbackfn, that, 3);
- var length = _toLength(self.length);
- var index = 0;
- var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
- var val, res;
- for (; length > index; index++) {
- if (NO_HOLES || index in self) {
- val = self[index];
- res = f(val, index, O);
- if (TYPE) {
- if (IS_MAP) result[index] = res; // map
- else if (res) switch (TYPE) {
- case 3:
- return true; // some
- case 5:
- return val; // find
- case 6:
- return index; // findIndex
- case 2:
- result.push(val); // filter
- } else if (IS_EVERY) return false; // every
- }
- }
- }return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
- };
- };
-
- var f$3 = Object.getOwnPropertySymbols;
-
- var _objectGops = {
- f: f$3
- };
-
- // 19.1.2.1 Object.assign(target, source, ...)
-
-
- var $assign = Object.assign;
-
- // should work with symbols and should have deterministic property order (V8 bug)
- var _objectAssign = !$assign || _fails(function () {
- var A = {};
- var B = {};
- // eslint-disable-next-line no-undef
- var S = Symbol();
- var K = 'abcdefghijklmnopqrst';
- A[S] = 7;
- K.split('').forEach(function (k) {
- B[k] = k;
- });
- return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
- }) ? function assign(target, source) {
- // eslint-disable-line no-unused-vars
- var T = _toObject(target);
- var aLen = arguments.length;
- var index = 1;
- var getSymbols = _objectGops.f;
- var isEnum = _objectPie.f;
- while (aLen > index) {
- var S = _iobject(arguments[index++]);
- var keys = getSymbols ? _objectKeys(S).concat(getSymbols(S)) : _objectKeys(S);
- var length = keys.length;
- var j = 0;
- var key;
- while (length > j) {
- if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
- }
- }return T;
- } : $assign;
-
- var getWeak = _meta.getWeak;
-
- var arrayFind = _arrayMethods(5);
- var arrayFindIndex = _arrayMethods(6);
- var id$1 = 0;
-
- // fallback for uncaught frozen keys
- var uncaughtFrozenStore = function uncaughtFrozenStore(that) {
- return that._l || (that._l = new UncaughtFrozenStore());
- };
- var UncaughtFrozenStore = function UncaughtFrozenStore() {
- this.a = [];
- };
- var findUncaughtFrozen = function findUncaughtFrozen(store, key) {
- return arrayFind(store.a, function (it) {
- return it[0] === key;
- });
- };
- UncaughtFrozenStore.prototype = {
- get: function get(key) {
- var entry = findUncaughtFrozen(this, key);
- if (entry) return entry[1];
- },
- has: function has(key) {
- return !!findUncaughtFrozen(this, key);
- },
- set: function set(key, value) {
- var entry = findUncaughtFrozen(this, key);
- if (entry) entry[1] = value;else this.a.push([key, value]);
- },
- 'delete': function _delete(key) {
- var index = arrayFindIndex(this.a, function (it) {
- return it[0] === key;
- });
- if (~index) this.a.splice(index, 1);
- return !!~index;
- }
- };
-
- var _collectionWeak = {
- getConstructor: function getConstructor(wrapper, NAME, IS_MAP, ADDER) {
- var C = wrapper(function (that, iterable) {
- _anInstance(that, C, NAME, '_i');
- that._t = NAME; // collection type
- that._i = id$1++; // collection id
- that._l = undefined; // leak store for uncaught frozen objects
- if (iterable != undefined) _forOf(iterable, IS_MAP, that[ADDER], that);
- });
- _redefineAll(C.prototype, {
- // 23.3.3.2 WeakMap.prototype.delete(key)
- // 23.4.3.3 WeakSet.prototype.delete(value)
- 'delete': function _delete(key) {
- if (!_isObject(key)) return false;
- var data = getWeak(key);
- if (data === true) return uncaughtFrozenStore(_validateCollection(this, NAME))['delete'](key);
- return data && _has(data, this._i) && delete data[this._i];
- },
- // 23.3.3.4 WeakMap.prototype.has(key)
- // 23.4.3.4 WeakSet.prototype.has(value)
- has: function has(key) {
- if (!_isObject(key)) return false;
- var data = getWeak(key);
- if (data === true) return uncaughtFrozenStore(_validateCollection(this, NAME)).has(key);
- return data && _has(data, this._i);
- }
- });
- return C;
- },
- def: function def(that, key, value) {
- var data = getWeak(_anObject(key), true);
- if (data === true) uncaughtFrozenStore(that).set(key, value);else data[that._i] = value;
- return that;
- },
- ufstore: uncaughtFrozenStore
- };
-
- var es6_weakMap = createCommonjsModule(function (module) {
- var each = _arrayMethods(0);
-
- var WEAK_MAP = 'WeakMap';
- var getWeak = _meta.getWeak;
- var isExtensible = Object.isExtensible;
- var uncaughtFrozenStore = _collectionWeak.ufstore;
- var tmp = {};
- var InternalMap;
-
- var wrapper = function wrapper(get) {
- return function WeakMap() {
- return get(this, arguments.length > 0 ? arguments[0] : undefined);
- };
- };
-
- var methods = {
- // 23.3.3.3 WeakMap.prototype.get(key)
- get: function get(key) {
- if (_isObject(key)) {
- var data = getWeak(key);
- if (data === true) return uncaughtFrozenStore(_validateCollection(this, WEAK_MAP)).get(key);
- return data ? data[this._i] : undefined;
- }
- },
- // 23.3.3.5 WeakMap.prototype.set(key, value)
- set: function set(key, value) {
- return _collectionWeak.def(_validateCollection(this, WEAK_MAP), key, value);
- }
- };
-
- // 23.3 WeakMap Objects
- var $WeakMap = module.exports = _collection(WEAK_MAP, wrapper, methods, _collectionWeak, true, true);
-
- // IE11 WeakMap frozen keys fix
- if (_fails(function () {
- return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7;
- })) {
- InternalMap = _collectionWeak.getConstructor(wrapper, WEAK_MAP);
- _objectAssign(InternalMap.prototype, methods);
- _meta.NEED = true;
- each(['delete', 'has', 'get', 'set'], function (key) {
- var proto = $WeakMap.prototype;
- var method = proto[key];
- _redefine(proto, key, function (a, b) {
- // store frozen objects on internal weakmap shim
- if (_isObject(a) && !isExtensible(a)) {
- if (!this._f) this._f = new InternalMap();
- var result = this._f[key](a, b);
- return key == 'set' ? this : result;
- // store all the rest on native weakmap
- }return method.call(this, a, b);
- });
- });
- }
- });
-
- // https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.of
- _setCollectionOf('WeakMap');
-
- // https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.from
- _setCollectionFrom('WeakMap');
-
- var weakMap = _core.WeakMap;
-
- var _createProperty = function _createProperty(object, index, value) {
- if (index in object) _objectDp.f(object, index, _propertyDesc(0, value));else object[index] = value;
- };
-
- _export(_export.S + _export.F * !_iterDetect(function (iter) {
-
- }), 'Array', {
- // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
- from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
- var O = _toObject(arrayLike);
- var C = typeof this == 'function' ? this : Array;
- var aLen = arguments.length;
- var mapfn = aLen > 1 ? arguments[1] : undefined;
- var mapping = mapfn !== undefined;
- var index = 0;
- var iterFn = core_getIteratorMethod(O);
- var length, result, step, iterator;
- if (mapping) mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
- // if object isn't iterable or it's array with default iterator - use simple case
- if (iterFn != undefined && !(C == Array && _isArrayIter(iterFn))) {
- for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
- _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value);
- }
- } else {
- length = _toLength(O.length);
- for (result = new C(length); length > index; index++) {
- _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
- }
- }
- result.length = index;
- return result;
- }
- });
-
- var from$1 = _core.Array.from;
-
- var reservedTagList = new Set(['annotation-xml', 'color-profile', 'font-face', 'font-face-src', 'font-face-uri', 'font-face-format', 'font-face-name', 'missing-glyph']);
-
- /**
- * @param {string} localName
- * @returns {boolean}
- */
- function isValidCustomElementName(localName) {
- var reserved = reservedTagList.has(localName);
- var validForm = /^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(localName);
- return !reserved && validForm;
- }
-
- /**
- * @private
- * @param {!Node} node
- * @return {boolean}
- */
- function isConnected(node) {
- // Use `Node#isConnected`, if defined.
- var nativeValue = node.isConnected;
- if (nativeValue !== undefined) {
- return nativeValue;
- }
-
- /** @type {?Node|undefined} */
- var current = node;
- while (current && !(current.__CE_isImportDocument || current instanceof Document)) {
- current = current.parentNode || (window.ShadowRoot && current instanceof ShadowRoot ? current.host : undefined);
- }
- return !!(current && (current.__CE_isImportDocument || current instanceof Document));
- }
-
- /**
- * @param {!Node} root
- * @param {!Node} start
- * @return {?Node}
- */
- function nextSiblingOrAncestorSibling(root, start) {
- var node = start;
- while (node && node !== root && !node.nextSibling) {
- node = node.parentNode;
- }
- return !node || node === root ? null : node.nextSibling;
- }
-
- /**
- * @param {!Node} root
- * @param {!Node} start
- * @return {?Node}
- */
- function nextNode(root, start) {
- return start.firstChild ? start.firstChild : nextSiblingOrAncestorSibling(root, start);
- }
-
- /**
- * @param {!Node} root
- * @param {!function(!Element)} callback
- * @param {!Set<Node>=} visitedImports
- */
- function walkDeepDescendantElements(root, callback) {
- var visitedImports = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : new Set();
-
- var node = root;
- while (node) {
- if (node.nodeType === Node.ELEMENT_NODE) {
- var element = /** @type {!Element} */node;
-
- callback(element);
-
- var localName = element.localName;
- if (localName === 'link' && element.getAttribute('rel') === 'import') {
- // If this import (polyfilled or not) has it's root node available,
- // walk it.
- var importNode = /** @type {!Node} */element.import;
- if (importNode instanceof Node && !visitedImports.has(importNode)) {
- // Prevent multiple walks of the same import root.
- visitedImports.add(importNode);
-
- for (var child = importNode.firstChild; child; child = child.nextSibling) {
- walkDeepDescendantElements(child, callback, visitedImports);
- }
- }
-
- // Ignore descendants of import links to prevent attempting to walk the
- // elements created by the HTML Imports polyfill that we just walked
- // above.
- node = nextSiblingOrAncestorSibling(root, element);
- continue;
- } else if (localName === 'template') {
- // Ignore descendants of templates. There shouldn't be any descendants
- // because they will be moved into `.content` during construction in
- // browsers that support template but, in case they exist and are still
- // waiting to be moved by a polyfill, they will be ignored.
- node = nextSiblingOrAncestorSibling(root, element);
- continue;
- }
-
- // Walk shadow roots.
- var shadowRoot = element.__CE_shadowRoot;
- if (shadowRoot) {
- for (var _child = shadowRoot.firstChild; _child; _child = _child.nextSibling) {
- walkDeepDescendantElements(_child, callback, visitedImports);
- }
- }
- }
-
- node = nextNode(root, node);
- }
- }
-
- /**
- * Used to suppress Closure's "Modifying the prototype is only allowed if the
- * constructor is in the same scope" warning without using
- * `@suppress {newCheckTypes, duplicate}` because `newCheckTypes` is too broad.
- *
- * @param {!Object} destination
- * @param {string} name
- * @param {*} value
- */
- function setPropertyUnchecked(destination, name, value) {
- destination[name] = value;
- }
-
- /**
- * @enum {number}
- */
- var CustomElementState = {
- custom: 1,
- failed: 2
- };
-
- var CustomElementInternals = function () {
- function CustomElementInternals() {
- classCallCheck(this, CustomElementInternals);
-
- /** @type {!Map<string, !CustomElementDefinition>} */
- this._localNameToDefinition = new Map();
-
- /** @type {!Map<!Function, !CustomElementDefinition>} */
- this._constructorToDefinition = new Map();
-
- /** @type {!Array<!function(!Node)>} */
- this._patches = [];
-
- /** @type {boolean} */
- this._hasPatches = false;
- }
-
- /**
- * @param {string} localName
- * @param {!CustomElementDefinition} definition
- */
-
-
- createClass(CustomElementInternals, [{
- key: 'setDefinition',
- value: function setDefinition(localName, definition) {
- this._localNameToDefinition.set(localName, definition);
- this._constructorToDefinition.set(definition.constructor, definition);
- }
-
- /**
- * @param {string} localName
- * @return {!CustomElementDefinition|undefined}
- */
-
- }, {
- key: 'localNameToDefinition',
- value: function localNameToDefinition(localName) {
- return this._localNameToDefinition.get(localName);
- }
-
- /**
- * @param {!Function} constructor
- * @return {!CustomElementDefinition|undefined}
- */
-
- }, {
- key: 'constructorToDefinition',
- value: function constructorToDefinition(constructor) {
- return this._constructorToDefinition.get(constructor);
- }
-
- /**
- * @param {!function(!Node)} listener
- */
-
- }, {
- key: 'addPatch',
- value: function addPatch(listener) {
- this._hasPatches = true;
- this._patches.push(listener);
- }
-
- /**
- * @param {!Node} node
- */
-
- }, {
- key: 'patchTree',
- value: function patchTree(node) {
- var _this = this;
-
- if (!this._hasPatches) return;
-
- walkDeepDescendantElements(node, function (element) {
- return _this.patch(element);
- });
- }
-
- /**
- * @param {!Node} node
- */
-
- }, {
- key: 'patch',
- value: function patch(node) {
- if (!this._hasPatches) return;
-
- if (node.__CE_patched) return;
- node.__CE_patched = true;
-
- for (var i = 0; i < this._patches.length; i++) {
- this._patches[i](node);
- }
- }
-
- /**
- * @param {!Node} root
- */
-
- }, {
- key: 'connectTree',
- value: function connectTree(root) {
- var elements = [];
-
- walkDeepDescendantElements(root, function (element) {
- return elements.push(element);
- });
-
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- if (element.__CE_state === CustomElementState.custom) {
- if (isConnected(element)) {
- this.connectedCallback(element);
- }
- } else {
- this.upgradeElement(element);
- }
- }
- }
-
- /**
- * @param {!Node} root
- */
-
- }, {
- key: 'disconnectTree',
- value: function disconnectTree(root) {
- var elements = [];
-
- walkDeepDescendantElements(root, function (element) {
- return elements.push(element);
- });
-
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- if (element.__CE_state === CustomElementState.custom) {
- this.disconnectedCallback(element);
- }
- }
- }
-
- /**
- * Upgrades all uncustomized custom elements at and below a root node for
- * which there is a definition. When custom element reaction callbacks are
- * assumed to be called synchronously (which, by the current DOM / HTML spec
- * definitions, they are *not*), callbacks for both elements customized
- * synchronously by the parser and elements being upgraded occur in the same
- * relative order.
- *
- * NOTE: This function, when used to simulate the construction of a tree that
- * is already created but not customized (i.e. by the parser), does *not*
- * prevent the element from reading the 'final' (true) state of the tree. For
- * example, the element, during truly synchronous parsing / construction would
- * see that it contains no children as they have not yet been inserted.
- * However, this function does not modify the tree, the element will
- * (incorrectly) have children. Additionally, self-modification restrictions
- * for custom element constructors imposed by the DOM spec are *not* enforced.
- *
- *
- * The following nested list shows the steps extending down from the HTML
- * spec's parsing section that cause elements to be synchronously created and
- * upgraded:
- *
- * The "in body" insertion mode:
- * https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
- * - Switch on token:
- * .. other cases ..
- * -> Any other start tag
- * - [Insert an HTML element](below) for the token.
- *
- * Insert an HTML element:
- * https://html.spec.whatwg.org/multipage/syntax.html#insert-an-html-element
- * - Insert a foreign element for the token in the HTML namespace:
- * https://html.spec.whatwg.org/multipage/syntax.html#insert-a-foreign-element
- * - Create an element for a token:
- * https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
- * - Will execute script flag is true?
- * - (Element queue pushed to the custom element reactions stack.)
- * - Create an element:
- * https://dom.spec.whatwg.org/#concept-create-element
- * - Sync CE flag is true?
- * - Constructor called.
- * - Self-modification restrictions enforced.
- * - Sync CE flag is false?
- * - (Upgrade reaction enqueued.)
- * - Attributes appended to element.
- * (`attributeChangedCallback` reactions enqueued.)
- * - Will execute script flag is true?
- * - (Element queue popped from the custom element reactions stack.
- * Reactions in the popped stack are invoked.)
- * - (Element queue pushed to the custom element reactions stack.)
- * - Insert the element:
- * https://dom.spec.whatwg.org/#concept-node-insert
- * - Shadow-including descendants are connected. During parsing
- * construction, there are no shadow-*excluding* descendants.
- * However, the constructor may have validly attached a shadow
- * tree to itself and added descendants to that shadow tree.
- * (`connectedCallback` reactions enqueued.)
- * - (Element queue popped from the custom element reactions stack.
- * Reactions in the popped stack are invoked.)
- *
- * @param {!Node} root
- * @param {!Set<Node>=} visitedImports
- */
-
- }, {
- key: 'patchAndUpgradeTree',
- value: function patchAndUpgradeTree(root) {
- var _this2 = this;
-
- var visitedImports = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
-
- var elements = [];
-
- var gatherElements = function gatherElements(element) {
- if (element.localName === 'link' && element.getAttribute('rel') === 'import') {
- // The HTML Imports polyfill sets a descendant element of the link to
- // the `import` property, specifically this is *not* a Document.
- var importNode = /** @type {?Node} */element.import;
-
- if (importNode instanceof Node && importNode.readyState === 'complete') {
- importNode.__CE_isImportDocument = true;
-
- // Connected links are associated with the registry.
- importNode.__CE_hasRegistry = true;
- } else {
- // If this link's import root is not available, its contents can't be
- // walked. Wait for 'load' and walk it when it's ready.
- element.addEventListener('load', function () {
- var importNode = /** @type {!Node} */element.import;
-
- if (importNode.__CE_documentLoadHandled) return;
- importNode.__CE_documentLoadHandled = true;
-
- importNode.__CE_isImportDocument = true;
-
- // Connected links are associated with the registry.
- importNode.__CE_hasRegistry = true;
-
- // Clone the `visitedImports` set that was populated sync during
- // the `patchAndUpgradeTree` call that caused this 'load' handler to
- // be added. Then, remove *this* link's import node so that we can
- // walk that import again, even if it was partially walked later
- // during the same `patchAndUpgradeTree` call.
- visitedImports.delete(importNode);
-
- _this2.patchAndUpgradeTree(importNode, visitedImports);
- });
- }
- } else {
- elements.push(element);
- }
- };
-
- // `walkDeepDescendantElements` populates (and internally checks against)
- // `visitedImports` when traversing a loaded import.
- walkDeepDescendantElements(root, gatherElements, visitedImports);
-
- if (this._hasPatches) {
- for (var i = 0; i < elements.length; i++) {
- this.patch(elements[i]);
- }
- }
-
- for (var _i = 0; _i < elements.length; _i++) {
- this.upgradeElement(elements[_i]);
- }
- }
-
- /**
- * @param {!Element} element
- */
-
- }, {
- key: 'upgradeElement',
- value: function upgradeElement(element) {
- var currentState = element.__CE_state;
- if (currentState !== undefined) return;
-
- var definition = this.localNameToDefinition(element.localName);
- if (!definition) return;
-
- definition.constructionStack.push(element);
-
- var constructor = definition.constructor;
- try {
- try {
- var result = new constructor();
- if (result !== element) {
- throw new Error('The custom element constructor did not produce the element being upgraded.');
- }
- } finally {
- definition.constructionStack.pop();
- }
- } catch (e) {
- element.__CE_state = CustomElementState.failed;
- throw e;
- }
-
- element.__CE_state = CustomElementState.custom;
- element.__CE_definition = definition;
-
- if (definition.attributeChangedCallback) {
- var observedAttributes = definition.observedAttributes;
- for (var i = 0; i < observedAttributes.length; i++) {
- var name = observedAttributes[i];
- var value = element.getAttribute(name);
- if (value !== null) {
- this.attributeChangedCallback(element, name, null, value, null);
- }
- }
- }
-
- if (isConnected(element)) {
- this.connectedCallback(element);
- }
- }
-
- /**
- * @param {!Element} element
- */
-
- }, {
- key: 'connectedCallback',
- value: function connectedCallback(element) {
- var definition = element.__CE_definition;
- if (definition.connectedCallback) {
- definition.connectedCallback.call(element);
- }
-
- element.__CE_isConnectedCallbackCalled = true;
- }
-
- /**
- * @param {!Element} element
- */
-
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback(element) {
- if (!element.__CE_isConnectedCallbackCalled) {
- this.connectedCallback(element);
- }
-
- var definition = element.__CE_definition;
- if (definition.disconnectedCallback) {
- definition.disconnectedCallback.call(element);
- }
-
- element.__CE_isConnectedCallbackCalled = undefined;
- }
-
- /**
- * @param {!Element} element
- * @param {string} name
- * @param {?string} oldValue
- * @param {?string} newValue
- * @param {?string} namespace
- */
-
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(element, name, oldValue, newValue, namespace) {
- var definition = element.__CE_definition;
- if (definition.attributeChangedCallback && definition.observedAttributes.indexOf(name) > -1) {
- definition.attributeChangedCallback.call(element, name, oldValue, newValue, namespace);
- }
- }
- }]);
- return CustomElementInternals;
- }();
-
- var DocumentConstructionObserver = function () {
- function DocumentConstructionObserver(internals, doc) {
- classCallCheck(this, DocumentConstructionObserver);
-
- /**
- * @type {!CustomElementInternals}
- */
- this._internals = internals;
-
- /**
- * @type {!Document}
- */
- this._document = doc;
-
- /**
- * @type {MutationObserver|undefined}
- */
- this._observer = undefined;
-
- // Simulate tree construction for all currently accessible nodes in the
- // document.
- this._internals.patchAndUpgradeTree(this._document);
-
- if (this._document.readyState === 'loading') {
- this._observer = new MutationObserver(this._handleMutations.bind(this));
-
- // Nodes created by the parser are given to the observer *before* the next
- // task runs. Inline scripts are run in a new task. This means that the
- // observer will be able to handle the newly parsed nodes before the inline
- // script is run.
- this._observer.observe(this._document, {
- childList: true,
- subtree: true
- });
- }
- }
-
- createClass(DocumentConstructionObserver, [{
- key: 'disconnect',
- value: function disconnect() {
- if (this._observer) {
- this._observer.disconnect();
- }
- }
-
- /**
- * @param {!Array<!MutationRecord>} mutations
- */
-
- }, {
- key: '_handleMutations',
- value: function _handleMutations(mutations) {
- // Once the document's `readyState` is 'interactive' or 'complete', all new
- // nodes created within that document will be the result of script and
- // should be handled by patching.
- var readyState = this._document.readyState;
- if (readyState === 'interactive' || readyState === 'complete') {
- this.disconnect();
- }
-
- for (var i = 0; i < mutations.length; i++) {
- var addedNodes = mutations[i].addedNodes;
- for (var j = 0; j < addedNodes.length; j++) {
- var node = addedNodes[j];
- this._internals.patchAndUpgradeTree(node);
- }
- }
- }
- }]);
- return DocumentConstructionObserver;
- }();
-
- /**
- * @template T
- */
- var Deferred = function () {
- function Deferred() {
- var _this = this;
-
- classCallCheck(this, Deferred);
-
- /**
- * @private
- * @type {T|undefined}
- */
- this._value = undefined;
-
- /**
- * @private
- * @type {Function|undefined}
- */
- this._resolve = undefined;
-
- /**
- * @private
- * @type {!Promise<T>}
- */
- this._promise = new Promise(function (resolve) {
- _this._resolve = resolve;
-
- if (_this._value) {
- resolve(_this._value);
- }
- });
- }
-
- /**
- * @param {T} value
- */
-
-
- createClass(Deferred, [{
- key: 'resolve',
- value: function resolve(value) {
- if (this._value) {
- throw new Error('Already resolved.');
- }
-
- this._value = value;
-
- if (this._resolve) {
- this._resolve(value);
- }
- }
-
- /**
- * @return {!Promise<T>}
- */
-
- }, {
- key: 'toPromise',
- value: function toPromise() {
- return this._promise;
- }
- }]);
- return Deferred;
- }();
-
- /**
- * @unrestricted
- */
-
- var CustomElementRegistry = function () {
-
- /**
- * @param {!CustomElementInternals} internals
- */
- function CustomElementRegistry(internals) {
- classCallCheck(this, CustomElementRegistry);
-
- /**
- * @private
- * @type {boolean}
- */
- this._elementDefinitionIsRunning = false;
-
- /**
- * @private
- * @type {!CustomElementInternals}
- */
- this._internals = internals;
-
- /**
- * @private
- * @type {!Map<string, !Deferred<undefined>>}
- */
- this._whenDefinedDeferred = new Map();
-
- /**
- * The default flush callback triggers the document walk synchronously.
- * @private
- * @type {!Function}
- */
- this._flushCallback = function (fn) {
- return fn();
- };
-
- /**
- * @private
- * @type {boolean}
- */
- this._flushPending = false;
-
- /**
- * @private
- * @type {!Array<string>}
- */
- this._unflushedLocalNames = [];
-
- /**
- * @private
- * @type {!DocumentConstructionObserver}
- */
- this._documentConstructionObserver = new DocumentConstructionObserver(internals, document);
- }
-
- /**
- * @param {string} localName
- * @param {!Function} constructor
- */
-
-
- createClass(CustomElementRegistry, [{
- key: 'define',
- value: function define(localName, constructor) {
- var _this = this;
-
- if (!(constructor instanceof Function)) {
- throw new TypeError('Custom element constructors must be functions.');
- }
-
- if (!isValidCustomElementName(localName)) {
- throw new SyntaxError('The element name \'' + localName + '\' is not valid.');
- }
-
- if (this._internals.localNameToDefinition(localName)) {
- throw new Error('A custom element with name \'' + localName + '\' has already been defined.');
- }
-
- if (this._elementDefinitionIsRunning) {
- throw new Error('A custom element is already being defined.');
- }
- this._elementDefinitionIsRunning = true;
-
- var connectedCallback = void 0;
- var disconnectedCallback = void 0;
- var adoptedCallback = void 0;
- var attributeChangedCallback = void 0;
- var observedAttributes = void 0;
- try {
- var getCallback = function getCallback(name) {
- var callbackValue = prototype[name];
- if (callbackValue !== undefined && !(callbackValue instanceof Function)) {
- throw new Error('The \'' + name + '\' callback must be a function.');
- }
- return callbackValue;
- };
-
- /** @type {!Object} */
- var prototype = constructor.prototype;
- if (!(prototype instanceof Object)) {
- throw new TypeError('The custom element constructor\'s prototype is not an object.');
- }
-
- connectedCallback = getCallback('connectedCallback');
- disconnectedCallback = getCallback('disconnectedCallback');
- adoptedCallback = getCallback('adoptedCallback');
- attributeChangedCallback = getCallback('attributeChangedCallback');
- observedAttributes = constructor['observedAttributes'] || [];
- } catch (e) {
- return;
- } finally {
- this._elementDefinitionIsRunning = false;
- }
-
- var definition = {
- localName: localName,
- constructor: constructor,
- connectedCallback: connectedCallback,
- disconnectedCallback: disconnectedCallback,
- adoptedCallback: adoptedCallback,
- attributeChangedCallback: attributeChangedCallback,
- observedAttributes: observedAttributes,
- constructionStack: []
- };
-
- this._internals.setDefinition(localName, definition);
-
- this._unflushedLocalNames.push(localName);
-
- // If we've already called the flush callback and it hasn't called back yet,
- // don't call it again.
- if (!this._flushPending) {
- this._flushPending = true;
- this._flushCallback(function () {
- return _this._flush();
- });
- }
- }
- }, {
- key: '_flush',
- value: function _flush() {
- // If no new definitions were defined, don't attempt to flush. This could
- // happen if a flush callback keeps the function it is given and calls it
- // multiple times.
- if (this._flushPending === false) return;
-
- this._flushPending = false;
- this._internals.patchAndUpgradeTree(document);
-
- while (this._unflushedLocalNames.length > 0) {
- var localName = this._unflushedLocalNames.shift();
- var deferred = this._whenDefinedDeferred.get(localName);
- if (deferred) {
- deferred.resolve(undefined);
- }
- }
- }
-
- /**
- * @param {string} localName
- * @return {Function|undefined}
- */
-
- }, {
- key: 'get',
- value: function get$$1(localName) {
- var definition = this._internals.localNameToDefinition(localName);
- if (definition) {
- return definition.constructor;
- }
-
- return undefined;
- }
-
- /**
- * @param {string} localName
- * @return {!Promise<undefined>}
- */
-
- }, {
- key: 'whenDefined',
- value: function whenDefined(localName) {
- if (!isValidCustomElementName(localName)) {
- return Promise.reject(new SyntaxError('\'' + localName + '\' is not a valid custom element name.'));
- }
-
- var prior = this._whenDefinedDeferred.get(localName);
- if (prior) {
- return prior.toPromise();
- }
-
- var deferred = new Deferred();
- this._whenDefinedDeferred.set(localName, deferred);
-
- var definition = this._internals.localNameToDefinition(localName);
- // Resolve immediately only if the given local name has a definition *and*
- // the full document walk to upgrade elements with that local name has
- // already happened.
- if (definition && this._unflushedLocalNames.indexOf(localName) === -1) {
- deferred.resolve(undefined);
- }
-
- return deferred.toPromise();
- }
- }, {
- key: 'polyfillWrapFlushCallback',
- value: function polyfillWrapFlushCallback(outer) {
- this._documentConstructionObserver.disconnect();
- var inner = this._flushCallback;
- this._flushCallback = function (flush) {
- return outer(function () {
- return inner(flush);
- });
- };
- }
- }]);
- return CustomElementRegistry;
- }();
-
- window['CustomElementRegistry'] = CustomElementRegistry;
- CustomElementRegistry.prototype['define'] = CustomElementRegistry.prototype.define;
- CustomElementRegistry.prototype['get'] = CustomElementRegistry.prototype.get;
- CustomElementRegistry.prototype['whenDefined'] = CustomElementRegistry.prototype.whenDefined;
- CustomElementRegistry.prototype['polyfillWrapFlushCallback'] = CustomElementRegistry.prototype.polyfillWrapFlushCallback;
-
- var Native = {
- Document_createElement: window.Document.prototype.createElement,
- Document_createElementNS: window.Document.prototype.createElementNS,
- Document_importNode: window.Document.prototype.importNode,
- Document_prepend: window.Document.prototype['prepend'],
- Document_append: window.Document.prototype['append'],
- Node_cloneNode: window.Node.prototype.cloneNode,
- Node_appendChild: window.Node.prototype.appendChild,
- Node_insertBefore: window.Node.prototype.insertBefore,
- Node_removeChild: window.Node.prototype.removeChild,
- Node_replaceChild: window.Node.prototype.replaceChild,
- Node_textContent: Object.getOwnPropertyDescriptor(window.Node.prototype, 'textContent'),
- Element_attachShadow: window.Element.prototype['attachShadow'],
- Element_innerHTML: Object.getOwnPropertyDescriptor(window.Element.prototype, 'innerHTML'),
- Element_getAttribute: window.Element.prototype.getAttribute,
- Element_setAttribute: window.Element.prototype.setAttribute,
- Element_removeAttribute: window.Element.prototype.removeAttribute,
- Element_getAttributeNS: window.Element.prototype.getAttributeNS,
- Element_setAttributeNS: window.Element.prototype.setAttributeNS,
- Element_removeAttributeNS: window.Element.prototype.removeAttributeNS,
- Element_insertAdjacentElement: window.Element.prototype['insertAdjacentElement'],
- Element_prepend: window.Element.prototype['prepend'],
- Element_append: window.Element.prototype['append'],
- Element_before: window.Element.prototype['before'],
- Element_after: window.Element.prototype['after'],
- Element_replaceWith: window.Element.prototype['replaceWith'],
- Element_remove: window.Element.prototype['remove'],
- HTMLElement: window.HTMLElement,
- HTMLElement_innerHTML: Object.getOwnPropertyDescriptor(window.HTMLElement.prototype, 'innerHTML'),
- HTMLElement_insertAdjacentElement: window.HTMLElement.prototype['insertAdjacentElement']
- };
-
- /**
- * This class exists only to work around Closure's lack of a way to describe
- * singletons. It represents the 'already constructed marker' used in custom
- * element construction stacks.
- *
- * https://html.spec.whatwg.org/#concept-already-constructed-marker
- */
- var AlreadyConstructedMarker = function AlreadyConstructedMarker() {
- classCallCheck(this, AlreadyConstructedMarker);
- };
-
- var AlreadyConstructedMarker$1 = new AlreadyConstructedMarker();
-
- /**
- * @param {!CustomElementInternals} internals
- */
- var PatchHTMLElement = function (internals) {
- window['HTMLElement'] = function () {
- /**
- * @type {function(new: HTMLElement): !HTMLElement}
- */
- function HTMLElement() {
- // This should really be `new.target` but `new.target` can't be emulated
- // in ES5. Assuming the user keeps the default value of the constructor's
- // prototype's `constructor` property, this is equivalent.
- /** @type {!Function} */
- var constructor = this.constructor;
-
- var definition = internals.constructorToDefinition(constructor);
- if (!definition) {
- throw new Error('The custom element being constructed was not registered with `customElements`.');
- }
-
- var constructionStack = definition.constructionStack;
-
- if (constructionStack.length === 0) {
- var _element = Native.Document_createElement.call(document, definition.localName);
- Object.setPrototypeOf(_element, constructor.prototype);
- _element.__CE_state = CustomElementState.custom;
- _element.__CE_definition = definition;
- internals.patch(_element);
- return _element;
- }
-
- var lastIndex = constructionStack.length - 1;
- var element = constructionStack[lastIndex];
- if (element === AlreadyConstructedMarker$1) {
- throw new Error('The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.');
- }
- constructionStack[lastIndex] = AlreadyConstructedMarker$1;
-
- Object.setPrototypeOf(element, constructor.prototype);
- internals.patch( /** @type {!HTMLElement} */element);
-
- return element;
- }
-
- HTMLElement.prototype = Native.HTMLElement.prototype;
-
- return HTMLElement;
- }();
- };
-
- /**
- * @param {!CustomElementInternals} internals
- * @param {!Object} destination
- * @param {!ParentNodeNativeMethods} builtIn
- */
- var PatchParentNode = function (internals, destination, builtIn) {
- /**
- * @param {...(!Node|string)} nodes
- */
- destination['prepend'] = function () {
- for (var _len = arguments.length, nodes = Array(_len), _key = 0; _key < _len; _key++) {
- nodes[_key] = arguments[_key];
- }
-
- // TODO: Fix this for when one of `nodes` is a DocumentFragment!
- var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
- // DocumentFragments are not connected and will not be added to the list.
- return node instanceof Node && isConnected(node);
- });
-
- builtIn.prepend.apply(this, nodes);
-
- for (var i = 0; i < connectedBefore.length; i++) {
- internals.disconnectTree(connectedBefore[i]);
- }
-
- if (isConnected(this)) {
- for (var _i = 0; _i < nodes.length; _i++) {
- var node = nodes[_i];
- if (node instanceof Element) {
- internals.connectTree(node);
- }
- }
- }
- };
-
- /**
- * @param {...(!Node|string)} nodes
- */
- destination['append'] = function () {
- for (var _len2 = arguments.length, nodes = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- nodes[_key2] = arguments[_key2];
- }
-
- // TODO: Fix this for when one of `nodes` is a DocumentFragment!
- var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
- // DocumentFragments are not connected and will not be added to the list.
- return node instanceof Node && isConnected(node);
- });
-
- builtIn.append.apply(this, nodes);
-
- for (var i = 0; i < connectedBefore.length; i++) {
- internals.disconnectTree(connectedBefore[i]);
- }
-
- if (isConnected(this)) {
- for (var _i2 = 0; _i2 < nodes.length; _i2++) {
- var node = nodes[_i2];
- if (node instanceof Element) {
- internals.connectTree(node);
- }
- }
- }
- };
- };
-
- /**
- * @param {!CustomElementInternals} internals
- */
- var PatchDocument = function (internals) {
- setPropertyUnchecked(Document.prototype, 'createElement',
- /**
- * @this {Document}
- * @param {string} localName
- * @return {!Element}
- */
- function (localName) {
- // Only create custom elements if this document is associated with the registry.
- if (this.__CE_hasRegistry) {
- var definition = internals.localNameToDefinition(localName);
- if (definition) {
- return new definition.constructor();
- }
- }
-
- var result = /** @type {!Element} */
- Native.Document_createElement.call(this, localName);
- internals.patch(result);
- return result;
- });
-
- setPropertyUnchecked(Document.prototype, 'importNode',
- /**
- * @this {Document}
- * @param {!Node} node
- * @param {boolean=} deep
- * @return {!Node}
- */
- function (node, deep) {
- var clone = Native.Document_importNode.call(this, node, deep);
- // Only create custom elements if this document is associated with the registry.
- if (!this.__CE_hasRegistry) {
- internals.patchTree(clone);
- } else {
- internals.patchAndUpgradeTree(clone);
- }
- return clone;
- });
-
- var NS_HTML = "http://www.w3.org/1999/xhtml";
-
- setPropertyUnchecked(Document.prototype, 'createElementNS',
- /**
- * @this {Document}
- * @param {?string} namespace
- * @param {string} localName
- * @return {!Element}
- */
- function (namespace, localName) {
- // Only create custom elements if this document is associated with the registry.
- if (this.__CE_hasRegistry && (namespace === null || namespace === NS_HTML)) {
- var definition = internals.localNameToDefinition(localName);
- if (definition) {
- return new definition.constructor();
- }
- }
-
- var result = /** @type {!Element} */
- Native.Document_createElementNS.call(this, namespace, localName);
- internals.patch(result);
- return result;
- });
-
- PatchParentNode(internals, Document.prototype, {
- prepend: Native.Document_prepend,
- append: Native.Document_append
- });
- };
-
- /**
- * @param {!CustomElementInternals} internals
- */
- var PatchNode = function (internals) {
- // `Node#nodeValue` is implemented on `Attr`.
- // `Node#textContent` is implemented on `Attr`, `Element`.
-
- setPropertyUnchecked(Node.prototype, 'insertBefore',
- /**
- * @this {Node}
- * @param {!Node} node
- * @param {?Node} refNode
- * @return {!Node}
- */
- function (node, refNode) {
- if (node instanceof DocumentFragment) {
- var insertedNodes = Array.prototype.slice.apply(node.childNodes);
- var _nativeResult = Native.Node_insertBefore.call(this, node, refNode);
-
- // DocumentFragments can't be connected, so `disconnectTree` will never
- // need to be called on a DocumentFragment's children after inserting it.
-
- if (isConnected(this)) {
- for (var i = 0; i < insertedNodes.length; i++) {
- internals.connectTree(insertedNodes[i]);
- }
- }
-
- return _nativeResult;
- }
-
- var nodeWasConnected = isConnected(node);
- var nativeResult = Native.Node_insertBefore.call(this, node, refNode);
-
- if (nodeWasConnected) {
- internals.disconnectTree(node);
- }
-
- if (isConnected(this)) {
- internals.connectTree(node);
- }
-
- return nativeResult;
- });
-
- setPropertyUnchecked(Node.prototype, 'appendChild',
- /**
- * @this {Node}
- * @param {!Node} node
- * @return {!Node}
- */
- function (node) {
- if (node instanceof DocumentFragment) {
- var insertedNodes = Array.prototype.slice.apply(node.childNodes);
- var _nativeResult2 = Native.Node_appendChild.call(this, node);
-
- // DocumentFragments can't be connected, so `disconnectTree` will never
- // need to be called on a DocumentFragment's children after inserting it.
-
- if (isConnected(this)) {
- for (var i = 0; i < insertedNodes.length; i++) {
- internals.connectTree(insertedNodes[i]);
- }
- }
-
- return _nativeResult2;
- }
-
- var nodeWasConnected = isConnected(node);
- var nativeResult = Native.Node_appendChild.call(this, node);
-
- if (nodeWasConnected) {
- internals.disconnectTree(node);
- }
-
- if (isConnected(this)) {
- internals.connectTree(node);
- }
-
- return nativeResult;
- });
-
- setPropertyUnchecked(Node.prototype, 'cloneNode',
- /**
- * @this {Node}
- * @param {boolean=} deep
- * @return {!Node}
- */
- function (deep) {
- var clone = Native.Node_cloneNode.call(this, deep);
- // Only create custom elements if this element's owner document is
- // associated with the registry.
- if (!this.ownerDocument.__CE_hasRegistry) {
- internals.patchTree(clone);
- } else {
- internals.patchAndUpgradeTree(clone);
- }
- return clone;
- });
-
- setPropertyUnchecked(Node.prototype, 'removeChild',
- /**
- * @this {Node}
- * @param {!Node} node
- * @return {!Node}
- */
- function (node) {
- var nodeWasConnected = isConnected(node);
- var nativeResult = Native.Node_removeChild.call(this, node);
-
- if (nodeWasConnected) {
- internals.disconnectTree(node);
- }
-
- return nativeResult;
- });
-
- setPropertyUnchecked(Node.prototype, 'replaceChild',
- /**
- * @this {Node}
- * @param {!Node} nodeToInsert
- * @param {!Node} nodeToRemove
- * @return {!Node}
- */
- function (nodeToInsert, nodeToRemove) {
- if (nodeToInsert instanceof DocumentFragment) {
- var insertedNodes = Array.prototype.slice.apply(nodeToInsert.childNodes);
- var _nativeResult3 = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);
-
- // DocumentFragments can't be connected, so `disconnectTree` will never
- // need to be called on a DocumentFragment's children after inserting it.
-
- if (isConnected(this)) {
- internals.disconnectTree(nodeToRemove);
- for (var i = 0; i < insertedNodes.length; i++) {
- internals.connectTree(insertedNodes[i]);
- }
- }
-
- return _nativeResult3;
- }
-
- var nodeToInsertWasConnected = isConnected(nodeToInsert);
- var nativeResult = Native.Node_replaceChild.call(this, nodeToInsert, nodeToRemove);
- var thisIsConnected = isConnected(this);
-
- if (thisIsConnected) {
- internals.disconnectTree(nodeToRemove);
- }
-
- if (nodeToInsertWasConnected) {
- internals.disconnectTree(nodeToInsert);
- }
-
- if (thisIsConnected) {
- internals.connectTree(nodeToInsert);
- }
-
- return nativeResult;
- });
-
- function patch_textContent(destination, baseDescriptor) {
- Object.defineProperty(destination, 'textContent', {
- enumerable: baseDescriptor.enumerable,
- configurable: true,
- get: baseDescriptor.get,
- set: /** @this {Node} */function set(assignedValue) {
- // If this is a text node then there are no nodes to disconnect.
- if (this.nodeType === Node.TEXT_NODE) {
- baseDescriptor.set.call(this, assignedValue);
- return;
- }
-
- var removedNodes = undefined;
- // Checking for `firstChild` is faster than reading `childNodes.length`
- // to compare with 0.
- if (this.firstChild) {
- // Using `childNodes` is faster than `children`, even though we only
- // care about elements.
- var childNodes = this.childNodes;
- var childNodesLength = childNodes.length;
- if (childNodesLength > 0 && isConnected(this)) {
- // Copying an array by iterating is faster than using slice.
- removedNodes = new Array(childNodesLength);
- for (var i = 0; i < childNodesLength; i++) {
- removedNodes[i] = childNodes[i];
- }
- }
- }
-
- baseDescriptor.set.call(this, assignedValue);
-
- if (removedNodes) {
- for (var _i = 0; _i < removedNodes.length; _i++) {
- internals.disconnectTree(removedNodes[_i]);
- }
- }
- }
- });
- }
-
- if (Native.Node_textContent && Native.Node_textContent.get) {
- patch_textContent(Node.prototype, Native.Node_textContent);
- } else {
- internals.addPatch(function (element) {
- patch_textContent(element, {
- enumerable: true,
- configurable: true,
- // NOTE: This implementation of the `textContent` getter assumes that
- // text nodes' `textContent` getter will not be patched.
- get: /** @this {Node} */function get() {
- /** @type {!Array<string>} */
- var parts = [];
-
- for (var i = 0; i < this.childNodes.length; i++) {
- parts.push(this.childNodes[i].textContent);
- }
-
- return parts.join('');
- },
- set: /** @this {Node} */function set(assignedValue) {
- while (this.firstChild) {
- Native.Node_removeChild.call(this, this.firstChild);
- }
- Native.Node_appendChild.call(this, document.createTextNode(assignedValue));
- }
- });
- });
- }
- };
-
- /**
- * @param {!CustomElementInternals} internals
- * @param {!Object} destination
- * @param {!ChildNodeNativeMethods} builtIn
- */
- var PatchChildNode = function (internals, destination, builtIn) {
- /**
- * @param {...(!Node|string)} nodes
- */
- destination['before'] = function () {
- for (var _len = arguments.length, nodes = Array(_len), _key = 0; _key < _len; _key++) {
- nodes[_key] = arguments[_key];
- }
-
- // TODO: Fix this for when one of `nodes` is a DocumentFragment!
- var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
- // DocumentFragments are not connected and will not be added to the list.
- return node instanceof Node && isConnected(node);
- });
-
- builtIn.before.apply(this, nodes);
-
- for (var i = 0; i < connectedBefore.length; i++) {
- internals.disconnectTree(connectedBefore[i]);
- }
-
- if (isConnected(this)) {
- for (var _i = 0; _i < nodes.length; _i++) {
- var node = nodes[_i];
- if (node instanceof Element) {
- internals.connectTree(node);
- }
- }
- }
- };
-
- /**
- * @param {...(!Node|string)} nodes
- */
- destination['after'] = function () {
- for (var _len2 = arguments.length, nodes = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- nodes[_key2] = arguments[_key2];
- }
-
- // TODO: Fix this for when one of `nodes` is a DocumentFragment!
- var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
- // DocumentFragments are not connected and will not be added to the list.
- return node instanceof Node && isConnected(node);
- });
-
- builtIn.after.apply(this, nodes);
-
- for (var i = 0; i < connectedBefore.length; i++) {
- internals.disconnectTree(connectedBefore[i]);
- }
-
- if (isConnected(this)) {
- for (var _i2 = 0; _i2 < nodes.length; _i2++) {
- var node = nodes[_i2];
- if (node instanceof Element) {
- internals.connectTree(node);
- }
- }
- }
- };
-
- /**
- * @param {...(!Node|string)} nodes
- */
- destination['replaceWith'] = function () {
- for (var _len3 = arguments.length, nodes = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- nodes[_key3] = arguments[_key3];
- }
-
- // TODO: Fix this for when one of `nodes` is a DocumentFragment!
- var connectedBefore = /** @type {!Array<!Node>} */nodes.filter(function (node) {
- // DocumentFragments are not connected and will not be added to the list.
- return node instanceof Node && isConnected(node);
- });
-
- var wasConnected = isConnected(this);
-
- builtIn.replaceWith.apply(this, nodes);
-
- for (var i = 0; i < connectedBefore.length; i++) {
- internals.disconnectTree(connectedBefore[i]);
- }
-
- if (wasConnected) {
- internals.disconnectTree(this);
- for (var _i3 = 0; _i3 < nodes.length; _i3++) {
- var node = nodes[_i3];
- if (node instanceof Element) {
- internals.connectTree(node);
- }
- }
- }
- };
-
- destination['remove'] = function () {
- var wasConnected = isConnected(this);
-
- builtIn.remove.call(this);
-
- if (wasConnected) {
- internals.disconnectTree(this);
- }
- };
- };
-
- /**
- * @param {!CustomElementInternals} internals
- */
- var PatchElement = function (internals) {
- if (Native.Element_attachShadow) {
- setPropertyUnchecked(Element.prototype, 'attachShadow',
- /**
- * @this {Element}
- * @param {!{mode: string}} init
- * @return {ShadowRoot}
- */
- function (init) {
- var shadowRoot = Native.Element_attachShadow.call(this, init);
- this.__CE_shadowRoot = shadowRoot;
- return shadowRoot;
- });
- } else {
- console.warn('Custom Elements: `Element#attachShadow` was not patched.');
- }
-
- function patch_innerHTML(destination, baseDescriptor) {
- Object.defineProperty(destination, 'innerHTML', {
- enumerable: baseDescriptor.enumerable,
- configurable: true,
- get: baseDescriptor.get,
- set: /** @this {Element} */function set(htmlString) {
- var _this = this;
-
- var isConnected$$1 = isConnected(this);
-
- // NOTE: In IE11, when using the native `innerHTML` setter, all nodes
- // that were previously descendants of the context element have all of
- // their children removed as part of the set - the entire subtree is
- // 'disassembled'. This work around walks the subtree *before* using the
- // native setter.
- /** @type {!Array<!Element>|undefined} */
- var removedElements = undefined;
- if (isConnected$$1) {
- removedElements = [];
- walkDeepDescendantElements(this, function (element) {
- if (element !== _this) {
- removedElements.push(element);
- }
- });
- }
-
- baseDescriptor.set.call(this, htmlString);
-
- if (removedElements) {
- for (var i = 0; i < removedElements.length; i++) {
- var element = removedElements[i];
- if (element.__CE_state === CustomElementState.custom) {
- internals.disconnectedCallback(element);
- }
- }
- }
-
- // Only create custom elements if this element's owner document is
- // associated with the registry.
- if (!this.ownerDocument.__CE_hasRegistry) {
- internals.patchTree(this);
- } else {
- internals.patchAndUpgradeTree(this);
- }
- return htmlString;
- }
- });
- }
-
- if (Native.Element_innerHTML && Native.Element_innerHTML.get) {
- patch_innerHTML(Element.prototype, Native.Element_innerHTML);
- } else if (Native.HTMLElement_innerHTML && Native.HTMLElement_innerHTML.get) {
- patch_innerHTML(HTMLElement.prototype, Native.HTMLElement_innerHTML);
- } else {
-
- /** @type {HTMLDivElement} */
- var rawDiv = Native.Document_createElement.call(document, 'div');
-
- internals.addPatch(function (element) {
- patch_innerHTML(element, {
- enumerable: true,
- configurable: true,
- // Implements getting `innerHTML` by performing an unpatched `cloneNode`
- // of the element and returning the resulting element's `innerHTML`.
- // TODO: Is this too expensive?
- get: /** @this {Element} */function get() {
- return Native.Node_cloneNode.call(this, true).innerHTML;
- },
- // Implements setting `innerHTML` by creating an unpatched element,
- // setting `innerHTML` of that element and replacing the target
- // element's children with those of the unpatched element.
- set: /** @this {Element} */function set(assignedValue) {
- // NOTE: re-route to `content` for `template` elements.
- // We need to do this because `template.appendChild` does not
- // route into `template.content`.
- /** @type {!Node} */
- var content = this.localName === 'template' ? /** @type {!HTMLTemplateElement} */this.content : this;
- rawDiv.innerHTML = assignedValue;
-
- while (content.childNodes.length > 0) {
- Native.Node_removeChild.call(content, content.childNodes[0]);
- }
- while (rawDiv.childNodes.length > 0) {
- Native.Node_appendChild.call(content, rawDiv.childNodes[0]);
- }
- }
- });
- });
- }
-
- setPropertyUnchecked(Element.prototype, 'setAttribute',
- /**
- * @this {Element}
- * @param {string} name
- * @param {string} newValue
- */
- function (name, newValue) {
- // Fast path for non-custom elements.
- if (this.__CE_state !== CustomElementState.custom) {
- return Native.Element_setAttribute.call(this, name, newValue);
- }
-
- var oldValue = Native.Element_getAttribute.call(this, name);
- Native.Element_setAttribute.call(this, name, newValue);
- newValue = Native.Element_getAttribute.call(this, name);
- internals.attributeChangedCallback(this, name, oldValue, newValue, null);
- });
-
- setPropertyUnchecked(Element.prototype, 'setAttributeNS',
- /**
- * @this {Element}
- * @param {?string} namespace
- * @param {string} name
- * @param {string} newValue
- */
- function (namespace, name, newValue) {
- // Fast path for non-custom elements.
- if (this.__CE_state !== CustomElementState.custom) {
- return Native.Element_setAttributeNS.call(this, namespace, name, newValue);
- }
-
- var oldValue = Native.Element_getAttributeNS.call(this, namespace, name);
- Native.Element_setAttributeNS.call(this, namespace, name, newValue);
- newValue = Native.Element_getAttributeNS.call(this, namespace, name);
- internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);
- });
-
- setPropertyUnchecked(Element.prototype, 'removeAttribute',
- /**
- * @this {Element}
- * @param {string} name
- */
- function (name) {
- // Fast path for non-custom elements.
- if (this.__CE_state !== CustomElementState.custom) {
- return Native.Element_removeAttribute.call(this, name);
- }
-
- var oldValue = Native.Element_getAttribute.call(this, name);
- Native.Element_removeAttribute.call(this, name);
- if (oldValue !== null) {
- internals.attributeChangedCallback(this, name, oldValue, null, null);
- }
- });
-
- setPropertyUnchecked(Element.prototype, 'removeAttributeNS',
- /**
- * @this {Element}
- * @param {?string} namespace
- * @param {string} name
- */
- function (namespace, name) {
- // Fast path for non-custom elements.
- if (this.__CE_state !== CustomElementState.custom) {
- return Native.Element_removeAttributeNS.call(this, namespace, name);
- }
-
- var oldValue = Native.Element_getAttributeNS.call(this, namespace, name);
- Native.Element_removeAttributeNS.call(this, namespace, name);
- // In older browsers, `Element#getAttributeNS` may return the empty string
- // instead of null if the attribute does not exist. For details, see;
- // https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttributeNS#Notes
- var newValue = Native.Element_getAttributeNS.call(this, namespace, name);
- if (oldValue !== newValue) {
- internals.attributeChangedCallback(this, name, oldValue, newValue, namespace);
- }
- });
-
- function patch_insertAdjacentElement(destination, baseMethod) {
- setPropertyUnchecked(destination, 'insertAdjacentElement',
- /**
- * @this {Element}
- * @param {string} where
- * @param {!Element} element
- * @return {?Element}
- */
- function (where, element) {
- var wasConnected = isConnected(element);
- var insertedElement = /** @type {!Element} */
- baseMethod.call(this, where, element);
-
- if (wasConnected) {
- internals.disconnectTree(element);
- }
-
- if (isConnected(insertedElement)) {
- internals.connectTree(element);
- }
- return insertedElement;
- });
- }
-
- if (Native.HTMLElement_insertAdjacentElement) {
- patch_insertAdjacentElement(HTMLElement.prototype, Native.HTMLElement_insertAdjacentElement);
- } else if (Native.Element_insertAdjacentElement) {
- patch_insertAdjacentElement(Element.prototype, Native.Element_insertAdjacentElement);
- } else {
- console.warn('Custom Elements: `Element#insertAdjacentElement` was not patched.');
- }
-
- PatchParentNode(internals, Element.prototype, {
- prepend: Native.Element_prepend,
- append: Native.Element_append
- });
-
- PatchChildNode(internals, Element.prototype, {
- before: Native.Element_before,
- after: Native.Element_after,
- replaceWith: Native.Element_replaceWith,
- remove: Native.Element_remove
- });
- };
-
- /**
- * @license
- * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
-
- var priorCustomElements = window['customElements'];
-
- if (!priorCustomElements || priorCustomElements['forcePolyfill'] || typeof priorCustomElements['define'] != 'function' || typeof priorCustomElements['get'] != 'function') {
- /** @type {!CustomElementInternals} */
- var internals = new CustomElementInternals();
-
- PatchHTMLElement(internals);
- PatchDocument(internals);
- PatchNode(internals);
- PatchElement(internals);
-
- // The main document is always associated with the registry.
- document.__CE_hasRegistry = true;
-
- /** @type {!CustomElementRegistry} */
- var customElements$1 = new CustomElementRegistry(internals);
-
- Object.defineProperty(window, 'customElements', {
- configurable: true,
- enumerable: true,
- value: customElements$1
- });
- }
-
- /**
- * @license
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
- // @version 0.7.22
-
- (function (global) {
- if (global.JsMutationObserver) {
- return;
- }
- var registrationsTable = new WeakMap();
- var setImmediate;
- if (/Trident|Edge/.test(navigator.userAgent)) {
- setImmediate = setTimeout;
- } else if (window.setImmediate) {
- setImmediate = window.setImmediate;
- } else {
- var setImmediateQueue = [];
- var sentinel = String(Math.random());
- window.addEventListener("message", function (e) {
- if (e.data === sentinel) {
- var queue = setImmediateQueue;
- setImmediateQueue = [];
- queue.forEach(function (func) {
- func();
- });
- }
- });
- setImmediate = function setImmediate(func) {
- setImmediateQueue.push(func);
- window.postMessage(sentinel, "*");
- };
- }
- var isScheduled = false;
- var scheduledObservers = [];
- function scheduleCallback(observer) {
- scheduledObservers.push(observer);
- if (!isScheduled) {
- isScheduled = true;
- setImmediate(dispatchCallbacks);
- }
- }
- function wrapIfNeeded(node) {
- return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
- }
- function dispatchCallbacks() {
- isScheduled = false;
- var observers = scheduledObservers;
- scheduledObservers = [];
- observers.sort(function (o1, o2) {
- return o1.uid_ - o2.uid_;
- });
- var anyNonEmpty = false;
- observers.forEach(function (observer) {
- var queue = observer.takeRecords();
- removeTransientObserversFor(observer);
- if (queue.length) {
- observer.callback_(queue, observer);
- anyNonEmpty = true;
- }
- });
- if (anyNonEmpty) dispatchCallbacks();
- }
- function removeTransientObserversFor(observer) {
- observer.nodes_.forEach(function (node) {
- var registrations = registrationsTable.get(node);
- if (!registrations) return;
- registrations.forEach(function (registration) {
- if (registration.observer === observer) registration.removeTransientObservers();
- });
- });
- }
- function forEachAncestorAndObserverEnqueueRecord(target, callback) {
- for (var node = target; node; node = node.parentNode) {
- var registrations = registrationsTable.get(node);
- if (registrations) {
- for (var j = 0; j < registrations.length; j++) {
- var registration = registrations[j];
- var options = registration.options;
- if (node !== target && !options.subtree) continue;
- var record = callback(options);
- if (record) registration.enqueue(record);
- }
- }
- }
- }
- var uidCounter = 0;
- function JsMutationObserver(callback) {
- this.callback_ = callback;
- this.nodes_ = [];
- this.records_ = [];
- this.uid_ = ++uidCounter;
- }
- JsMutationObserver.prototype = {
- observe: function observe(target, options) {
- target = wrapIfNeeded(target);
- if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
- throw new SyntaxError();
- }
- var registrations = registrationsTable.get(target);
- if (!registrations) registrationsTable.set(target, registrations = []);
- var registration;
- for (var i = 0; i < registrations.length; i++) {
- if (registrations[i].observer === this) {
- registration = registrations[i];
- registration.removeListeners();
- registration.options = options;
- break;
- }
- }
- if (!registration) {
- registration = new Registration(this, target, options);
- registrations.push(registration);
- this.nodes_.push(target);
- }
- registration.addListeners();
- },
- disconnect: function disconnect() {
- this.nodes_.forEach(function (node) {
- var registrations = registrationsTable.get(node);
- for (var i = 0; i < registrations.length; i++) {
- var registration = registrations[i];
- if (registration.observer === this) {
- registration.removeListeners();
- registrations.splice(i, 1);
- break;
- }
- }
- }, this);
- this.records_ = [];
- },
- takeRecords: function takeRecords() {
- var copyOfRecords = this.records_;
- this.records_ = [];
- return copyOfRecords;
- }
- };
- function MutationRecord(type, target) {
- this.type = type;
- this.target = target;
- this.addedNodes = [];
- this.removedNodes = [];
- this.previousSibling = null;
- this.nextSibling = null;
- this.attributeName = null;
- this.attributeNamespace = null;
- this.oldValue = null;
- }
- function copyMutationRecord(original) {
- var record = new MutationRecord(original.type, original.target);
- record.addedNodes = original.addedNodes.slice();
- record.removedNodes = original.removedNodes.slice();
- record.previousSibling = original.previousSibling;
- record.nextSibling = original.nextSibling;
- record.attributeName = original.attributeName;
- record.attributeNamespace = original.attributeNamespace;
- record.oldValue = original.oldValue;
- return record;
- }
- var currentRecord, recordWithOldValue;
- function getRecord(type, target) {
- return currentRecord = new MutationRecord(type, target);
- }
- function getRecordWithOldValue(oldValue) {
- if (recordWithOldValue) return recordWithOldValue;
- recordWithOldValue = copyMutationRecord(currentRecord);
- recordWithOldValue.oldValue = oldValue;
- return recordWithOldValue;
- }
- function clearRecords() {
- currentRecord = recordWithOldValue = undefined;
- }
- function recordRepresentsCurrentMutation(record) {
- return record === recordWithOldValue || record === currentRecord;
- }
- function selectRecord(lastRecord, newRecord) {
- if (lastRecord === newRecord) return lastRecord;
- if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
- return null;
- }
- function Registration(observer, target, options) {
- this.observer = observer;
- this.target = target;
- this.options = options;
- this.transientObservedNodes = [];
- }
- Registration.prototype = {
- enqueue: function enqueue(record) {
- var records = this.observer.records_;
- var length = records.length;
- if (records.length > 0) {
- var lastRecord = records[length - 1];
- var recordToReplaceLast = selectRecord(lastRecord, record);
- if (recordToReplaceLast) {
- records[length - 1] = recordToReplaceLast;
- return;
- }
- } else {
- scheduleCallback(this.observer);
- }
- records[length] = record;
- },
- addListeners: function addListeners() {
- this.addListeners_(this.target);
- },
- addListeners_: function addListeners_(node) {
- var options = this.options;
- if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
- if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
- if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
- if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
- },
- removeListeners: function removeListeners() {
- this.removeListeners_(this.target);
- },
- removeListeners_: function removeListeners_(node) {
- var options = this.options;
- if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
- if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
- if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
- if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
- },
- addTransientObserver: function addTransientObserver(node) {
- if (node === this.target) return;
- this.addListeners_(node);
- this.transientObservedNodes.push(node);
- var registrations = registrationsTable.get(node);
- if (!registrations) registrationsTable.set(node, registrations = []);
- registrations.push(this);
- },
- removeTransientObservers: function removeTransientObservers() {
- var transientObservedNodes = this.transientObservedNodes;
- this.transientObservedNodes = [];
- transientObservedNodes.forEach(function (node) {
- this.removeListeners_(node);
- var registrations = registrationsTable.get(node);
- for (var i = 0; i < registrations.length; i++) {
- if (registrations[i] === this) {
- registrations.splice(i, 1);
- break;
- }
- }
- }, this);
- },
- handleEvent: function handleEvent(e) {
- e.stopImmediatePropagation();
- switch (e.type) {
- case "DOMAttrModified":
- var name = e.attrName;
- var namespace = e.relatedNode.namespaceURI;
- var target = e.target;
- var record = new getRecord("attributes", target);
- record.attributeName = name;
- record.attributeNamespace = namespace;
- var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
- forEachAncestorAndObserverEnqueueRecord(target, function (options) {
- if (!options.attributes) return;
- if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
- return;
- }
- if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
- return record;
- });
- break;
-
- case "DOMCharacterDataModified":
- var target = e.target;
- var record = getRecord("characterData", target);
- var oldValue = e.prevValue;
- forEachAncestorAndObserverEnqueueRecord(target, function (options) {
- if (!options.characterData) return;
- if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
- return record;
- });
- break;
-
- case "DOMNodeRemoved":
- this.addTransientObserver(e.target);
-
- case "DOMNodeInserted":
- var changedNode = e.target;
- var addedNodes, removedNodes;
- if (e.type === "DOMNodeInserted") {
- addedNodes = [changedNode];
- removedNodes = [];
- } else {
- addedNodes = [];
- removedNodes = [changedNode];
- }
- var previousSibling = changedNode.previousSibling;
- var nextSibling = changedNode.nextSibling;
- var record = getRecord("childList", e.target.parentNode);
- record.addedNodes = addedNodes;
- record.removedNodes = removedNodes;
- record.previousSibling = previousSibling;
- record.nextSibling = nextSibling;
- forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function (options) {
- if (!options.childList) return;
- return record;
- });
- }
- clearRecords();
- }
- };
- global.JsMutationObserver = JsMutationObserver;
- if (!global.MutationObserver) {
- global.MutationObserver = JsMutationObserver;
- JsMutationObserver._isPolyfilled = true;
- }
- })(self);
-
- /*
- Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- */
- (function (global, undefined) {
- if (global.setImmediate) {
- return;
- }
-
- var nextHandle = 1; // Spec says greater than zero
- var tasksByHandle = {};
- var currentlyRunningATask = false;
- var doc = global.document;
- var setImmediate;
-
- function addFromSetImmediateArguments(args) {
- tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
- return nextHandle++;
- }
-
- // This function accepts the same arguments as setImmediate, but
- // returns a function that requires no arguments.
- function partiallyApplied(handler) {
- var args = [].slice.call(arguments, 1);
- return function () {
- if (typeof handler === "function") {
- handler.apply(undefined, args);
- } else {
- new Function("" + handler)();
- }
- };
- }
-
- function runIfPresent(handle) {
- // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
- // So if we're currently running a task, we'll need to delay this invocation.
- if (currentlyRunningATask) {
- // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
- // "too much recursion" error.
- setTimeout(partiallyApplied(runIfPresent, handle), 0);
- } else {
- var task = tasksByHandle[handle];
- if (task) {
- currentlyRunningATask = true;
- try {
- task();
- } finally {
- clearImmediate(handle);
- currentlyRunningATask = false;
- }
- }
- }
- }
-
- function clearImmediate(handle) {
- delete tasksByHandle[handle];
- }
-
- function installNextTickImplementation() {
- setImmediate = function setImmediate() {
- var handle = addFromSetImmediateArguments(arguments);
- process.nextTick(partiallyApplied(runIfPresent, handle));
- return handle;
- };
- }
-
- function canUsePostMessage() {
- // The test against `importScripts` prevents this implementation from being installed inside a web worker,
- // where `global.postMessage` means something completely different and can't be used for this purpose.
- if (global.postMessage && !global.importScripts) {
- var postMessageIsAsynchronous = true;
- var oldOnMessage = global.onmessage;
- global.onmessage = function () {
- postMessageIsAsynchronous = false;
- };
- global.postMessage("", "*");
- global.onmessage = oldOnMessage;
- return postMessageIsAsynchronous;
- }
- }
-
- function installPostMessageImplementation() {
- // Installs an event handler on `global` for the `message` event: see
- // * https://developer.mozilla.org/en/DOM/window.postMessage
- // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
-
- var messagePrefix = "setImmediate$" + Math.random() + "$";
- var onGlobalMessage = function onGlobalMessage(event) {
- if (event.source === global && typeof event.data === "string" && event.data.indexOf(messagePrefix) === 0) {
- runIfPresent(+event.data.slice(messagePrefix.length));
- }
- };
-
- if (global.addEventListener) {
- global.addEventListener("message", onGlobalMessage, false);
- } else {
- global.attachEvent("onmessage", onGlobalMessage);
- }
-
- setImmediate = function setImmediate() {
- var handle = addFromSetImmediateArguments(arguments);
- global.postMessage(messagePrefix + handle, "*");
- return handle;
- };
- }
-
- function installMessageChannelImplementation() {
- var channel = new MessageChannel();
- channel.port1.onmessage = function (event) {
- var handle = event.data;
- runIfPresent(handle);
- };
-
- setImmediate = function setImmediate() {
- var handle = addFromSetImmediateArguments(arguments);
- channel.port2.postMessage(handle);
- return handle;
- };
- }
-
- function installReadyStateChangeImplementation() {
- var html = doc.documentElement;
- setImmediate = function setImmediate() {
- var handle = addFromSetImmediateArguments(arguments);
- // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
- // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
- var script = doc.createElement("script");
- script.onreadystatechange = function () {
- runIfPresent(handle);
- script.onreadystatechange = null;
- html.removeChild(script);
- script = null;
- };
- html.appendChild(script);
- return handle;
- };
- }
-
- function installSetTimeoutImplementation() {
- setImmediate = function setImmediate() {
- var handle = addFromSetImmediateArguments(arguments);
- setTimeout(partiallyApplied(runIfPresent, handle), 0);
- return handle;
- };
- }
-
- // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
- var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
- attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
-
- // Don't get fooled by e.g. browserify environments.
- if ({}.toString.call(global.process) === "[object process]") {
- // For Node.js before 0.9
- installNextTickImplementation();
- } else if (canUsePostMessage()) {
- // For non-IE10 modern browsers
- installPostMessageImplementation();
- } else if (global.MessageChannel) {
- // For web workers, where supported
- installMessageChannelImplementation();
- } else if (doc && "onreadystatechange" in doc.createElement("script")) {
- // For IE 6–8
- installReadyStateChangeImplementation();
- } else {
- // For older browsers
- installSetTimeoutImplementation();
- }
-
- attachTo.setImmediate = setImmediate;
- attachTo.clearImmediate = clearImmediate;
- })(self);
-
- // Caution:
- // Do not replace this import statement with codes.
- //
- // If you replace this import statement with codes,
- // the codes will be executed after the following polyfills are imported
- // because import statements are hoisted during compilation.
- // Polyfill ECMAScript standard features with global namespace pollution
- // Polyfill Custom Elements v1 with global namespace pollution
- // Polyfill MutationObserver with global namespace pollution
- // Polyfill setImmediate with global namespace pollution
-
- (function () {
- var DEFAULT_VIEWPORT = 'width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no';
-
- var Viewport = {
- ensureViewportElement: function ensureViewportElement() {
- var viewportElement = document.querySelector('meta[name=viewport]');
-
- if (!viewportElement) {
- viewportElement = document.createElement('meta');
- viewportElement.name = 'viewport';
- document.head.appendChild(viewportElement);
- }
-
- return viewportElement;
- },
-
- setup: function setup() {
- var viewportElement = Viewport.ensureViewportElement();
-
- if (!viewportElement) {
- return;
- }
-
- if (!viewportElement.hasAttribute('content')) {
- viewportElement.setAttribute('content', DEFAULT_VIEWPORT);
- }
- }
- };
-
- window.Viewport = Viewport;
- })();
-
- function setup$1(ons) {
- if (window._onsLoaded) {
- ons._util.warn('Onsen UI is loaded more than once.');
- }
- window._onsLoaded = true;
-
- // fastclick
- window.addEventListener('load', function () {
- ons.fastClick = fastclick_1.attach(document.body);
-
- var supportTouchAction = 'touch-action' in document.body.style;
-
- ons.platform._runOnActualPlatform(function () {
- if (ons.platform.isAndroid()) {
- // In Android4.4+, correct viewport settings can remove click delay.
- // So disable FastClick on Android.
- ons.fastClick.destroy();
- } else if (ons.platform.isIOS()) {
- if (supportTouchAction && (ons.platform.isIOSSafari() || ons.platform.isWKWebView())) {
- // If 'touch-action' supported in iOS Safari or WKWebView, disable FastClick.
- ons.fastClick.destroy();
- } else {
- // Do nothing. 'touch-action: manipulation' has no effect on UIWebView.
- }
- }
- });
- }, false);
-
- ons.ready(function () {
- ons.enableDeviceBackButtonHandler();
- ons._defaultDeviceBackButtonHandler = ons._internal.dbbDispatcher.createHandler(window.document.body, function () {
- if (Object.hasOwnProperty.call(navigator, 'app')) {
- navigator.app.exitApp();
- } else {
- console.warn('Could not close the app. Is \'cordova.js\' included?\nError: \'window.navigator.app\' is undefined.');
- }
- });
- document.body._gestureDetector = new ons.GestureDetector(document.body, { passive: true });
-
- // Simulate Device Back Button on ESC press
- if (!ons.platform.isWebView()) {
- document.body.addEventListener('keydown', function (event) {
- if (event.keyCode === 27) {
- ons.fireDeviceBackButtonEvent();
- }
- });
- }
-
- // setup loading placeholder
- ons._setupLoadingPlaceHolders();
- });
-
- // viewport.js
- Viewport.setup();
- }
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- function getElementClass() {
- if (typeof HTMLElement !== 'function') {
- // case of Safari
- var _BaseElement = function _BaseElement() {};
- _BaseElement.prototype = document.createElement('div');
- return _BaseElement;
- } else {
- return HTMLElement;
- }
- }
-
- var BaseElement = function (_getElementClass) {
- inherits(BaseElement, _getElementClass);
-
- function BaseElement() {
- classCallCheck(this, BaseElement);
- return possibleConstructorReturn(this, (BaseElement.__proto__ || Object.getPrototypeOf(BaseElement)).call(this));
- }
-
- return BaseElement;
- }(getElementClass());
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-template
- * @category util
- * @description
- * [en]
- * Define a separate HTML fragment and use as a template. These templates can be loaded as pages in `<ons-navigator>`, `<ons-tabbar>` and `<ons-splitter>`. They can also be used to generate dialogs. Since Onsen UI 2.4.0, the native `<template>` element can be used instead of `<ons-template>` for better performance and features. `<ons-template>` is still supported for backward compatibility.
- * [/en]
- * [ja]テンプレートとして使用するためのHTMLフラグメントを定義します。この要素でHTMLを宣言すると、id属性に指定した名前をpageのURLとしてons-navigatorなどのコンポーネントから参照できます。[/ja]
- * @seealso ons-navigator
- * [en]The `<ons-navigator>` component enables stack based navigation.[/en]
- * [ja][/ja]
- * @seealso ons-tabbar
- * [en]The `<ons-tabbar>` component is used to add tab navigation.[/en]
- * [ja][/ja]
- * @seealso ons-splitter
- * [en]The `<ons-splitter>` component can be used to create a draggable menu or column based layout.[/en]
- * [ja][/ja]
- * @example
- * <ons-template id="foobar.html">
- * <ons-page>
- * Page content
- * </ons-page>
- * </ons-template>
- *
- * <ons-navigator page="foobar.html"></ons-navigator>
- */
-
- var TemplateElement = function (_BaseElement) {
- inherits(TemplateElement, _BaseElement);
-
- /**
- * @property template
- * @type {String}
- * @description
- * [en]Template content. This property can not be used with AngularJS bindings.[/en]
- * [ja][/ja]
- */
-
- function TemplateElement() {
- classCallCheck(this, TemplateElement);
-
- var _this = possibleConstructorReturn(this, (TemplateElement.__proto__ || Object.getPrototypeOf(TemplateElement)).call(this));
-
- _this.template = _this.innerHTML;
-
- while (_this.firstChild) {
- _this.removeChild(_this.firstChild);
- }
- return _this;
- }
-
- createClass(TemplateElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- if (this.parentNode) {
- // Note: this.parentNode is not set in some CE0/CE1 polyfills.
- // Show warning when the ons-template is not located just under document.body
- if (this.parentNode !== document.body) {
- // if the parent is not document.body
- util$1.warn('ons-template (id = ' + this.getAttribute('id') + ') must be located just under document.body' + (this.parentNode.outerHTML ? ':\n\n' + this.parentNode.outerHTML : '.'));
- }
- }
-
- var event = new CustomEvent('_templateloaded', { bubbles: true, cancelable: true });
- event.template = this.template;
- event.templateId = this.getAttribute('id');
-
- this.dispatchEvent(event);
- }
- }]);
- return TemplateElement;
- }(BaseElement);
-
- onsElements.Template = TemplateElement;
- customElements.define('ons-template', TemplateElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-if
- * @category conditional
- * @tutorial vanilla/Reference/if
- * @description
- * [en]
- * Conditionally display content depending on the platform, device orientation or both.
- *
- * Sometimes it is useful to conditionally hide or show certain components based on platform. When running on iOS the `<ons-if>` element can be used to hide the `<ons-fab>` element.
- * [/en]
- * [ja][/ja]
- * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
- * @example
- * <ons-page>
- * <ons-if orientation="landscape">
- * Landscape view!
- * </ons-if>
- * <ons-if platform="android">
- * This is Android.
- * </ons-if>
- * <ons-if platform="ios other">
- * This is not Android.
- * </ons-if>
- * </ons-page>
- */
-
- var IfElement = function (_BaseElement) {
- inherits(IfElement, _BaseElement);
-
- /**
- * @attribute platform
- * @initonly
- * @type {string}
- * @description
- * [en]Space-separated platform names. Possible values are `"ios"`, `"android"`, `"windows"` and `"other"`.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute orientation
- * @type {string}
- * @description
- * [en]Either `"portrait"` or `"landscape"`.[/en]
- * [ja]portraitもしくはlandscapeを指定します[/ja]
- */
-
- function IfElement() {
- classCallCheck(this, IfElement);
-
- var _this = possibleConstructorReturn(this, (IfElement.__proto__ || Object.getPrototypeOf(IfElement)).call(this));
-
- contentReady(_this, function () {
- if (platform._getSelectedPlatform() !== null) {
- _this._platformUpdate();
- } else if (!_this._isAllowedPlatform()) {
- while (_this.childNodes[0]) {
- _this.childNodes[0].remove();
- }
- _this._platformUpdate();
- }
- });
-
- _this._onOrientationChange();
- return _this;
- }
-
- createClass(IfElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- orientation.on('change', this._onOrientationChange.bind(this));
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name) {
- if (name === 'orientation') {
- this._onOrientationChange();
- }
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- orientation.off('change', this._onOrientationChange);
- }
- }, {
- key: '_platformUpdate',
- value: function _platformUpdate() {
- this.style.display = this._isAllowedPlatform() ? '' : 'none';
- }
- }, {
- key: '_isAllowedPlatform',
- value: function _isAllowedPlatform() {
- return !this.getAttribute('platform') || this.getAttribute('platform').split(/\s+/).indexOf(platform.getMobileOS()) >= 0;
- }
- }, {
- key: '_onOrientationChange',
- value: function _onOrientationChange() {
- if (this.hasAttribute('orientation') && this._isAllowedPlatform()) {
- var conditionalOrientation = this.getAttribute('orientation').toLowerCase();
- var currentOrientation = orientation.isPortrait() ? 'portrait' : 'landscape';
-
- this.style.display = conditionalOrientation === currentOrientation ? '' : 'none';
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['orientation'];
- }
- }]);
- return IfElement;
- }(BaseElement);
-
- onsElements.If = IfElement;
- customElements.define('ons-if', IfElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var BaseAnimator = function () {
-
- /**
- * @param {Object} options
- * @param {String} options.timing
- * @param {Number} options.duration
- * @param {Number} options.delay
- */
- function BaseAnimator() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- classCallCheck(this, BaseAnimator);
-
- this.timing = options.timing || 'linear';
- this.duration = options.duration || 0;
- this.delay = options.delay || 0;
-
- this.def = {
- timing: this.timing,
- duration: this.duration,
- delay: this.delay
- };
- }
-
- createClass(BaseAnimator, null, [{
- key: 'extend',
- value: function extend() {
- var properties = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- var extendedAnimator = this;
- var newAnimator = function newAnimator() {
- extendedAnimator.apply(this, arguments);
- util$1.extend(this, properties);
- };
-
- newAnimator.prototype = this.prototype;
- return newAnimator;
- }
- }]);
- return BaseAnimator;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- // This object should not be exposed to users. Please keep this private.
- var iPhoneXPatch = {};
-
- iPhoneXPatch.isIPhoneXPortraitPatchActive = function () {
- return document.documentElement.getAttribute('onsflag-iphonex-portrait') != null && window.innerWidth < window.innerHeight;
- };
-
- iPhoneXPatch.isIPhoneXLandscapePatchActive = function () {
- // If width === height, treat it as landscape
- return document.documentElement.getAttribute('onsflag-iphonex-landscape') != null && window.innerWidth >= window.innerHeight;
- };
-
- /**
- * Returns the safe area lengths based on the current state of the safe areas.
- */
- iPhoneXPatch.getSafeAreaLengths = function () {
- var safeAreaLengths = void 0;
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- safeAreaLengths = {
- top: 44,
- right: 0,
- bottom: 34,
- left: 0
- };
- } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
- safeAreaLengths = {
- top: 0,
- right: 44,
- bottom: 21,
- left: 44
- };
- } else {
- safeAreaLengths = {
- top: 0,
- right: 0,
- bottom: 0,
- left: 0
- };
- }
-
- return safeAreaLengths;
- };
-
- /**
- * Returns the safe area rect based on the current state of the safe areas.
- */
- iPhoneXPatch.getSafeAreaDOMRect = function () {
- var safeAreaRect = void 0;
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- safeAreaRect = {
- x: 0,
- y: 44, /* 0 + 44 (top safe area) */
- width: window.innerWidth,
- height: window.innerHeight - 78 /* height - 44 (top safe area) - 34 (bottom safe area) */
- };
- } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
- safeAreaRect = {
- x: 44, /* 0 + 44 (left safe area) */
- y: 0,
- width: window.innerWidth - 88, /* width - 44 (left safe area) - 34 (right safe area) */
- height: window.innerHeight - 21 /* height - 21 (bottom safe area) */
- };
- } else {
- safeAreaRect = {
- x: 0,
- y: 0,
- width: window.innerWidth,
- height: window.innerHeight
- };
- }
-
- return _extends({}, safeAreaRect, {
- left: safeAreaRect.x,
- top: safeAreaRect.y,
- right: safeAreaRect.x + safeAreaRect.width,
- bottom: safeAreaRect.y + safeAreaRect.height
- });
- };
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var ActionSheetAnimator = function (_BaseAnimator) {
- inherits(ActionSheetAnimator, _BaseAnimator);
-
- function ActionSheetAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, ActionSheetAnimator);
- return possibleConstructorReturn(this, (ActionSheetAnimator.__proto__ || Object.getPrototypeOf(ActionSheetAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} dialog
- * @param {Function} done
- */
-
-
- createClass(ActionSheetAnimator, [{
- key: 'show',
- value: function show(dialog, done) {
- done();
- }
-
- /**
- * @param {HTMLElement} dialog
- * @param {Function} done
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, done) {
- done();
- }
- }]);
- return ActionSheetAnimator;
- }(BaseAnimator);
-
- /**
- * Android style animator for Action Sheet.
- */
- var MDActionSheetAnimator = function (_ActionSheetAnimator) {
- inherits(MDActionSheetAnimator, _ActionSheetAnimator);
-
- function MDActionSheetAnimator() {
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref2$timing = _ref2.timing,
- timing = _ref2$timing === undefined ? 'ease' : _ref2$timing,
- _ref2$delay = _ref2.delay,
- delay = _ref2$delay === undefined ? 0 : _ref2$delay,
- _ref2$duration = _ref2.duration,
- duration = _ref2$duration === undefined ? 0.4 : _ref2$duration;
-
- classCallCheck(this, MDActionSheetAnimator);
-
- var _this2 = possibleConstructorReturn(this, (MDActionSheetAnimator.__proto__ || Object.getPrototypeOf(MDActionSheetAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this2.maskTiming = 'linear';
- _this2.maskDuration = 0.2;
- return _this2;
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(MDActionSheetAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
-
- Animit.runAll(Animit(dialog._mask).queue({ opacity: 0 }).wait(this.delay).queue({ opacity: 1.0 }, {
- duration: this.maskDuration,
- timing: this.maskTiming
- }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, 80%, 0)', opacity: 0 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- Animit.runAll(Animit(dialog._mask).queue({ opacity: 1 }).wait(this.delay).queue({ opacity: 0 }, {
- duration: this.maskDuration,
- timing: this.maskTiming
- }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 1 }, { transform: 'translate3d(0, 80%, 0)', opacity: 0 }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
- }]);
- return MDActionSheetAnimator;
- }(ActionSheetAnimator);
-
- /**
- * iOS style animator for dialog.
- */
- var IOSActionSheetAnimator = function (_ActionSheetAnimator2) {
- inherits(IOSActionSheetAnimator, _ActionSheetAnimator2);
-
- function IOSActionSheetAnimator() {
- var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref3$timing = _ref3.timing,
- timing = _ref3$timing === undefined ? 'ease' : _ref3$timing,
- _ref3$delay = _ref3.delay,
- delay = _ref3$delay === undefined ? 0 : _ref3$delay,
- _ref3$duration = _ref3.duration,
- duration = _ref3$duration === undefined ? 0.3 : _ref3$duration;
-
- classCallCheck(this, IOSActionSheetAnimator);
-
- var _this3 = possibleConstructorReturn(this, (IOSActionSheetAnimator.__proto__ || Object.getPrototypeOf(IOSActionSheetAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this3.maskTiming = 'linear';
- _this3.maskDuration = 0.2;
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- _this3.liftAmount = 'calc(100% + 48px)';
- } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
- _this3.liftAmount = 'calc(100% + 33px)';
- } else {
- _this3.liftAmount = document.body.clientHeight / 2.0 - 1 + 'px'; // avoid Forced Synchronous Layout
- }
- return _this3;
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(IOSActionSheetAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
- Animit.runAll(Animit(dialog._mask).queue({ opacity: 0 }).wait(this.delay).queue({ opacity: 1 }, {
- duration: this.maskDuration,
- timing: this.maskTiming
- }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, ' + this.liftAmount + ', 0)' }, { transform: 'translate3d(0, 0, 0)' }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- Animit.runAll(Animit(dialog._mask).queue({ opacity: 1 }).wait(this.delay).queue({ opacity: 0 }, {
- duration: this.maskDuration,
- timing: this.maskTiming
- }), Animit(dialog._sheet, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, ' + this.liftAmount + ', 0)' }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
- }]);
- return IOSActionSheetAnimator;
- }(ActionSheetAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var BaseDialogElement = function (_BaseElement) {
- inherits(BaseDialogElement, _BaseElement);
- createClass(BaseDialogElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- util$1.throwMember();
- }
- }, {
- key: '_toggleStyle',
- value: function _toggleStyle(shouldShow) {
- this.style.display = shouldShow ? 'block' : 'none';
- }
- }, {
- key: '_scheme',
- get: function get$$1() {
- util$1.throwMember();
- }
- }]);
-
- function BaseDialogElement() {
- classCallCheck(this, BaseDialogElement);
-
- var _this = possibleConstructorReturn(this, (BaseDialogElement.__proto__ || Object.getPrototypeOf(BaseDialogElement)).call(this));
-
- if (_this.constructor === BaseDialogElement) {
- util$1.throwAbstract();
- }
-
- _this._visible = false;
- _this._doorLock = new DoorLock();
- _this._cancel = _this._cancel.bind(_this);
- _this._selfCamelName = util$1.camelize(_this.tagName.slice(4));
- _this._defaultDBB = function (e) {
- return _this.cancelable ? _this._cancel() : e.callParentHandler();
- };
- _this._animatorFactory = _this._updateAnimatorFactory();
- return _this;
- }
-
- createClass(BaseDialogElement, [{
- key: '_cancel',
- value: function _cancel() {
- var _this2 = this;
-
- if (this.cancelable && !this._running) {
- this._running = true;
- this.hide().then(function () {
- _this2._running = false;
- util$1.triggerElementEvent(_this2, 'dialog-cancel');
- }, function () {
- return _this2._running = false;
- });
- }
- }
- }, {
- key: 'show',
- value: function show() {
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- return this._setVisible.apply(this, [true].concat(args));
- }
- }, {
- key: 'hide',
- value: function hide() {
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- return this._setVisible.apply(this, [false].concat(args));
- }
- }, {
- key: 'toggle',
- value: function toggle() {
- for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- args[_key3] = arguments[_key3];
- }
-
- return this._setVisible.apply(this, [!this.visible].concat(args));
- }
- }, {
- key: '_setVisible',
- value: function _setVisible(shouldShow) {
- var _util$triggerElementE,
- _this3 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var action = shouldShow ? 'show' : 'hide';
-
- options = _extends({}, options);
- options.animationOptions = util$1.extend(options.animationOptions || {}, AnimatorFactory.parseAnimationOptionsString(this.getAttribute('animation-options')));
-
- var canceled = false;
- util$1.triggerElementEvent(this, 'pre' + action, (_util$triggerElementE = {}, defineProperty(_util$triggerElementE, this._selfCamelName, this), defineProperty(_util$triggerElementE, 'cancel', function cancel() {
- return canceled = true;
- }), _util$triggerElementE));
-
- if (canceled) {
- return Promise.reject('Canceled in pre' + action + ' event.');
- }
-
- return new Promise(function (resolve) {
- _this3._doorLock.waitUnlock(function () {
- var unlock = _this3._doorLock.lock();
- var animator = _this3._animatorFactory.newAnimator(options);
-
- shouldShow && _this3._toggleStyle(true, options);
- _this3._visible = shouldShow;
- util$1.iosPageScrollFix(shouldShow);
-
- contentReady(_this3, function () {
- animator[action](_this3, function () {
- !shouldShow && _this3._toggleStyle(false, options);
-
- unlock();
-
- util$1.propagateAction(_this3, '_' + action);
- util$1.triggerElementEvent(_this3, 'post' + action, defineProperty({}, _this3._selfCamelName, _this3)); // postshow posthide
-
- if (options.callback instanceof Function) {
- options.callback(_this3);
- }
-
- resolve(_this3);
- });
- });
- });
- });
- }
- }, {
- key: '_updateMask',
- value: function _updateMask() {
- var _this4 = this;
-
- contentReady(this, function () {
- if (_this4._mask && _this4.getAttribute('mask-color')) {
- _this4._mask.style.backgroundColor = _this4.getAttribute('mask-color');
- }
- });
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this5 = this;
-
- if (typeof this._defaultDBB === 'function') {
- this.onDeviceBackButton = this._defaultDBB.bind(this);
- }
-
- contentReady(this, function () {
- if (_this5._mask) {
- _this5._mask.addEventListener('click', _this5._cancel, false);
- util$1.iosMaskScrollFix(_this5._mask, true);
- }
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- if (this._backButtonHandler) {
- this._backButtonHandler.destroy();
- this._backButtonHandler = null;
- }
-
- if (this._mask) {
- this._mask.removeEventListener('click', this._cancel, false);
- util$1.iosMaskScrollFix(this._mask, false);
- }
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, this._scheme);
- break;
- case 'animation':
- this._animatorFactory = this._updateAnimatorFactory();
- break;
- case 'mask-color':
- this._updateMask();
- break;
- }
- }
- }, {
- key: 'onDeviceBackButton',
- get: function get$$1() {
- return this._backButtonHandler;
- },
- set: function set$$1(callback) {
- if (this._backButtonHandler) {
- this._backButtonHandler.destroy();
- }
-
- this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
- }
- }, {
- key: 'visible',
- get: function get$$1() {
- return this._visible;
- }
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
- }, {
- key: 'cancelable',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'cancelable', value);
- },
- get: function get$$1() {
- return this.hasAttribute('cancelable');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'animation', 'mask-color'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['preshow', 'postshow', 'prehide', 'posthide', 'dialog-cancel'];
- }
- }]);
- return BaseDialogElement;
- }(BaseElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme = {
- '.action-sheet': 'action-sheet--*',
- '.action-sheet-mask': 'action-sheet-mask--*',
- '.action-sheet-title': 'action-sheet-title--*'
- };
-
- var _animatorDict = {
- 'default': function _default() {
- return platform.isAndroid() ? MDActionSheetAnimator : IOSActionSheetAnimator;
- },
- 'none': ActionSheetAnimator
- };
-
- /**
- * @element ons-action-sheet
- * @category dialog
- * @description
- * [en]
- * Action/bottom sheet that is displayed on top of current screen.
- *
- * This element can either be attached directly to the `<body>` or dynamically created from a template using the `ons.createElement(template, { append: true })` utility function and the `<template>` tag.
- *
- * The action sheet is useful for displaying a list of options and asking the user to make a decision. A `ons-action-sheet-button` is provided for this purpose, although it can contain any type of content.
- *
- * It will automatically be displayed as Material Design (bottom sheet) when running on an Android device.
- * [/en]
- * [ja]
- * アクションシート、もしくはボトムシートを現在のスクリーン上に表示します。
- *
- * この要素は、`<body>`要素に直接アタッチされるか、もしくは`ons.createElement(template, { append: true })`と`<template>`タグを使ってテンプレートから動的に生成されます。
- *
- * アクションシートは、選択肢のリストを表示してユーザーに尋ねるのに便利です。`ons-action-sheet-button`は、この要素の中に置くために提供されていますが、それ以外にも他のどのような要素を含むことができます。
- *
- * Androidデバイスで実行されるときには、自動的にマテリアルデザイン(ボトムシート)として表示されます。
- * [/ja]
- * @modifier material
- * [en]Display a Material Design bottom sheet.[/en]
- * [ja]マテリアルデザインのボトムシートを表示します。[/ja]
- * @tutorial vanilla/reference/action-sheet
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @seealso ons-popover
- * [en]`<ons-popover>` component[/en]
- * [ja]ons-popoverコンポーネント[/ja]
- * @seealso ons-modal
- * [en]`<ons-modal>` component[/en]
- * [ja]ons-modalコンポーネント[/ja]
- * @example
- * <ons-action-sheet id="sheet">
- * <ons-action-sheet-button>Label</ons-action-sheet-button>
- * <ons-action-sheet-button>Label</ons-action-sheet-button>
- * </ons-action-sheet>
- *
- * <script>
- * document.getElementById('sheet').show();
- * </script>
- */
-
- var ActionSheetElement = function (_BaseDialogElement) {
- inherits(ActionSheetElement, _BaseDialogElement);
-
- /**
- * @event preshow
- * @description
- * [en]Fired just before the action sheet is displayed.[/en]
- * [ja]ダイアログが表示される直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.actionSheet
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute this function to stop the action sheet from being shown.[/en]
- * [ja]この関数を実行すると、ダイアログの表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event postshow
- * @description
- * [en]Fired just after the action sheet is displayed.[/en]
- * [ja]ダイアログが表示された直後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.actionSheet
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @event prehide
- * @description
- * [en]Fired just before the action sheet is hidden.[/en]
- * [ja]ダイアログが隠れる直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.actionSheet
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute this function to stop the action sheet from being hidden.[/en]
- * [ja]この関数を実行すると、ダイアログの非表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event posthide
- * @description
- * [en]Fired just after the action sheet is hidden.[/en]
- * [ja]ダイアログが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.actionSheet
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @attribute title
- * @type {String}
- * @description
- * [en]Optional title of the action sheet. A new element will be created containing this string.[/en]
- * [ja]アクションシートのタイトルを指定します。ここで指定した文字列を含む新しい要素が作成されます。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the action sheet.[/en]
- * [ja]ダイアログの表現を指定します。[/ja]
- */
-
- /**
- * @attribute cancelable
- * @description
- * [en]If this attribute is set the action sheet can be closed by tapping the background or by pressing the back button on Android devices.[/en]
- * [ja]この属性が設定されると、アクションシートの背景やAndroidデバイスのバックボタンを推すことでアクションシートが閉じるようになります。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]If this attribute is set the action sheet is disabled.[/en]
- * [ja]この属性がある時、ダイアログはdisabled状態になります。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]The animation used when showing and hiding the action sheet. Can be either `"none"` or `"default"`.[/en]
- * [ja]ダイアログを表示する際のアニメーション名を指定します。"none"もしくは"default"を指定できます。[/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/ja]
- */
-
- /**
- * @attribute mask-color
- * @type {String}
- * @default rgba(0, 0, 0, 0.2)
- * @description
- * [en]Color of the background mask. Default is `"rgba(0, 0, 0, 0.2)"`.[/en]
- * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
- */
-
- function ActionSheetElement() {
- classCallCheck(this, ActionSheetElement);
-
- var _this = possibleConstructorReturn(this, (ActionSheetElement.__proto__ || Object.getPrototypeOf(ActionSheetElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(ActionSheetElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- return new AnimatorFactory({
- animators: _animatorDict,
- baseClass: ActionSheetAnimator,
- baseClassName: 'ActionSheetAnimator',
- defaultAnimation: this.getAttribute('animation')
- });
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.style.display = 'none';
- this.style.zIndex = 10001;
-
- /* Expected result:
- * <ons-action-sheet>
- * <div class="action-sheet-mask"></div>
- * <div class="action-sheet">
- * <div class="action-sheet-title></div>
- * ...
- * </div>
- * </ons-action-sheet>
- */
-
- if (!this._sheet) {
- var sheet = document.createElement('div');
- sheet.classList.add('action-sheet');
-
- while (this.firstChild) {
- sheet.appendChild(this.firstChild);
- }
-
- this.appendChild(sheet);
- }
-
- if (!this._title && this.hasAttribute('title')) {
- var title = document.createElement('div');
- title.innerHTML = this.getAttribute('title');
- title.classList.add('action-sheet-title');
- this._sheet.insertBefore(title, this._sheet.firstChild);
- }
-
- if (!this._mask) {
- var mask = document.createElement('div');
- mask.classList.add('action-sheet-mask');
- this.insertBefore(mask, this.firstChild);
- }
-
- this._sheet.style.zIndex = 20001;
- this._mask.style.zIndex = 20000;
-
- ModifierUtil.initModifier(this, this._scheme);
- }
- }, {
- key: '_updateTitle',
- value: function _updateTitle() {
- if (this._title) {
- this._title.innerHTML = this.getAttribute('title');
- }
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- /**
- * @method show
- * @signature show([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
- * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定します。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
- * @param {Function} [options.callback]
- * [en]This function is called after the action sheet has been revealed.[/en]
- * [ja]ダイアログが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Show the action sheet.[/en]
- * [ja]ダイアログを開きます。[/ja]
- * @return {Promise} Resolves to the displayed element.
- */
-
- /**
- * @method hide
- * @signature hide([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
- * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定できます。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/ja]
- * @param {Function} [options.callback]
- * [en]This functions is called after the action sheet has been hidden.[/en]
- * [ja]ダイアログが隠れた後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Hide the action sheet.[/en]
- * [ja]ダイアログを閉じます。[/ja]
- * @return {Promise}
- * [en]Resolves to the hidden element[/en]
- * [ja]隠れた要素を解決します。[/ja]
- */
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the action sheet is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the action sheet is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- /**
- * @property cancelable
- * @type {Boolean}
- * @description
- * [en]Whether the action sheet is cancelable or not. A cancelable action sheet can be closed by tapping the background or by pressing the back button on Android devices.[/en]
- * [ja]アクションシートがキャンセル可能かどうかを設定します。キャンセル可能なアクションシートは、背景をタップしたりAndroidデバイスのバックボタンを推すことで閉じるようになります。[/ja]
- */
-
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'title') {
- this._updateTitle();
- } else {
- get(ActionSheetElement.prototype.__proto__ || Object.getPrototypeOf(ActionSheetElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
- }
-
- /**
- * @param {String} name
- * @param {ActionSheetAnimator} Animator
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme;
- }
- }, {
- key: '_mask',
- get: function get$$1() {
- return util$1.findChild(this, '.action-sheet-mask');
- }
- }, {
- key: '_sheet',
- get: function get$$1() {
- return util$1.findChild(this, '.action-sheet');
- }
- }, {
- key: '_title',
- get: function get$$1() {
- return this.querySelector('.action-sheet-title');
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof ActionSheetAnimator)) {
- util$1.throwAnimator('ActionSheet');
- }
- _animatorDict[name] = Animator;
- }
- }, {
- key: 'observedAttributes',
- get: function get$$1() {
- return [].concat(toConsumableArray(get(ActionSheetElement.__proto__ || Object.getPrototypeOf(ActionSheetElement), 'observedAttributes', this)), ['title']);
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict;
- }
- }, {
- key: 'ActionSheetAnimator',
- get: function get$$1() {
- return ActionSheetAnimator;
- }
- }]);
- return ActionSheetElement;
- }(BaseDialogElement);
-
- onsElements.ActionSheet = ActionSheetElement;
- customElements.define('ons-action-sheet', ActionSheetElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var BaseButtonElement = function (_BaseElement) {
- inherits(BaseButtonElement, _BaseElement);
- createClass(BaseButtonElement, [{
- key: '_scheme',
- get: function get$$1() {
- util$1.throwMember();
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- util$1.throwMember();
- }
- }, {
- key: '_rippleOpt',
- get: function get$$1() {
- return [this];
- }
- }]);
-
- function BaseButtonElement() {
- classCallCheck(this, BaseButtonElement);
-
- var _this = possibleConstructorReturn(this, (BaseButtonElement.__proto__ || Object.getPrototypeOf(BaseButtonElement)).call(this));
-
- if (_this.constructor === BaseButtonElement) {
- util$1.throwAbstract();
- }
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(BaseButtonElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.classList.add(this._defaultClassName);
-
- if (!this._icon && this.hasAttribute('icon')) {
- util$1.checkMissingImport('Icon');
- var icon = util$1.createElement('<ons-icon icon="' + this.getAttribute('icon') + '"></ons-icon>');
- icon.classList.add(this._defaultClassName.replace('button', 'icon'));
- this.insertBefore(icon, this.firstChild);
- }
-
- this._updateRipple();
-
- ModifierUtil.initModifier(this, this._scheme);
- }
- }, {
- key: '_updateIcon',
- value: function _updateIcon() {
- if (this._icon) {
- this._icon.setAttribute('icon', this.getAttribute('icon'));
- }
- }
- }, {
- key: '_updateRipple',
- value: function _updateRipple() {
- this._rippleOpt && util$1.updateRipple.apply(util$1, toConsumableArray(this._rippleOpt));
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, this._defaultClassName, this._scheme);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, this._scheme);
- break;
- case 'icon':
- this._updateIcon();
- break;
- case 'ripple':
- this.classList.contains(this._defaultClassName) && this._updateRipple();
- break;
- }
- }
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
- }, {
- key: '_icon',
- get: function get$$1() {
- return util$1.findChild(this, 'ons-icon');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class', 'icon', 'ripple'];
- }
- }]);
- return BaseButtonElement;
- }(BaseElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-action-sheet-button
- * @category dialog
- * @modifier destructive
- * [en]Shows a "destructive" button (only for iOS).[/en]
- * [ja]"destructive"なボタンを表示します(iOSでのみ有効)。[/ja]
- * @description
- * [en]Component that represent each button of the action sheet.[/en]
- * [ja]アクションシートに表示される各ボタンを表現するコンポーネントです。[/ja]
- * @seealso ons-action-sheet
- * [en]The `<ons-action-sheet>` component[/en]
- * [ja]ons-action-sheetコンポーネント[/ja]
- * @seealso ons-list-item
- * [en]The `<ons-list-item>` component[/en]
- * [ja]ons-list-itemコンポーネント[/ja]
- * @seealso ons-icon
- * [en]The `<ons-icon>` component[/en]
- * [ja]ons-iconコンポーネント[/ja]
- * @tutorial vanilla/Reference/action-sheet
- * @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
- * @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
- * @modifier material
- * [en]Display a Material Design action sheet button.[/en]
- * [ja]マテリアルデザインのアクションシート用のボタンを表示します。[/ja]
- * @example
- * <ons-action-sheet id="sheet">
- * <ons-action-sheet-button>Label</ons-action-sheet-button>
- * <ons-action-sheet-button>Label</ons-action-sheet-button>
- * </ons-action-sheet>
- *
- * <script>
- * document.getElementById('sheet').show();
- * </script>
- */
-
- var ActionSheetButtonElement = function (_BaseButtonElement) {
- inherits(ActionSheetButtonElement, _BaseButtonElement);
-
- function ActionSheetButtonElement() {
- classCallCheck(this, ActionSheetButtonElement);
- return possibleConstructorReturn(this, (ActionSheetButtonElement.__proto__ || Object.getPrototypeOf(ActionSheetButtonElement)).apply(this, arguments));
- }
-
- createClass(ActionSheetButtonElement, [{
- key: '_scheme',
-
-
- /**
- * @attribute icon
- * @type {String}
- * @description
- * [en]Creates an `ons-icon` component with this string. Only visible on Android. Check [See also](#seealso) section for more information.[/en]
- * [ja]`ons-icon`コンポーネントを悪性します。Androidでのみ表示されます。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the action sheet button.[/en]
- * [ja]アクションシートボタンの見た目を設定します。[/ja]
- */
-
- get: function get$$1() {
- return {
- '': 'action-sheet-button--*',
- '.action-sheet-icon': 'action-sheet-icon--*'
- };
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'action-sheet-button';
- }
- }, {
- key: '_rippleOpt',
- get: function get$$1() {
- return undefined;
- }
- }]);
- return ActionSheetButtonElement;
- }(BaseButtonElement);
-
- onsElements.ActionSheetButton = ActionSheetButtonElement;
- customElements.define('ons-action-sheet-button', ActionSheetButtonElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var AlertDialogAnimator = function (_BaseAnimator) {
- inherits(AlertDialogAnimator, _BaseAnimator);
-
- function AlertDialogAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, AlertDialogAnimator);
- return possibleConstructorReturn(this, (AlertDialogAnimator.__proto__ || Object.getPrototypeOf(AlertDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} dialog
- * @param {Function} done
- */
-
-
- createClass(AlertDialogAnimator, [{
- key: 'show',
- value: function show(dialog, done) {
- done();
- }
-
- /**
- * @param {HTMLElement} dialog
- * @param {Function} done
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, done) {
- done();
- }
- }]);
- return AlertDialogAnimator;
- }(BaseAnimator);
-
- /**
- * Android style animator for alert dialog.
- */
- var AndroidAlertDialogAnimator = function (_AlertDialogAnimator) {
- inherits(AndroidAlertDialogAnimator, _AlertDialogAnimator);
-
- function AndroidAlertDialogAnimator() {
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref2$timing = _ref2.timing,
- timing = _ref2$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref2$timing,
- _ref2$duration = _ref2.duration,
- duration = _ref2$duration === undefined ? 0.2 : _ref2$duration,
- _ref2$delay = _ref2.delay,
- delay = _ref2$delay === undefined ? 0 : _ref2$delay;
-
- classCallCheck(this, AndroidAlertDialogAnimator);
- return possibleConstructorReturn(this, (AndroidAlertDialogAnimator.__proto__ || Object.getPrototypeOf(AndroidAlertDialogAnimator)).call(this, { duration: duration, timing: timing, delay: delay }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(AndroidAlertDialogAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0) scale3d(.9, .9, 1)', opacity: 0 }, { transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)', opacity: 1 }).queue(function (done) {
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)', opacity: 1 }, { transform: 'translate3d(-50%, -50%, 0) scale3d(.9, .9, 1)', opacity: 0 }).queue(function (done) {
- callback();
- done();
- }));
- }
- }]);
- return AndroidAlertDialogAnimator;
- }(AlertDialogAnimator);
-
- /**
- * iOS style animator for alert dialog.
- */
- var IOSAlertDialogAnimator = function (_AlertDialogAnimator2) {
- inherits(IOSAlertDialogAnimator, _AlertDialogAnimator2);
-
- function IOSAlertDialogAnimator() {
- var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref3$timing = _ref3.timing,
- timing = _ref3$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref3$timing,
- _ref3$duration = _ref3.duration,
- duration = _ref3$duration === undefined ? 0.2 : _ref3$duration,
- _ref3$delay = _ref3.delay,
- delay = _ref3$delay === undefined ? 0 : _ref3$delay;
-
- classCallCheck(this, IOSAlertDialogAnimator);
- return possibleConstructorReturn(this, (IOSAlertDialogAnimator.__proto__ || Object.getPrototypeOf(IOSAlertDialogAnimator)).call(this, { duration: duration, timing: timing, delay: delay }));
- }
-
- /*
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(IOSAlertDialogAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0) scale3d(1.3, 1.3, 1)', opacity: 0 }, { transform: 'translate3d(-50%, -50%, 0) scale3d(1, 1, 1)', opacity: 1 }).queue(function (done) {
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ opacity: 1 }, { opacity: 0 }).queue(function (done) {
- callback();
- done();
- }));
- }
- }]);
- return IOSAlertDialogAnimator;
- }(AlertDialogAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$1 = {
- '.alert-dialog': 'alert-dialog--*',
- '.alert-dialog-container': 'alert-dialog-container--*',
- '.alert-dialog-title': 'alert-dialog-title--*',
- '.alert-dialog-content': 'alert-dialog-content--*',
- '.alert-dialog-footer': 'alert-dialog-footer--*',
- '.alert-dialog-footer--rowfooter': 'alert-dialog-footer--rowfooter--*',
- '.alert-dialog-button--rowfooter': 'alert-dialog-button--rowfooter--*',
- '.alert-dialog-button--primal': 'alert-dialog-button--primal--*',
- '.alert-dialog-button': 'alert-dialog-button--*',
- 'ons-alert-dialog-button': 'alert-dialog-button--*',
- '.alert-dialog-mask': 'alert-dialog-mask--*',
- '.text-input': 'text-input--*'
- };
-
- var _animatorDict$1 = {
- 'none': AlertDialogAnimator,
- 'default': function _default() {
- return platform.isAndroid() ? AndroidAlertDialogAnimator : IOSAlertDialogAnimator;
- },
- 'fade': function fade() {
- return platform.isAndroid() ? AndroidAlertDialogAnimator : IOSAlertDialogAnimator;
- }
- };
-
- /**
- * @element ons-alert-dialog
- * @category dialog
- * @description
- * [en]
- * Alert dialog that is displayed on top of the current screen. Useful for displaying questions, warnings or error messages to the user. The title, content and buttons can be easily customized and it will automatically switch style based on the platform.
- *
- * To use the element it can either be attached directly to the `<body>` element or dynamically created from a template using the `ons.createAlertDialog(template)` utility function and the `<template>` tag.
- * [/en]
- * [ja]
- * 現在のスクリーンの上に表示するアラートダイアログです。ユーザに対する問いかけ、警告、エラーメッセージを表示するのに利用できます。タイトルやコンテンツやボタンは簡単にカスタマイズでき、実行しているプラットフォームに併せてスタイルが自動的に切り替わります。
- * [/ja]
- * @codepen Qwwxyp
- * @tutorial vanilla/Reference/alert-dialog
- * @modifier material
- * [en]Material Design style[/en]
- * [ja]マテリアルデザインのスタイル[/ja]
- * @modifier rowfooter
- * [en]Horizontally aligns the footer buttons.[/en]
- * [ja]フッターの複数のボタンを水平に配置[/ja]
- * @seealso ons-dialog
- * [en]ons-dialog component[/en]
- * [ja]ons-dialogコンポーネント[/ja]
- * @seealso ons-popover
- * [en]ons-popover component[/en]
- * [ja]ons-dialogコンポーネント[/ja]
- * @seealso ons.notification
- * [en]Using ons.notification utility functions.[/en]
- * [ja]アラートダイアログを表示するには、ons.notificationオブジェクトのメソッドを使うこともできます。[/ja]
- * @example
- * <ons-alert-dialog id="alert-dialog">
- * <div class="alert-dialog-title">Warning!</div>
- * <div class="alert-dialog-content">
- * An error has occurred!
- * </div>
- * <div class="alert-dialog-footer">
- * <button id="alert-dialog-button" class="alert-dialog-button">OK</button>
- * </div>
- * </ons-alert-dialog>
- * <script>
- * document.getElementById('alert-dialog').show();
- * </script>
- */
-
- var AlertDialogElement = function (_BaseDialogElement) {
- inherits(AlertDialogElement, _BaseDialogElement);
-
- /**
- * @event preshow
- * @description
- * [en]Fired just before the alert dialog is displayed.[/en]
- * [ja]アラートダイアログが表示される直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.alertDialog
- * [en]Alert dialog object.[/en]
- * [ja]アラートダイアログのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute to stop the dialog from showing.[/en]
- * [ja]この関数を実行すると、アラートダイアログの表示を止めます。[/ja]
- */
-
- /**
- * @event postshow
- * @description
- * [en]Fired just after the alert dialog is displayed.[/en]
- * [ja]アラートダイアログが表示された直後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.alertDialog
- * [en]Alert dialog object.[/en]
- * [ja]アラートダイアログのオブジェクト。[/ja]
- */
-
- /**
- * @event prehide
- * @description
- * [en]Fired just before the alert dialog is hidden.[/en]
- * [ja]アラートダイアログが隠れる直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.alertDialog
- * [en]Alert dialog object.[/en]
- * [ja]アラートダイアログのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute to stop the dialog from hiding.[/en]
- * [ja]この関数を実行すると、アラートダイアログが閉じようとするのを止めます。[/ja]
- */
-
- /**
- * @event posthide
- * @description
- * [en]Fired just after the alert dialog is hidden.[/en]
- * [ja]アラートダイアログが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.alertDialog
- * [en]Alert dialog object.[/en]
- * [ja]アラートダイアログのオブジェクト。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the dialog.[/en]
- * [ja]ダイアログの見た目を指定します。[/ja]
- */
-
- /**
- * @attribute cancelable
- * @description
- * [en]If this attribute is set the dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
- * [ja]この属性を設定すると、ダイアログの背景をタップしたりAndroidデバイスのバックボタンを押すとダイアログが閉じるようになります。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]If this attribute is set the dialog is disabled.[/en]
- * [ja]この属性がある時、アラートダイアログはdisabled状態になります。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]The animation used when showing and hiding the dialog. Can be either `"none"` or `"default"`.[/en]
- * [ja]ダイアログを表示する際のアニメーション名を指定します。デフォルトでは"none"か"default"が指定できます。[/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。例:{duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
- */
-
- /**
- * @attribute mask-color
- * @type {String}
- * @default rgba(0, 0, 0, 0.2)
- * @description
- * [en]Color of the background mask. Default is "rgba(0, 0, 0, 0.2)".[/en]
- * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
- */
-
- function AlertDialogElement() {
- classCallCheck(this, AlertDialogElement);
-
- var _this = possibleConstructorReturn(this, (AlertDialogElement.__proto__ || Object.getPrototypeOf(AlertDialogElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(AlertDialogElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- return new AnimatorFactory({
- animators: _animatorDict$1,
- baseClass: AlertDialogAnimator,
- baseClassName: 'AlertDialogAnimator',
- defaultAnimation: this.getAttribute('animation')
- });
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.style.display = 'none';
- this.style.zIndex = 10001;
-
- /**
- * Expected result after compile:
- *
- * <ons-alert-dialog style="none">
- * <div class="alert-dialog-mask"></div>
- * <div class="alert-dialog">
- * <div class="alert-dialog-container">...</div>
- * </div>
- * </ons-alert-dialog>
- */
-
- var content = document.createDocumentFragment();
-
- if (!this._mask && !this._dialog) {
- while (this.firstChild) {
- content.appendChild(this.firstChild);
- }
- }
-
- if (!this._mask) {
- var mask = document.createElement('div');
- mask.classList.add('alert-dialog-mask');
- this.insertBefore(mask, this.children[0]);
- }
-
- if (!this._dialog) {
- var dialog = document.createElement('div');
- dialog.classList.add('alert-dialog');
- this.insertBefore(dialog, null);
- }
-
- if (!util$1.findChild(this._dialog, '.alert-dialog-container')) {
- var container = document.createElement('div');
- container.classList.add('alert-dialog-container');
- this._dialog.appendChild(container);
- }
-
- this._dialog.children[0].appendChild(content);
-
- this._dialog.style.zIndex = 20001;
- this._mask.style.zIndex = 20000;
-
- ModifierUtil.initModifier(this, this._scheme);
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- /**
- * @property cancelable
- * @type {Boolean}
- * @description
- * [en]Whether the dialog is cancelable or not. A cancelable dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
- * [ja]そのダイアログがキャンセル可能かどうかを表します。キャンセル可能なダイアログは、背景をタップするかAndroidデバイスのバックボタンを押すことで閉じることが出来るようになります。[/ja]
- */
-
- /**
- * @method show
- * @signature show([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクトです。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"fade"` and `"none"`.[/en]
- * [ja]アニメーション名を指定します。指定できるのは、"fade", "none"のいずれかです。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. <code>{duration: 0.2, delay: 0.4, timing: 'ease-in'}</code> [/ja]
- * @param {Function} [options.callback]
- * [en]Function to execute after the dialog has been revealed.[/en]
- * [ja]ダイアログが表示され終わった時に呼び出されるコールバックを指定します。[/ja]
- * @description
- * [en]Show the alert dialog.[/en]
- * [ja]ダイアログを表示します。[/ja]
- * @return {Promise}
- * [en]A `Promise` object that resolves to the displayed element.[/en]
- * [ja]表示される要素を解決する`Promise`オブジェクトを返します。[/ja]
- */
-
- /**
- * @method hide
- * @signature hide([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"fade"` and `"none"`.[/en]
- * [ja]アニメーション名を指定します。"fade", "none"のいずれかを指定します。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. <code>{duration: 0.2, delay: 0.4, timing: 'ease-in'}</code>[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. <code>{duration: 0.2, delay: 0.4, timing: 'ease-in'}</code> [/ja]
- * @param {Function} [options.callback]
- * [en]Function to execute after the dialog has been hidden.[/en]
- * [ja]このダイアログが閉じた時に呼び出されるコールバックを指定します。[/ja]
- * @description
- * [en]Hide the alert dialog.[/en]
- * [ja]ダイアログを閉じます。[/ja]
- * @return {Promise}
- * [en]Resolves to the hidden element[/en]
- * [ja]隠れた要素を解決する`Promise`オブジェクトを返します。[/ja]
- */
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the dialog is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- /**
- * @param {String} name
- * @param {DialogAnimator} Animator
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$1;
- }
-
- /**
- * @return {Element}
- */
-
- }, {
- key: '_mask',
- get: function get$$1() {
- return util$1.findChild(this, '.alert-dialog-mask');
- }
-
- /**
- * @return {Element}
- */
-
- }, {
- key: '_dialog',
- get: function get$$1() {
- return util$1.findChild(this, '.alert-dialog');
- }
-
- /**
- * @return {Element}
- */
-
- }, {
- key: '_titleElement',
- get: function get$$1() {
- return util$1.findChild(this._dialog.children[0], '.alert-dialog-title');
- }
-
- /**
- * @return {Element}
- */
-
- }, {
- key: '_contentElement',
- get: function get$$1() {
- return util$1.findChild(this._dialog.children[0], '.alert-dialog-content');
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof AlertDialogAnimator)) {
- util$1.throwAnimator('AlertDialog');
- }
- _animatorDict$1[name] = Animator;
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$1;
- }
- }, {
- key: 'AlertDialogAnimator',
- get: function get$$1() {
- return AlertDialogAnimator;
- }
- }]);
- return AlertDialogElement;
- }(BaseDialogElement);
-
- onsElements.AlertDialog = AlertDialogElement;
- customElements.define('ons-alert-dialog', AlertDialogElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-alert-dialog-button
- * @modifier material
- * [en]Material Design alert-dialog button.[/en]
- * [ja]マテリアルデザインのボタンを表示します。[/ja]
- * @description
- * [en][/en]
- * [ja][/ja]
- * @seealso ons-alert-dialog
- * [en]The `<ons-alert-dialog>` component displays a alert dialog.[/en]
- * [ja]ons-alert-dialogコンポーネント[/ja]
- * @example
- * <ons-alert-dialog>
- * <div class="alert-dialog-title">Warning!</div>
- * <div class="alert-dialog-content">
- * An error has occurred!
- * </div>
- * <div class="alert-dialog-footer">
- * <alert-dialog-button onclick="app.close()">Cancel</alert-dialog-button>
- * <alert-dialog-button class="alert-dialog-button" onclick="app.close()">OK</alert-dialog-button>
- * </div>
- * </ons-alert-dialog>
- */
-
- var AlertDialogButtonElement = function (_BaseButtonElement) {
- inherits(AlertDialogButtonElement, _BaseButtonElement);
-
- function AlertDialogButtonElement() {
- classCallCheck(this, AlertDialogButtonElement);
- return possibleConstructorReturn(this, (AlertDialogButtonElement.__proto__ || Object.getPrototypeOf(AlertDialogButtonElement)).apply(this, arguments));
- }
-
- createClass(AlertDialogButtonElement, [{
- key: '_scheme',
-
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the button.[/en]
- * [ja]ボタンの表現を指定します。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Specify if button should be disabled.[/en]
- * [ja]ボタンを無効化する場合は指定してください。[/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- get: function get$$1() {
- return { '': 'alert-dialog-button--*' };
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'alert-dialog-button';
- }
- }, {
- key: '_rippleOpt',
- get: function get$$1() {
- return [this, undefined, { 'modifier': 'light-gray' }];
- }
- }]);
- return AlertDialogButtonElement;
- }(BaseButtonElement);
-
- onsElements.AlertDialogButton = AlertDialogButtonElement;
- customElements.define('ons-alert-dialog-button', AlertDialogButtonElement);
-
- var iosBackButtonIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"13px\" height=\"21px\" viewBox=\"0 0 13 21\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <title>ios-back-button-icon</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"toolbar-back-button\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <g id=\"ios\" transform=\"translate(-34.000000, -30.000000)\">\n <polygon id=\"ios-back-button-icon\" points=\"34 40.5 44.5 30 46.5 32 38 40.5 46.5 49 44.5 51\"></polygon>\n </g>\n </g>\n</svg>\n";
-
- var mdBackButtonIcon = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"16px\" height=\"16px\" viewBox=\"0 0 16 16\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <title>md-back-button-icon</title>\n <desc>Created with Sketch.</desc>\n <defs></defs>\n <g id=\"toolbar-back-button\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\n <g id=\"android\" transform=\"translate(-32.000000, -32.000000)\" fill-rule=\"nonzero\">\n <polygon id=\"md-back-button-icon\" points=\"48 39 35.83 39 41.42 33.41 40 32 32 40 40 48 41.41 46.59 35.83 41 48 41\"></polygon>\n </g>\n </g>\n</svg>\n";
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName = 'back-button';
-
- var scheme$2 = {
- '': 'back-button--*',
- '.back-button__icon': 'back-button--*__icon',
- '.back-button__label': 'back-button--*__label'
- };
-
- /**
- * @element ons-back-button
- * @category navigation
- * @description
- * [en]
- * Back button component for `<ons-toolbar>`. Put it in the left part of the `<ons-toolbar>`.
- *
- * It will find the parent `<ons-navigator>` element and pop a page when clicked. This behavior can be overriden by specifying the `onClick` property.
- * [/en]
- * [ja][/ja]
- * @codepen aHmGL
- * @tutorial vanilla/Reference/back-button
- * @modifier material
- * [en]Material Design style[/en]
- * [ja][/ja]
- * @seealso ons-toolbar
- * [en]ons-toolbar component[/en]
- * [ja]ons-toolbarコンポーネント[/ja]
- * @seealso ons-navigator
- * [en]ons-navigator component[/en]
- * [ja]ons-navigatorコンポーネント[/ja]
- * @example
- * <ons-toolbar>
- * <div class="left">
- * <ons-back-button>Back</ons-back-button>
- * </div>
- * <div class="center">
- * Title
- * <div>
- * </ons-toolbar>
- */
-
- var BackButtonElement = function (_BaseElement) {
- inherits(BackButtonElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the back button.[/en]
- * [ja]バックボタンの見た目を指定します。[/ja]
- */
-
- function BackButtonElement() {
- classCallCheck(this, BackButtonElement);
-
- var _this = possibleConstructorReturn(this, (BackButtonElement.__proto__ || Object.getPrototypeOf(BackButtonElement)).call(this));
-
- contentReady(_this, function () {
- _this._compile();
- });
-
- _this._options = {};
- _this._boundOnClick = _this._onClick.bind(_this);
- return _this;
- }
-
- createClass(BackButtonElement, [{
- key: '_updateIcon',
- value: function _updateIcon() {
- var icon = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : util$1.findChild(this, '.back-button__icon');
-
- icon.innerHTML = autoStyle.getPlatform(this) === 'android' || util$1.hasModifier(this, 'material') ? mdBackButtonIcon : iosBackButtonIcon;
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.classList.add(defaultClassName);
-
- if (!util$1.findChild(this, '.back-button__label')) {
- var label = util$1.create('span.back-button__label');
-
- while (this.childNodes[0]) {
- label.appendChild(this.childNodes[0]);
- }
- this.appendChild(label);
- }
-
- if (!util$1.findChild(this, '.back-button__icon')) {
- var icon = util$1.create('span.back-button__icon');
- this._updateIcon(icon);
-
- this.insertBefore(icon, this.children[0]);
- }
-
- util$1.updateRipple(this, undefined, { center: '', 'size': 'contain', 'background': 'transparent' });
-
- ModifierUtil.initModifier(this, scheme$2);
- }
-
- /**
- * @property options
- * @type {Object}
- * @description
- * [en]Options object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- */
-
- /**
- * @property options.animation
- * @type {String}
- * @description
- * [en]Animation name. Available animations are "slide", "lift", "fade" and "none".
- * These are platform based animations. For fixed animations, add "-ios" or "-md"
- * suffix to the animation name. E.g. "lift-ios", "lift-md". Defaults values are "slide-ios" and "fade-md".
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @property options.animationOptions
- * @type {String}
- * @description
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
- */
-
- /**
- * @property options.callback
- * @type {String}
- * @description
- * [en]Function that is called when the transition has ended.[/en]
- * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
- */
-
- }, {
- key: '_onClick',
-
-
- /**
- * @property onClick
- * @type {Function}
- * @description
- * [en]Used to override the default back button behavior.[/en]
- * [ja][/ja]
- */
- value: function _onClick() {
- if (this.onClick) {
- this.onClick.apply(this);
- } else {
- var navigator = util$1.findParent(this, 'ons-navigator');
- if (navigator) {
- navigator.popPage(this.options);
- }
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this.addEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName, scheme$2);
- break;
-
- case 'modifier':
- {
- ModifierUtil.onModifierChanged(last, current, this, scheme$2) && this._updateIcon();
- break;
- }
- }
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this.removeEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: 'show',
- value: function show() {
- this.style.display = 'inline-block';
- }
- }, {
- key: 'hide',
- value: function hide() {
- this.style.display = 'none';
- }
- }, {
- key: 'options',
- get: function get$$1() {
- return this._options;
- },
- set: function set$$1(object) {
- this._options = object;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return BackButtonElement;
- }(BaseElement);
-
- onsElements.BackButton = BackButtonElement;
- customElements.define('ons-back-button', BackButtonElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$1 = 'bottom-bar';
- var scheme$3 = { '': 'bottom-bar--*' };
-
- /**
- * @element ons-bottom-toolbar
- * @category page
- * @description
- * [en]Toolbar component that is positioned at the bottom of the page. Since bottom toolbars are very versatile elements, `ons-bottom-toolbar` does not provide any specific layout syntax for its children. Modifiers or custom CSS must be used.[/en]
- * [ja]ページ下部に配置されるツールバー用コンポーネントです。[/ja]
- * @modifier transparent
- * [en]Make the toolbar transparent.[/en]
- * [ja]ツールバーの背景を透明にして表示します。[/ja]
- * @modifier aligned
- * [en]Vertically aligns its children and applies flexbox for block elements. `justify-content` CSS rule can be used to change horizontal align.[/en]
- * [ja]ツールバーの背景を透明にして表示します。[/ja]
- * @seealso ons-toolbar [en]ons-toolbar component[/en][ja]ons-toolbarコンポーネント[/ja]
- * @example
- * <ons-bottom-toolbar>
- * Content
- * </ons-bottom-toolbar>
- */
-
- var BottomToolbarElement = function (_BaseElement) {
- inherits(BottomToolbarElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the toolbar.[/en]
- * [ja]ツールバーの見た目の表現を指定します。[/ja]
- */
-
- function BottomToolbarElement() {
- classCallCheck(this, BottomToolbarElement);
-
- var _this = possibleConstructorReturn(this, (BottomToolbarElement.__proto__ || Object.getPrototypeOf(BottomToolbarElement)).call(this));
-
- _this.classList.add(defaultClassName$1);
- ModifierUtil.initModifier(_this, scheme$3);
- return _this;
- }
-
- createClass(BottomToolbarElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$1, scheme$3);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$3);
- break;
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return BottomToolbarElement;
- }(BaseElement);
-
- onsElements.BottomToolbar = BottomToolbarElement;
- customElements.define('ons-bottom-toolbar', BottomToolbarElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-button
- * @category form
- * @modifier outline
- * [en]Button with outline and transparent background[/en]
- * [ja]アウトラインを持ったボタンを表示します。[/ja]
- * @modifier light
- * [en]Button that doesn't stand out.[/en]
- * [ja]目立たないボタンを表示します。[/ja]
- * @modifier quiet
- * [en]Button with no outline and or background..[/en]
- * [ja]枠線や背景が無い文字だけのボタンを表示します。[/ja]
- * @modifier cta
- * [en]Button that really stands out.[/en]
- * [ja]目立つボタンを表示します。[/ja]
- * @modifier large
- * [en]Large button that covers the width of the screen.[/en]
- * [ja]横いっぱいに広がる大きなボタンを表示します。[/ja]
- * @modifier large--quiet
- * [en]Large quiet button.[/en]
- * [ja]横いっぱいに広がるquietボタンを表示します。[/ja]
- * @modifier large--cta
- * [en]Large call to action button.[/en]
- * [ja]横いっぱいに広がるctaボタンを表示します。[/ja]
- * @modifier material
- * [en]Material Design button[/en]
- * [ja]マテリアルデザインのボタン[/ja]
- * @modifier material--flat
- * [en]Material Design flat button[/en]
- * [ja]マテリアルデザインのフラットボタン[/ja]
- * @description
- * [en]
- * Button component. If you want to place a button in a toolbar, use `<ons-toolbar-button>` or `<ons-back-button>` instead.
- *
- * Will automatically display as a Material Design button with a ripple effect on Android.
- * [/en]
- * [ja]ボタン用コンポーネント。ツールバーにボタンを設置する場合は、ons-toolbar-buttonもしくはons-back-buttonコンポーネントを使用します。[/ja]
- * @codepen hLayx
- * @tutorial vanilla/Reference/button
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
- * @example
- * <ons-button modifier="large--cta">
- * Tap Me
- * </ons-button>
- */
-
- var ButtonElement = function (_BaseButtonElement) {
- inherits(ButtonElement, _BaseButtonElement);
-
- function ButtonElement() {
- classCallCheck(this, ButtonElement);
- return possibleConstructorReturn(this, (ButtonElement.__proto__ || Object.getPrototypeOf(ButtonElement)).apply(this, arguments));
- }
-
- createClass(ButtonElement, [{
- key: '_scheme',
-
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the button.[/en]
- * [ja]ボタンの表現を指定します。[/ja]
- */
-
- /**
- * @attribute ripple
- * @description
- * [en]If this attribute is defined, the button will have a ripple effect.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Specify if button should be disabled.[/en]
- * [ja]ボタンを無効化する場合は指定します。[/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the button is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- get: function get$$1() {
- return { '': 'button--*' };
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'button';
- }
- }]);
- return ButtonElement;
- }(BaseButtonElement);
-
- onsElements.Button = ButtonElement;
- customElements.define('ons-button', ButtonElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$2 = 'card';
- var scheme$4 = {
- '': 'card--*',
- '.card__title': 'card--*__title',
- '.card__content': 'card--*__content'
- };
-
- /**
- * @element ons-card
- * @category visual
- * @modifier material
- * [en]A card with material design.[/en]
- * [ja]リストの上下のボーダーが無いリストを表示します。[/ja]
- * @description
- * [en]
- * Component to create a card that displays some information.
- *
- * The card may be composed by divs with specially prepared classes `title` and/or `content`. You can also add your own content as you please.[/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/card
- * @example
- * <ons-card>
- * <p>Some content</p>
- * </ons-card>
- */
-
- var CardElement = function (_BaseElement) {
- inherits(CardElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the card.[/en]
- * [ja]リストの表現を指定します。[/ja]
- */
-
- function CardElement() {
- classCallCheck(this, CardElement);
-
- var _this = possibleConstructorReturn(this, (CardElement.__proto__ || Object.getPrototypeOf(CardElement)).call(this));
-
- contentReady(_this, function () {
- _this._compile();
- });
- return _this;
- }
-
- createClass(CardElement, [{
- key: '_compile',
- value: function _compile() {
- for (var i = 0; i < this.children.length; i++) {
- var el = this.children[i];
-
- if (el.classList.contains('title')) {
- el.classList.add('card__title');
-
- } else if (el.classList.contains('content')) {
- el.classList.add('card__content');
-
- }
- }
-
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$2);
- ModifierUtil.initModifier(this, scheme$4);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$2, scheme$4);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$4);
- break;
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return CardElement;
- }(BaseElement);
-
- onsElements.Card = CardElement;
- customElements.define('ons-card', CardElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$5 = { '': 'carousel-item--*' };
-
- /**
- * @element ons-carousel-item
- * @category carousel
- * @description
- * [en]
- * Carousel item component. Used as a child of the `<ons-carousel>` element.
- * [/en]
- * [ja][/ja]
- * @codepen xbbzOQ
- * @tutorial vanilla/Reference/carousel
- * @seealso ons-carousel
- * [en]`<ons-carousel>` components[/en]
- * [ja]<ons-carousel>コンポーネント[/ja]
- * @example
- * <ons-carousel style="width: 100%; height: 200px">
- * <ons-carousel-item>
- * ...
- * </ons-carousel-item>
- * <ons-carousel-item>
- * ...
- * </ons-carousel-item>
- * </ons-carousel>
- */
-
- var CarouselItemElement = function (_BaseElement) {
- inherits(CarouselItemElement, _BaseElement);
-
- function CarouselItemElement() {
- classCallCheck(this, CarouselItemElement);
-
- var _this = possibleConstructorReturn(this, (CarouselItemElement.__proto__ || Object.getPrototypeOf(CarouselItemElement)).call(this));
-
- _this.style.width = '100%';
- ModifierUtil.initModifier(_this, scheme$5);
- return _this;
- }
-
- createClass(CarouselItemElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'modifier') {
- return ModifierUtil.onModifierChanged(last, current, this, scheme$5);
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier'];
- }
- }]);
- return CarouselItemElement;
- }(BaseElement);
-
- onsElements.CarouselItem = CarouselItemElement;
- customElements.define('ons-carousel-item', CarouselItemElement);
-
- var directionMap = {
- vertical: {
- axis: 'Y',
- size: 'Height',
- dir: ['up', 'down'],
- t3d: ['0px, ', 'px, 0px']
- },
- horizontal: {
- axis: 'X',
- size: 'Width',
- dir: ['left', 'right'],
- t3d: ['', 'px, 0px, 0px']
- }
- };
-
- var Swiper = function () {
- function Swiper(params) {
- var _this = this;
-
- classCallCheck(this, Swiper);
-
- // Parameters
- var FALSE = function FALSE() {
- return false;
- };
- 'getInitialIndex getBubbleWidth isVertical isOverScrollable isCentered\n isAutoScrollable refreshHook preChangeHook postChangeHook overScrollHook'.split(/\s+/).forEach(function (key) {
- return _this[key] = params[key] || FALSE;
- });
-
- this.getElement = params.getElement; // Required
- this.scrollHook = params.scrollHook; // Optional
- this.itemSize = params.itemSize || '100%';
-
- this.getAutoScrollRatio = function () {
- var ratio = params.getAutoScrollRatio && params.getAutoScrollRatio.apply(params, arguments);
- ratio = typeof ratio === 'number' && ratio === ratio ? ratio : .5;
- if (ratio < 0.0 || ratio > 1.0) {
- util$1.throw('Invalid auto-scroll-ratio ' + ratio + '. Must be between 0 and 1');
- }
- return ratio;
- };
-
- // Prevent clicks only on desktop
- this.shouldBlock = util$1.globals.actualMobileOS === 'other';
-
- // Bind handlers
- this.onDragStart = this.onDragStart.bind(this);
- this.onDrag = this.onDrag.bind(this);
- this.onDragEnd = this.onDragEnd.bind(this);
- this.onResize = this.onResize.bind(this);
-
- this._shouldFixScroll = util$1.globals.actualMobileOS === 'ios';
- }
-
- createClass(Swiper, [{
- key: 'init',
- value: function init() {
- var _this2 = this;
-
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- swipeable = _ref.swipeable,
- autoRefresh = _ref.autoRefresh;
-
- this.initialized = true;
- this.target = this.getElement().children[0];
- this.blocker = this.getElement().children[1];
- if (!this.target || !this.blocker) {
- util$1.throw('Expected "target" and "blocker" elements to exist before initializing Swiper');
- }
-
- if (!this.shouldBlock) {
- this.blocker.style.display = 'none';
- }
-
- // Add classes
- this.getElement().classList.add('ons-swiper');
- this.target.classList.add('ons-swiper-target');
- this.blocker.classList.add('ons-swiper-blocker');
-
- // Setup listeners
- this._gestureDetector = new GestureDetector(this.getElement(), { dragMinDistance: 1, dragLockToAxis: true, passive: !this._shouldFixScroll });
- this._mutationObserver = new MutationObserver(function () {
- return _this2.refresh();
- });
- this.updateSwipeable(swipeable);
- this.updateAutoRefresh(autoRefresh);
-
- // Setup initial layout
- this._scroll = this._offset = this._lastActiveIndex = 0;
- this._updateLayout();
- this._setupInitialIndex();
- setImmediate(function () {
- return _this2.initialized && _this2._setupInitialIndex();
- });
-
- // Fix rendering glitch on Android 4.1
- // Fix for iframes where the width is inconsistent at the beginning
- if (window !== window.parent || this.offsetHeight === 0) {
- window.requestAnimationFrame(function () {
- return _this2.initialized && _this2.onResize();
- });
- }
- }
- }, {
- key: 'dispose',
- value: function dispose() {
- this.initialized = false;
- this.updateSwipeable(false);
- this.updateAutoRefresh(false);
-
- this._gestureDetector && this._gestureDetector.dispose();
- this.target = this.blocker = this._gestureDetector = this._mutationObserver = null;
-
- this.setupResize(false);
- }
- }, {
- key: 'onResize',
- value: function onResize() {
- var i = this._scroll / this.targetSize;
- this._reset();
- this.setActiveIndex(i);
- this.refresh();
- }
- }, {
- key: '_calculateItemSize',
- value: function _calculateItemSize() {
- var matches = this.itemSize.match(/^(\d+)(px|%)/);
-
- if (!matches) {
- util$1.throw('Invalid state: swiper\'s size unit must be \'%\' or \'px\'');
- }
-
- var value = parseInt(matches[1], 10);
- return matches[2] === '%' ? Math.round(value / 100 * this.targetSize) : value;
- }
- }, {
- key: '_setupInitialIndex',
- value: function _setupInitialIndex() {
- this._reset();
- this._lastActiveIndex = Math.max(Math.min(Number(this.getInitialIndex()), this.itemCount), 0);
- this._scroll = this._offset + this.itemNumSize * this._lastActiveIndex;
- this._scrollTo(this._scroll);
- }
- }, {
- key: '_setSwiping',
- value: function _setSwiping(toggle) {
- this.target.classList.toggle('swiping', toggle); // Hides everything except shown pages
- }
- }, {
- key: 'setActiveIndex',
- value: function setActiveIndex(index) {
- var _this3 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- this._setSwiping(true);
- index = Math.max(0, Math.min(index, this.itemCount - 1));
- var scroll = Math.max(0, Math.min(this.maxScroll, this._offset + this.itemNumSize * index));
-
- if (platform.isUIWebView()) {
- /* Dirty fix for #2231(https://github.com/OnsenUI/OnsenUI/issues/2231). begin */
- var concat = function concat(arrayOfArray) {
- return Array.prototype.concat.apply([], arrayOfArray);
- };
- var contents = concat(util$1.arrayFrom(this.target.children).map(function (page) {
- return util$1.arrayFrom(page.children).filter(function (child) {
- return child.classList.contains('page__content');
- });
- }));
-
- var map = new Map();
- return new Promise(function (resolve) {
- contents.forEach(function (content) {
- map.set(content, content.getAttribute('class'));
- content.classList.add('page__content--suppress-layer-creation');
- });
- requestAnimationFrame(resolve);
- }).then(function () {
- return _this3._changeTo(scroll, options);
- }).then(function () {
- return new Promise(function (resolve) {
- contents.forEach(function (content) {
- content.setAttribute('class', map.get(content));
- });
- requestAnimationFrame(resolve);
- });
- });
- /* end */
- } else {
- return this._changeTo(scroll, options);
- }
- }
- }, {
- key: 'getActiveIndex',
- value: function getActiveIndex() {
- var scroll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._scroll;
-
- scroll -= this._offset;
- var count = this.itemCount,
- size = this.itemNumSize;
-
- if (this.itemNumSize === 0 || !util$1.isInteger(scroll)) {
- return this._lastActiveIndex;
- }
-
- if (scroll <= 0) {
- return 0;
- }
-
- for (var i = 0; i < count; i++) {
- if (size * i <= scroll && size * (i + 1) > scroll) {
- return i;
- }
- }
-
- return count - 1;
- }
- }, {
- key: 'setupResize',
- value: function setupResize(add) {
- window[(add ? 'add' : 'remove') + 'EventListener']('resize', this.onResize, true);
- }
- }, {
- key: 'show',
- value: function show() {
- var _this4 = this;
-
- this.setupResize(true);
- this.onResize();
- setTimeout(function () {
- return _this4.target && _this4.target.classList.add('active');
- }, 1000 / 60); // Hide elements after animations
- }
- }, {
- key: 'hide',
- value: function hide() {
- this.setupResize(false);
- this.target.classList.remove('active'); // Show elements before animations
- }
- }, {
- key: 'updateSwipeable',
- value: function updateSwipeable(shouldUpdate) {
- if (this._gestureDetector) {
- var action = shouldUpdate ? 'on' : 'off';
- this._gestureDetector[action]('drag', this.onDrag);
- this._gestureDetector[action]('dragstart', this.onDragStart);
- this._gestureDetector[action]('dragend', this.onDragEnd);
- }
- }
- }, {
- key: 'updateAutoRefresh',
- value: function updateAutoRefresh(shouldWatch) {
- if (this._mutationObserver) {
- shouldWatch ? this._mutationObserver.observe(this.target, { childList: true }) : this._mutationObserver.disconnect();
- }
- }
- }, {
- key: 'updateItemSize',
- value: function updateItemSize(newSize) {
- this.itemSize = newSize || '100%';
- this.refresh();
- }
- }, {
- key: 'toggleBlocker',
- value: function toggleBlocker(block) {
- this.blocker.style.pointerEvents = block ? 'auto' : 'none';
- }
- }, {
- key: '_canConsumeGesture',
- value: function _canConsumeGesture(gesture) {
- var d = gesture.direction;
- var isFirst = this._scroll === 0 && !this.isOverScrollable();
- var isLast = this._scroll === this.maxScroll && !this.isOverScrollable();
-
- return this.isVertical() ? d === 'down' && !isFirst || d === 'up' && !isLast : d === 'right' && !isFirst || d === 'left' && !isLast;
- }
- }, {
- key: 'onDragStart',
- value: function onDragStart(event) {
- var _this5 = this;
-
- this._ignoreDrag = event.consumed || !util$1.isValidGesture(event);
-
- if (!this._ignoreDrag) {
- var consume = event.consume;
- event.consume = function () {
- consume && consume();_this5._ignoreDrag = true;
- };
-
- if (this._canConsumeGesture(event.gesture)) {
- var startX = event.gesture.center && event.gesture.center.clientX || 0,
- distFromEdge = this.getBubbleWidth() || 0,
- start = function start() {
- consume && consume();
- event.consumed = true;
- _this5._started = true; // Avoid starting drag from outside
- _this5.shouldBlock && _this5.toggleBlocker(true);
- _this5._setSwiping(true);
- util$1.iosPreventScroll(_this5._gestureDetector);
- };
-
- // Let parent elements consume the gesture or consume it right away
- startX < distFromEdge || startX > this.targetSize - distFromEdge ? setImmediate(function () {
- return !_this5._ignoreDrag && start();
- }) : start();
- }
- }
- }
- }, {
- key: 'onDrag',
- value: function onDrag(event) {
- if (!event.gesture || this._ignoreDrag || !this._started) {
- return;
- }
-
- this._continued = true; // Fix for random 'dragend' without 'drag'
- event.stopPropagation();
-
- this._scrollTo(this._scroll - this._getDelta(event), { throttle: true });
- }
- }, {
- key: 'onDragEnd',
- value: function onDragEnd(event) {
- this._started = false;
- if (!event.gesture || this._ignoreDrag || !this._continued) {
- this._ignoreDrag = true; // onDragEnd might fire before onDragStart's setImmediate
- return;
- }
-
- this._continued = false;
- event.stopPropagation();
-
- var scroll = this._scroll - this._getDelta(event);
- var normalizedScroll = this._normalizeScroll(scroll);
- scroll === normalizedScroll ? this._startMomentumScroll(scroll, event) : this._killOverScroll(normalizedScroll);
- this.shouldBlock && this.toggleBlocker(false);
- }
- }, {
- key: '_startMomentumScroll',
- value: function _startMomentumScroll(scroll, event) {
- var velocity = this._getVelocity(event),
- matchesDirection = event.gesture.interimDirection === this.dM.dir[this._getDelta(event) < 0 ? 0 : 1];
-
- var nextScroll = this._getAutoScroll(scroll, velocity, matchesDirection);
- var duration = Math.abs(nextScroll - scroll) / (velocity + 0.01) / 1000;
- duration = Math.min(.25, Math.max(.1, duration));
-
- this._changeTo(nextScroll, { swipe: true, animationOptions: { duration: duration, timing: 'cubic-bezier(.4, .7, .5, 1)' } });
- }
- }, {
- key: '_killOverScroll',
- value: function _killOverScroll(scroll) {
- var _this6 = this;
-
- this._scroll = scroll;
- var direction = this.dM.dir[Number(scroll > 0)];
- var killOverScroll = function killOverScroll() {
- return _this6._changeTo(scroll, { animationOptions: { duration: .4, timing: 'cubic-bezier(.1, .4, .1, 1)' } });
- };
- this.overScrollHook({ direction: direction, killOverScroll: killOverScroll }) || killOverScroll();
- }
- }, {
- key: '_changeTo',
- value: function _changeTo(scroll) {
- var _this7 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var e = { activeIndex: this.getActiveIndex(scroll), lastActiveIndex: this._lastActiveIndex, swipe: options.swipe || false };
- var change = e.activeIndex !== e.lastActiveIndex;
- var canceled = change ? this.preChangeHook(e) : false;
-
- this._scroll = canceled ? this._offset + e.lastActiveIndex * this.itemNumSize : scroll;
- this._lastActiveIndex = canceled ? e.lastActiveIndex : e.activeIndex;
-
- return this._scrollTo(this._scroll, options).then(function () {
- if (scroll === _this7._scroll && !canceled) {
- _this7._setSwiping(false);
- change && _this7.postChangeHook(e);
- } else if (options.reject) {
- _this7._setSwiping(false);
- return Promise.reject('Canceled');
- }
- });
- }
- }, {
- key: '_scrollTo',
- value: function _scrollTo(scroll) {
- var _this8 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (options.throttle) {
- var ratio = 0.35;
- if (scroll < 0) {
- scroll = this.isOverScrollable() ? Math.round(scroll * ratio) : 0;
- } else {
- var maxScroll = this.maxScroll;
- if (maxScroll < scroll) {
- scroll = this.isOverScrollable() ? maxScroll + Math.round((scroll - maxScroll) * ratio) : maxScroll;
- }
- }
- }
-
- var opt = options.animation === 'none' ? {} : options.animationOptions;
- this.scrollHook && this.itemNumSize > 0 && this.scrollHook((scroll / this.itemNumSize).toFixed(2), options.animationOptions || {});
-
- return new Promise(function (resolve) {
- return Animit(_this8.target).queue({ transform: _this8._getTransform(scroll) }, opt).play(resolve);
- });
- }
- }, {
- key: '_getAutoScroll',
- value: function _getAutoScroll(scroll, velocity, matchesDirection) {
- var max = this.maxScroll,
- offset = this._offset,
- size = this.itemNumSize;
-
- if (!this.isAutoScrollable()) {
- return Math.max(0, Math.min(max, scroll));
- }
-
- var arr = [];
- for (var s = offset; s < max; s += size) {
- arr.push(s);
- }
- arr.push(max);
-
- arr = arr.sort(function (left, right) {
- return Math.abs(left - scroll) - Math.abs(right - scroll);
- }).filter(function (item, pos) {
- return !pos || item !== arr[pos - 1];
- });
-
- var result = arr[0];
- var lastScroll = this._lastActiveIndex * size + offset;
- var scrollRatio = Math.abs(scroll - lastScroll) / size;
-
- if (scrollRatio <= this.getAutoScrollRatio(matchesDirection, velocity, size)) {
- result = lastScroll;
- } else {
- if (scrollRatio < 1.0 && arr[0] === lastScroll && arr.length > 1) {
- result = arr[1];
- }
- }
- return Math.max(0, Math.min(max, result));
- }
- }, {
- key: '_reset',
- value: function _reset() {
- this._targetSize = this._itemNumSize = undefined;
- }
- }, {
- key: '_normalizeScroll',
- value: function _normalizeScroll(scroll) {
- return Math.max(Math.min(scroll, this.maxScroll), 0);
- }
- }, {
- key: 'refresh',
- value: function refresh() {
- this._reset();
- this._updateLayout();
-
- if (util$1.isInteger(this._scroll)) {
- var scroll = this._normalizeScroll(this._scroll);
- scroll !== this._scroll ? this._killOverScroll(scroll) : this._changeTo(scroll);
- } else {
- this._setupInitialIndex();
- }
-
- this.refreshHook();
- }
- }, {
- key: '_getDelta',
- value: function _getDelta(event) {
- return event.gesture['delta' + this.dM.axis];
- }
- }, {
- key: '_getVelocity',
- value: function _getVelocity(event) {
- return event.gesture['velocity' + this.dM.axis];
- }
- }, {
- key: '_getTransform',
- value: function _getTransform(scroll) {
- return 'translate3d(' + this.dM.t3d[0] + -scroll + this.dM.t3d[1] + ')';
- }
- }, {
- key: '_updateLayout',
- value: function _updateLayout() {
- this.dM = directionMap[this.isVertical() ? 'vertical' : 'horizontal'];
- this.target.classList.toggle('ons-swiper-target--vertical', this.isVertical());
-
- for (var c = this.target.children[0]; c; c = c.nextElementSibling) {
- c.style[this.dM.size.toLowerCase()] = this.itemSize;
- }
-
- if (this.isCentered()) {
- this._offset = (this.targetSize - this.itemNumSize) / -2 || 0;
- }
- }
- }, {
- key: 'itemCount',
- get: function get$$1() {
- return this.target.children.length;
- }
- }, {
- key: 'itemNumSize',
- get: function get$$1() {
- if (typeof this._itemNumSize !== 'number' || this._itemNumSize !== this._itemNumSize) {
- this._itemNumSize = this._calculateItemSize();
- }
- return this._itemNumSize;
- }
- }, {
- key: 'maxScroll',
- get: function get$$1() {
- var max = this.itemCount * this.itemNumSize - this.targetSize;
- return Math.ceil(max < 0 ? 0 : max); // Need to return an integer value.
- }
- }, {
- key: 'targetSize',
- get: function get$$1() {
- if (!this._targetSize) {
- this._targetSize = this.target['offset' + this.dM.size];
- }
- return this._targetSize;
- }
- }]);
- return Swiper;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-carousel
- * @category carousel
- * @description
- * [en]
- * Carousel component. A carousel can be used to display several items in the same space.
- *
- * The component supports displaying content both horizontally and vertically. The user can scroll through the items by dragging and it can also be controller programmatically.
- * [/en]
- * [ja][/ja]
- * @codepen xbbzOQ
- * @tutorial vanilla/Reference/carousel
- * @seealso ons-carousel-item
- * [en]`<ons-carousel-item>` component[/en]
- * [ja]ons-carousel-itemコンポーネント[/ja]
- * @example
- * <ons-carousel style="width: 100%; height: 200px">
- * <ons-carousel-item>
- * ...
- * </ons-carousel-item>
- * <ons-carousel-item>
- * ...
- * </ons-carousel-item>
- * </ons-carousel>
- */
-
- var CarouselElement = function (_BaseElement) {
- inherits(CarouselElement, _BaseElement);
-
- /**
- * @event postchange
- * @description
- * [en]Fired just after the current carousel item has changed.[/en]
- * [ja]現在表示しているカルーセルの要素が変わった時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.carousel
- * [en]Carousel object.[/en]
- * [ja]イベントが発火したCarouselオブジェクトです。[/ja]
- * @param {Number} event.activeIndex
- * [en]Current active index.[/en]
- * [ja]現在アクティブになっている要素のインデックス。[/ja]
- * @param {Number} event.lastActiveIndex
- * [en]Previous active index.[/en]
- * [ja]以前アクティブだった要素のインデックス。[/ja]
- */
-
- /**
- * @event refresh
- * @description
- * [en]Fired when the carousel has been refreshed.[/en]
- * [ja]カルーセルが更新された時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.carousel
- * [en]Carousel object.[/en]
- * [ja]イベントが発火したCarouselオブジェクトです。[/ja]
- */
-
- /**
- * @event overscroll
- * @description
- * [en]Fired when the carousel has been overscrolled.[/en]
- * [ja]カルーセルがオーバースクロールした時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.carousel
- * [en]Fired when the carousel has been refreshed.[/en]
- * [ja]カルーセルが更新された時に発火します。[/ja]
- * @param {Number} event.activeIndex
- * [en]Current active index.[/en]
- * [ja]現在アクティブになっている要素のインデックス。[/ja]
- * @param {String} event.direction
- * [en]Can be one of either "up", "down", "left" or "right".[/en]
- * [ja]オーバースクロールされた方向が得られます。"up", "down", "left", "right"のいずれかの方向が渡されます。[/ja]
- * @param {Function} event.waitToReturn
- * [en]Takes a <code>Promise</code> object as an argument. The carousel will not scroll back until the promise has been resolved or rejected.[/en]
- * [ja]この関数はPromiseオブジェクトを引数として受け取ります。渡したPromiseオブジェクトがresolveされるかrejectされるまで、カルーセルはスクロールバックしません。[/ja]
- */
-
- /**
- * @attribute direction
- * @type {String}
- * @description
- * [en]The direction of the carousel. Can be either "horizontal" or "vertical". Default is "horizontal".[/en]
- * [ja]カルーセルの方向を指定します。"horizontal"か"vertical"を指定できます。"horizontal"がデフォルト値です。[/ja]
- */
-
- /**
- * @attribute fullscreen
- * @description
- * [en]If this attribute is set the carousel will cover the whole screen.[/en]
- * [ja]この属性があると、absoluteポジションを使ってカルーセルが自動的に画面いっぱいに広がります。[/ja]
- */
-
- /**
- * @attribute overscrollable
- * @description
- * [en]If this attribute is set the carousel will be scrollable over the edge. It will bounce back when released.[/en]
- * [ja]この属性がある時、タッチやドラッグで端までスクロールした時に、バウンドするような効果が当たります。[/ja]
- */
-
- /**
- * @attribute centered
- * @description
- * [en]If this attribute is set the carousel then the selected item will be in the center of the carousel instead of the beginning. Useful only when the items are smaller than the carousel. [/en]
- * [ja]この属性がある時、選んでいるons-carousel-itemはカルーセルの真ん中へ行きます。項目がカルーセルよりも小さい場合にのみ、これは便利です。[/ja]
- */
-
- /**
- * @attribute item-width
- * @type {String}
- * @description
- * [en]ons-carousel-item's width. Only works when the direction is set to "horizontal".[/en]
- * [ja]ons-carousel-itemの幅を指定します。この属性は、direction属性に"horizontal"を指定した時のみ有効になります。[/ja]
- */
-
- /**
- * @attribute item-height
- * @type {String}
- * @description
- * [en]ons-carousel-item's height. Only works when the direction is set to "vertical".[/en]
- * [ja]ons-carousel-itemの高さを指定します。この属性は、direction属性に"vertical"を指定した時のみ有効になります。[/ja]
- */
-
- /**
- * @attribute auto-scroll
- * @description
- * [en]If this attribute is set the carousel will be automatically scrolled to the closest item border when released.[/en]
- * [ja]この属性がある時、一番近いcarousel-itemの境界まで自動的にスクロールするようになります。[/ja]
- */
-
- /**
- * @attribute auto-scroll-ratio
- * @type {Number}
- * @description
- * [en]A number between 0.0 and 1.0 that specifies how much the user must drag the carousel in order for it to auto scroll to the next item.[/en]
- * [ja]0.0から1.0までの値を指定します。カルーセルの要素をどれぐらいの割合までドラッグすると次の要素に自動的にスクロールするかを指定します。[/ja]
- */
-
- /**
- * @attribute swipeable
- * @description
- * [en]If this attribute is set the carousel can be scrolled by drag or swipe.[/en]
- * [ja]この属性がある時、カルーセルをスワイプやドラッグで移動できるようになります。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]If this attribute is set the carousel is disabled.[/en]
- * [ja]この属性がある時、dragやtouchやswipeを受け付けなくなります。[/ja]
- */
-
- /**
- * @attribute initial-index
- * @initonly
- * @default 0
- * @type {Number}
- * @description
- * [en]Specify the index of the ons-carousel-item to show initially. Default is 0.[/en]
- * [ja]最初に表示するons-carousel-itemを0始まりのインデックスで指定します。デフォルト値は 0 です。[/ja]
- */
-
- /**
- * @attribute auto-refresh
- * @description
- * [en]When this attribute is set the carousel will automatically refresh when the number of child nodes change.[/en]
- * [ja]この属性がある時、子要素の数が変わるとカルーセルは自動的に更新されるようになります。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @description
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。例:{duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
- */
-
- function CarouselElement() {
- classCallCheck(this, CarouselElement);
-
- var _this = possibleConstructorReturn(this, (CarouselElement.__proto__ || Object.getPrototypeOf(CarouselElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(CarouselElement, [{
- key: '_compile',
- value: function _compile() {
- var target = this.children[0] && this.children[0].tagName !== 'ONS-CAROUSEL-ITEM' && this.children[0] || document.createElement('div');
- if (!target.parentNode) {
- while (this.firstChild) {
- target.appendChild(this.firstChild);
- }
- this.appendChild(target);
- }
-
- !this.children[1] && this.appendChild(document.createElement('div'));
-
- this.appendChild = this.appendChild.bind(target);
- this.insertBefore = this.insertBefore.bind(target);
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- if (!this._swiper) {
- this._swiper = new Swiper({
- getElement: function getElement() {
- return _this2;
- },
- getInitialIndex: function getInitialIndex() {
- return _this2.getAttribute('initial-index');
- },
- getAutoScrollRatio: function getAutoScrollRatio() {
- return _this2.autoScrollRatio;
- },
- isVertical: function isVertical() {
- return _this2.vertical;
- },
- isOverScrollable: function isOverScrollable() {
- return _this2.overscrollable;
- },
- isCentered: function isCentered() {
- return _this2.centered;
- },
- isAutoScrollable: function isAutoScrollable() {
- return _this2.autoScroll;
- },
- itemSize: this.itemSize,
- overScrollHook: this._onOverScroll.bind(this),
- preChangeHook: this._onChange.bind(this, 'prechange'),
- postChangeHook: this._onChange.bind(this, 'postchange'),
- refreshHook: this._onRefresh.bind(this),
- scrollHook: function scrollHook() {
- return _this2._onSwipe && _this2._onSwipe.apply(_this2, arguments);
- }
- });
-
- contentReady(this, function () {
- return _this2._swiper.init({
- swipeable: _this2.hasAttribute('swipeable'),
- autoRefresh: _this2.hasAttribute('auto-refresh')
- });
- });
- }
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- if (this._swiper && this._swiper.initialized) {
- this._swiper.dispose();
- this._swiper = null;
- }
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (!this._swiper) {
- return;
- }
-
- switch (name) {
- case 'swipeable':
- this._swiper.updateSwipeable(this.hasAttribute('swipeable'));
- break;
- case 'auto-refresh':
- this._swiper.updateAutoRefresh(this.hasAttribute('auto-refresh'));
- break;
- case 'item-height':
- this.vertical && this._swiper.updateItemSize(this.itemSize);
- break;
- case 'item-width':
- this.vertical || this._swiper.updateItemSize(this.itemSize);
- break;
- case 'direction':
- this._swiper.refresh();
- }
- }
- }, {
- key: '_show',
- value: function _show() {
- this._swiper.show();
- }
- }, {
- key: '_hide',
- value: function _hide() {
- this._swiper.hide();
- }
- }, {
- key: '_onOverScroll',
- value: function _onOverScroll(_ref) {
- var direction = _ref.direction,
- killOverScroll = _ref.killOverScroll;
-
- var waitForAction = false;
- util$1.triggerElementEvent(this, 'overscroll', {
- carousel: this,
- activeIndex: this.getActiveIndex(),
- direction: direction,
- waitToReturn: function waitToReturn(promise) {
- waitForAction = true;
- promise.then(killOverScroll);
- }
- });
-
- return waitForAction;
- }
- }, {
- key: '_onChange',
- value: function _onChange(eventName, _ref2) {
- var activeIndex = _ref2.activeIndex,
- lastActiveIndex = _ref2.lastActiveIndex;
-
- util$1.triggerElementEvent(this, eventName, { carousel: this, activeIndex: activeIndex, lastActiveIndex: lastActiveIndex });
- }
- }, {
- key: '_onRefresh',
- value: function _onRefresh() {
- util$1.triggerElementEvent(this, 'refresh', { carousel: this });
- }
-
- /**
- * @method setActiveIndex
- * @signature setActiveIndex(index, [options])
- * @param {Number} index
- * [en]The index that the carousel should be set to.[/en]
- * [ja]carousel要素のインデックスを指定します。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be called after the animation is finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @description
- * [en]Specify the index of the `<ons-carousel-item>` to show.[/en]
- * [ja]表示するons-carousel-itemをindexで指定します。[/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'setActiveIndex',
- value: function setActiveIndex(index) {
- var _this3 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- options = _extends({
- animation: this.getAttribute('animation'),
- animationOptions: this.hasAttribute('animation-options') ? util$1.animationOptionsParse(this.getAttribute('animation-options')) : { duration: .3, timing: 'cubic-bezier(.4, .7, .5, 1)' }
- }, options);
-
- return this._swiper.setActiveIndex(index, options).then(function () {
- options.callback instanceof Function && options.callback(_this3);
- return Promise.resolve(_this3);
- });
- }
-
- /**
- * @method getActiveIndex
- * @signature getActiveIndex()
- * @return {Number}
- * [en]The current carousel item index.[/en]
- * [ja]現在表示しているカルーセル要素のインデックスが返されます。[/ja]
- * @description
- * [en]Returns the index of the currently visible `<ons-carousel-item>`.[/en]
- * [ja]現在表示されているons-carousel-item要素のインデックスを返します。[/ja]
- */
-
- }, {
- key: 'getActiveIndex',
- value: function getActiveIndex() {
- return this._swiper.getActiveIndex();
- }
-
- /**
- * @method next
- * @signature next([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja][/ja]
- * @description
- * [en]Show next `<ons-carousel-item>`.[/en]
- * [ja]次のons-carousel-itemを表示します。[/ja]
- */
-
- }, {
- key: 'next',
- value: function next(options) {
- return this.setActiveIndex(this.getActiveIndex() + 1, options);
- }
-
- /**
- * @method prev
- * @signature prev([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja][/ja]
- * @description
- * [en]Show previous `<ons-carousel-item>`.[/en]
- * [ja]前のons-carousel-itemを表示します。[/ja]
- */
-
- }, {
- key: 'prev',
- value: function prev(options) {
- return this.setActiveIndex(this.getActiveIndex() - 1, options);
- }
-
- /**
- * @method first
- * @signature first()
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this is set to `"none"`, the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja][/ja]
- * @description
- * [en]Show first `<ons-carousel-item>`.[/en]
- * [ja]最初のons-carousel-itemを表示します。[/ja]
- */
-
- }, {
- key: 'first',
- value: function first(options) {
- return this.setActiveIndex(0, options);
- }
-
- /**
- * @method last
- * @signature last()
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja][/ja]
- * @param {Function} [options.callback]
- * [en]A function that will be executed after the animation has finished.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- * @param {Object} [options.animationOptions]
- * [en]An object that can be used to specify the duration, delay and timing function of the animation.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the carousel element[/en]
- * [ja]Resolves to the carousel element[/ja]
- * @description
- * [en]Show last ons-carousel item.[/en]
- * [ja]最後のons-carousel-itemを表示します。[/ja]
- */
-
- }, {
- key: 'last',
- value: function last(options) {
- this.setActiveIndex(Math.max(this.itemCount - 1, 0), options);
- }
-
- /**
- * @method refresh
- * @signature refresh()
- * @description
- * [en]Update the layout of the carousel. Used when adding `<ons-carousel-items>` dynamically or to automatically adjust the size.[/en]
- * [ja]レイアウトや内部の状態を最新のものに更新します。ons-carousel-itemを動的に増やしたり、ons-carouselの大きさを動的に変える際に利用します。[/ja]
- */
-
- }, {
- key: 'refresh',
- value: function refresh() {
- this._swiper.refresh();
- }
-
- /**
- * @property itemCount
- * @readonly
- * @type {Number}
- * @description
- * [en]The number of carousel items.[/en]
- * [ja]カルーセル要素の数です。[/ja]
- */
-
- }, {
- key: 'itemCount',
- get: function get$$1() {
- return this._swiper.itemCount;
- }
-
- /**
- * @property swipeable
- * @type {Boolean}
- * @description
- * [en]true if the carousel is swipeable.[/en]
- * [ja]swipeableであればtrueを返します。[/ja]
- */
-
- }, {
- key: 'swipeable',
- get: function get$$1() {
- return this.hasAttribute('swipeable');
- },
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'swipeable', value);
- }
-
- /**
- * @property onSwipe
- * @type {Function}
- * @description
- * [en]Hook called whenever the user slides the carousel. It gets a decimal index and an animationOptions object as arguments.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onSwipe',
- get: function get$$1() {
- return this._onSwipe;
- },
- set: function set$$1(value) {
- if (value && !(value instanceof Function)) {
- util$1.throw('"onSwipe" must be a function');
- }
- this._onSwipe = value;
- }
-
- /**
- * @property autoScroll
- * @type {Boolean}
- * @description
- * [en]true if auto scroll is enabled.[/en]
- * [ja]オートスクロールが有効であればtrueを返します。[/ja]
- */
-
- }, {
- key: 'autoScroll',
- get: function get$$1() {
- return this.hasAttribute('auto-scroll');
- },
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'auto-scroll', value);
- }
- }, {
- key: 'vertical',
- get: function get$$1() {
- return this.getAttribute('direction') === 'vertical';
- }
- }, {
- key: 'itemSize',
- get: function get$$1() {
- var itemSizeAttr = (this.getAttribute('item-' + (this.vertical ? 'height' : 'width')) || '').trim();
- return itemSizeAttr.match(/^\d+(px|%)$/) ? itemSizeAttr : '100%';
- }
-
- /**
- * @property autoScrollRatio
- * @type {Number}
- * @description
- * [en]The current auto scroll ratio. [/en]
- * [ja]現在のオートスクロールのratio値。[/ja]
- */
-
- }, {
- key: 'autoScrollRatio',
- get: function get$$1() {
- return parseFloat(this.getAttribute('auto-scroll-ratio'));
- },
- set: function set$$1(ratio) {
- this.setAttribute('auto-scroll-ratio', ratio);
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the carousel is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'disabled',
- get: function get$$1() {
- return this.hasAttribute('disabled');
- },
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- }
-
- /**
- * @property overscrollable
- * @type {Boolean}
- * @description
- * [en]Whether the carousel is overscrollable or not.[/en]
- * [ja]overscrollできればtrueを返します。[/ja]
- */
-
- }, {
- key: 'overscrollable',
- get: function get$$1() {
- return this.hasAttribute('overscrollable');
- },
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'overscrollable', value);
- }
-
- /**
- * @property centered
- * @type {Boolean}
- * @description
- * [en]Whether the carousel is centered or not.[/en]
- * [ja]centered状態になっていればtrueを返します。[/ja]
- */
-
- }, {
- key: 'centered',
- get: function get$$1() {
- return this.hasAttribute('centered');
- },
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'centered', value);
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['swipeable', 'auto-refresh', 'direction', 'item-height', 'item-width'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['postchange', 'refresh', 'overscroll'];
- }
- }]);
- return CarouselElement;
- }(BaseElement);
-
- onsElements.Carousel = CarouselElement;
- customElements.define('ons-carousel', CarouselElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-col
- * @category grid
- * @description
- * [en]Represents a column in the grid system. Use with `<ons-row>` to layout components.[/en]
- * [ja]グリッドシステムにて列を定義します。ons-rowとともに使用し、コンポーネントのレイアウトに利用します。[/ja]
- * @note
- * [en]For Android 4.3 and earlier, and iOS6 and earlier, when using mixed alignment with ons-row and ons-column, they may not be displayed correctly. You can use only one alignment.[/en]
- * [ja]Android 4.3以前、もしくはiOS 6以前のOSの場合、ons-rowとons-columnを組み合わせた場合に描画が崩れる場合があります。[/ja]
- * @codepen GgujC {wide}
- * @guide theming.html [en]Layouting guide[/en][ja]レイアウト機能[/ja]
- * @seealso ons-row
- * [en]The `<ons-row>` component is the parent of `<ons-col>`.[/en]
- * [ja]ons-rowコンポーネント[/ja]
- * @example
- * <ons-row>
- * <ons-col width="50px"><ons-icon icon="fa-twitter"></ons-icon></ons-col>
- * <ons-col>Text</ons-col>
- * </ons-row>
- */
-
- /**
- * @attribute vertical-align
- * @type {String}
- * @description
- * [en]Vertical alignment of the column. Valid values are "top", "center", and "bottom".[/en]
- * [ja]縦の配置を指定する。"top", "center", "bottom"のいずれかを指定します。[/ja]
- */
-
- /**
- * @attribute width
- * @type {String}
- * @description
- * [en]The width of the column. Valid values are css width values ("10%", "50px").[/en]
- * [ja]カラムの横幅を指定する。パーセントもしくはピクセルで指定します(10%や50px)。[/ja]
- */
-
- var ColElement = function (_BaseElement) {
- inherits(ColElement, _BaseElement);
-
- function ColElement() {
- classCallCheck(this, ColElement);
-
- var _this = possibleConstructorReturn(this, (ColElement.__proto__ || Object.getPrototypeOf(ColElement)).call(this));
-
- if (_this.getAttribute('width')) {
- _this._updateWidth();
- }
- return _this;
- }
-
- createClass(ColElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'width') {
- this._updateWidth();
- }
- }
- }, {
- key: '_updateWidth',
- value: function _updateWidth() {
- var width = this.getAttribute('width');
- if (!width) {
- styler.clear(this, 'flex maxWidth');
- } else {
- width = width.trim().match(/^\d+$/) ? width + '%' : width;
-
- styler(this, {
- flex: '0 0 ' + width,
- maxWidth: width
- });
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['width'];
- }
- }]);
- return ColElement;
- }(BaseElement);
-
- onsElements.Col = ColElement;
- customElements.define('ons-col', ColElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var DialogAnimator = function (_BaseAnimator) {
- inherits(DialogAnimator, _BaseAnimator);
-
- function DialogAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, DialogAnimator);
- return possibleConstructorReturn(this, (DialogAnimator.__proto__ || Object.getPrototypeOf(DialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} dialog
- * @param {Function} done
- */
-
-
- createClass(DialogAnimator, [{
- key: 'show',
- value: function show(dialog, done) {
- done();
- }
-
- /**
- * @param {HTMLElement} dialog
- * @param {Function} done
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, done) {
- done();
- }
- }]);
- return DialogAnimator;
- }(BaseAnimator);
-
- /**
- * Android style animator for dialog.
- */
- var AndroidDialogAnimator = function (_DialogAnimator) {
- inherits(AndroidDialogAnimator, _DialogAnimator);
-
- function AndroidDialogAnimator() {
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref2$timing = _ref2.timing,
- timing = _ref2$timing === undefined ? 'ease-in-out' : _ref2$timing,
- _ref2$delay = _ref2.delay,
- delay = _ref2$delay === undefined ? 0 : _ref2$delay,
- _ref2$duration = _ref2.duration,
- duration = _ref2$duration === undefined ? 0.3 : _ref2$duration;
-
- classCallCheck(this, AndroidDialogAnimator);
- return possibleConstructorReturn(this, (AndroidDialogAnimator.__proto__ || Object.getPrototypeOf(AndroidDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(AndroidDialogAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -60%, 0)', opacity: 0 }, { transform: 'translate3d(-50%, -50%, 0)', opacity: 1 }).queue(function (done) {
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0)', opacity: 1 }, { transform: 'translate3d(-50%, -60%, 0)', opacity: 0 }).queue(function (done) {
- callback();
- done();
- }));
- }
- }]);
- return AndroidDialogAnimator;
- }(DialogAnimator);
-
- /**
- * iOS style animator for dialog.
- */
- var IOSDialogAnimator = function (_DialogAnimator2) {
- inherits(IOSDialogAnimator, _DialogAnimator2);
-
- function IOSDialogAnimator() {
- var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref3$timing = _ref3.timing,
- timing = _ref3$timing === undefined ? 'ease-in-out' : _ref3$timing,
- _ref3$delay = _ref3.delay,
- delay = _ref3$delay === undefined ? 0 : _ref3$delay,
- _ref3$duration = _ref3.duration,
- duration = _ref3$duration === undefined ? 0.2 : _ref3$duration;
-
- classCallCheck(this, IOSDialogAnimator);
-
- var _this3 = possibleConstructorReturn(this, (IOSDialogAnimator.__proto__ || Object.getPrototypeOf(IOSDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this3.bodyHeight = document.body.clientHeight; // avoid Forced Synchronous Layout
- return _this3;
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(IOSDialogAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, ' + (this.bodyHeight / 2.0 - 1) + 'px, 0)' }, { transform: 'translate3d(-50%, -50%, 0)' }).queue(function (done) {
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0)' }, { transform: 'translate3d(-50%, ' + (this.bodyHeight / 2.0 - 1) + 'px, 0)' }).queue(function (done) {
- callback();
- done();
- }));
- }
- }]);
- return IOSDialogAnimator;
- }(DialogAnimator);
-
- /**
- * Slide animator for dialog.
- */
- var SlideDialogAnimator = function (_DialogAnimator3) {
- inherits(SlideDialogAnimator, _DialogAnimator3);
-
- function SlideDialogAnimator() {
- var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref4$timing = _ref4.timing,
- timing = _ref4$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref4$timing,
- _ref4$delay = _ref4.delay,
- delay = _ref4$delay === undefined ? 0 : _ref4$delay,
- _ref4$duration = _ref4.duration,
- duration = _ref4$duration === undefined ? 0.2 : _ref4$duration;
-
- classCallCheck(this, SlideDialogAnimator);
-
- var _this4 = possibleConstructorReturn(this, (SlideDialogAnimator.__proto__ || Object.getPrototypeOf(SlideDialogAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this4.bodyHeight = document.body.clientHeight; // avoid Forced Synchronous Layout
- return _this4;
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
-
- createClass(SlideDialogAnimator, [{
- key: 'show',
- value: function show(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 0 }, { opacity: 1 }), Animit(dialog._dialog, this.def).default(
- // FIXME: This should avoid Forced Synchronous Layout. Otherwise, fade animation of mask will be broken.
- { transform: 'translate3d(-50%, ' + (-(this.bodyHeight / 2.0) + 1 - dialog._dialog.clientHeight) + 'px, 0)' }, { transform: 'translate3d(-50%, -50%, 0)' }).queue(function (done) {
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} dialog
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(dialog, callback) {
- callback = callback ? callback : function () {};
-
- Animit.runAll(Animit(dialog._mask, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(dialog._dialog, this.def).default({ transform: 'translate3d(-50%, -50%, 0)' },
- // FIXME: This should avoid Forced Synchronous Layout. Otherwise, fade animation of mask will be broken.
- { transform: 'translate3d(-50%, ' + (-(this.bodyHeight / 2.0) + 1 - dialog._dialog.clientHeight) + 'px, 0)' }).queue(function (done) {
- callback();
- done();
- }));
- }
- }]);
- return SlideDialogAnimator;
- }(DialogAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$6 = {
- '.dialog': 'dialog--*',
- '.dialog-container': 'dialog-container--*',
- '.dialog-mask': 'dialog-mask--*'
- };
-
- var _animatorDict$2 = {
- 'default': function _default() {
- return platform.isAndroid() ? AndroidDialogAnimator : IOSDialogAnimator;
- },
- 'slide': SlideDialogAnimator,
- 'none': DialogAnimator
- };
-
- /**
- * @element ons-dialog
- * @category dialog
- * @description
- * [en]
- * Dialog that is displayed on top of current screen. As opposed to the `<ons-alert-dialog>` element, this component can contain any kind of content.
- *
- * To use the element it can either be attached directly to the `<body>` element or dynamically created from a template using the `ons.createDialog(template)` utility function and the `<template>` tag.
- *
- * The dialog is useful for displaying menus, additional information or to ask the user to make a decision.
- *
- * It will automatically be displayed as Material Design when running on an Android device.
- * [/en]
- * [ja][/ja]
- * @modifier material
- * [en]Display a Material Design dialog.[/en]
- * [ja]マテリアルデザインのダイアログを表示します。[/ja]
- * @codepen zxxaGa
- * @tutorial vanilla/Reference/dialog
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @seealso ons-alert-dialog
- * [en]`<ons-alert-dialog>` component[/en]
- * [ja]ons-alert-dialogコンポーネント[/ja]
- * @seealso ons-popover
- * [en]`<ons-popover>` component[/en]
- * [ja]ons-popoverコンポーネント[/ja]
- * @seealso ons-modal
- * [en]`<ons-modal>` component[/en]
- * [ja]ons-modalコンポーネント[/ja]
- * @example
- * <ons-dialog id="dialog">
- * <p>This is a dialog!</p>
- * </ons-dialog>
- *
- * <script>
- * document.getElementById('dialog').show();
- * </script>
- */
-
- var DialogElement = function (_BaseDialogElement) {
- inherits(DialogElement, _BaseDialogElement);
-
- /**
- * @event preshow
- * @description
- * [en]Fired just before the dialog is displayed.[/en]
- * [ja]ダイアログが表示される直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.dialog
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute this function to stop the dialog from being shown.[/en]
- * [ja]この関数を実行すると、ダイアログの表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event postshow
- * @description
- * [en]Fired just after the dialog is displayed.[/en]
- * [ja]ダイアログが表示された直後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.dialog
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @event prehide
- * @description
- * [en]Fired just before the dialog is hidden.[/en]
- * [ja]ダイアログが隠れる直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.dialog
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute this function to stop the dialog from being hidden.[/en]
- * [ja]この関数を実行すると、ダイアログの非表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event posthide
- * @description
- * [en]Fired just after the dialog is hidden.[/en]
- * [ja]ダイアログが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.dialog
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the dialog.[/en]
- * [ja]ダイアログの表現を指定します。[/ja]
- */
-
- /**
- * @attribute cancelable
- * @description
- * [en]If this attribute is set the dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]If this attribute is set the dialog is disabled.[/en]
- * [ja]この属性がある時、ダイアログはdisabled状態になります。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]The animation used when showing and hiding the dialog. Can be either `"none"` or `"default"`.[/en]
- * [ja]ダイアログを表示する際のアニメーション名を指定します。"none"もしくは"default"を指定できます。[/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/ja]
- */
-
- /**
- * @attribute mask-color
- * @type {String}
- * @default rgba(0, 0, 0, 0.2)
- * @description
- * [en]Color of the background mask. Default is `"rgba(0, 0, 0, 0.2)"`.[/en]
- * [ja]背景のマスクの色を指定します。"rgba(0, 0, 0, 0.2)"がデフォルト値です。[/ja]
- */
-
- function DialogElement() {
- classCallCheck(this, DialogElement);
-
- var _this = possibleConstructorReturn(this, (DialogElement.__proto__ || Object.getPrototypeOf(DialogElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(DialogElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- return new AnimatorFactory({
- animators: _animatorDict$2,
- baseClass: DialogAnimator,
- baseClassName: 'DialogAnimator',
- defaultAnimation: this.getAttribute('animation')
- });
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.style.display = 'none';
- this.style.zIndex = 10001;
-
- /* Expected result:
- * <ons-dialog>
- * <div class="dialog-mask"></div>
- * <div class="dialog">
- * <div class="dialog-container">...</div>
- * </div>
- * </ons-dialog>
- */
-
- if (!this._dialog) {
- var dialog = document.createElement('div');
- dialog.classList.add('dialog');
-
- var container = document.createElement('div');
- container.classList.add('dialog-container');
- while (this.firstChild) {
- container.appendChild(this.firstChild);
- }
- dialog.appendChild(container);
-
- this.appendChild(dialog);
- }
-
- if (!this._mask) {
- var mask = document.createElement('div');
- mask.classList.add('dialog-mask');
- this.insertBefore(mask, this.firstChild);
- }
-
- this._dialog.style.zIndex = 20001;
- this._mask.style.zIndex = 20000;
-
- this.setAttribute('status-bar-fill', '');
-
- ModifierUtil.initModifier(this, this._scheme);
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- /**
- * @method show
- * @signature show([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
- * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定します。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
- * @param {Function} [options.callback]
- * [en]This function is called after the dialog has been revealed.[/en]
- * [ja]ダイアログが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Show the dialog.[/en]
- * [ja]ダイアログを開きます。[/ja]
- * @return {Promise} Resolves to the displayed element.
- */
-
- /**
- * @method hide
- * @signature hide([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"slide"`.[/en]
- * [ja]アニメーション名を指定します。"none", "slide"のいずれかを指定できます。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/ja]
- * @param {Function} [options.callback]
- * [en]This functions is called after the dialog has been hidden.[/en]
- * [ja]ダイアログが隠れた後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Hide the dialog.[/en]
- * [ja]ダイアログを閉じます。[/ja]
- * @return {Promise}
- * [en]Resolves to the hidden element[/en]
- * [ja][/ja]
- */
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the dialog is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the dialog is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- /**
- * @property cancelable
- * @type {Boolean}
- * @description
- * [en]Whether the dialog is cancelable or not. A cancelable dialog can be closed by tapping the background or by pressing the back button on Android devices.[/en]
- * [ja][/ja]
- */
-
- /**
- * @param {String} name
- * @param {DialogAnimator} Animator
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$6;
- }
- }, {
- key: '_mask',
- get: function get$$1() {
- return util$1.findChild(this, '.dialog-mask');
- }
- }, {
- key: '_dialog',
- get: function get$$1() {
- return util$1.findChild(this, '.dialog');
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof DialogAnimator)) {
- util$1.throwAnimator('Dialog');
- }
- _animatorDict$2[name] = Animator;
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$2;
- }
- }, {
- key: 'DialogAnimator',
- get: function get$$1() {
- return DialogAnimator;
- }
- }]);
- return DialogElement;
- }(BaseDialogElement);
-
- onsElements.Dialog = DialogElement;
- customElements.define('ons-dialog', DialogElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var defaultClassName$3 = 'fab';
-
- var scheme$7 = {
- '': 'fab--*',
- '.fab__icon': 'fab--*__icon'
- };
-
- /**
- * @element ons-fab
- * @category form
- * @description
- * [en]
- * The Floating action button is a circular button defined in the [Material Design specification](https://www.google.com/design/spec/components/buttons-floating-action-button.html). They are often used to promote the primary action of the app.
- *
- * It can be displayed either as an inline element or in one of the corners. Normally it will be positioned in the lower right corner of the screen.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/fab
- * @modifier mini
- * [en]Makes the `ons-fab` smaller.[/en]
- * [ja][/ja]
- * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
- * @seealso ons-speed-dial
- * [en]The `<ons-speed-dial>` component is a Floating action button that displays a menu when tapped.[/en]
- * [ja][/ja]
- */
-
- var FabElement = function (_BaseElement) {
- inherits(FabElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the button.[/en]
- * [ja]ボタンの表現を指定します。[/ja]
- */
-
- /**
- * @attribute ripple
- * @description
- * [en]If this attribute is defined, the button will have a ripple effect when tapped.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute position
- * @type {String}
- * @description
- * [en]The position of the button. Should be a string like `"bottom right"` or `"top left"`. If this attribute is not defined it will be displayed as an inline element.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Specify if button should be disabled.[/en]
- * [ja]ボタンを無効化する場合は指定します。[/ja]
- */
-
- function FabElement() {
- classCallCheck(this, FabElement);
-
- // The following statements can be executed before contentReady
- // since these do not access the children
- var _this = possibleConstructorReturn(this, (FabElement.__proto__ || Object.getPrototypeOf(FabElement)).call(this));
-
- _this._hide();
- _this.classList.add(defaultClassName$3);
-
- contentReady(_this, function () {
- _this._compile();
- });
- return _this;
- }
-
- createClass(FabElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- if (!util$1.findChild(this, '.fab__icon')) {
- var content = document.createElement('span');
- content.classList.add('fab__icon');
-
- util$1.arrayFrom(this.childNodes).forEach(function (element) {
- if (!element.tagName || element.tagName.toLowerCase() !== 'ons-ripple') {
- content.appendChild(element);
- }
- });
- this.appendChild(content);
- }
-
- this._updateRipple();
-
- ModifierUtil.initModifier(this, scheme$7);
-
- this._updatePosition();
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- setImmediate(function () {
- return _this2._show();
- });
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$3, scheme$7);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$7);
- break;
- case 'ripple':
- this._updateRipple();
- break;
- case 'position':
- this._updatePosition();
- break;
- }
- }
- }, {
- key: '_show',
- value: function _show() {
- if (!this._manuallyHidden) {
- // if user has not called ons-fab.hide()
- this._toggle(true);
- }
- }
- }, {
- key: '_hide',
- value: function _hide() {
- var _this3 = this;
-
- setImmediate(function () {
- return _this3._toggle(false);
- });
- }
- }, {
- key: '_updateRipple',
- value: function _updateRipple() {
- util$1.updateRipple(this);
- }
- }, {
- key: '_updatePosition',
- value: function _updatePosition() {
- var position = this.getAttribute('position');
- this.classList.remove('fab--top__left', 'fab--bottom__right', 'fab--bottom__left', 'fab--top__right', 'fab--top__center', 'fab--bottom__center');
- switch (position) {
- case 'top right':
- case 'right top':
- this.classList.add('fab--top__right');
- break;
- case 'top left':
- case 'left top':
- this.classList.add('fab--top__left');
- break;
- case 'bottom right':
- case 'right bottom':
- this.classList.add('fab--bottom__right');
- break;
- case 'bottom left':
- case 'left bottom':
- this.classList.add('fab--bottom__left');
- break;
- case 'center top':
- case 'top center':
- this.classList.add('fab--top__center');
- break;
- case 'center bottom':
- case 'bottom center':
- this.classList.add('fab--bottom__center');
- break;
- default:
- break;
- }
- }
-
- /**
- * @method show
- * @signature show()
- * @description
- * [en]Show the floating action button.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'show',
- value: function show() {
- this.toggle(true);
- }
-
- /**
- * @method hide
- * @signature hide()
- * @description
- * [en]Hide the floating action button.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'hide',
- value: function hide() {
- this.toggle(false);
- }
-
- /**
- * @method toggle
- * @signature toggle()
- * @description
- * [en]Toggle the visibility of the button.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'toggle',
- value: function toggle() {
- var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : !this.visible;
-
- this._manuallyHidden = !action;
- this._toggle(action);
- }
- }, {
- key: '_toggle',
- value: function _toggle() {
- var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : !this.visible;
-
- var isBottom = (this.getAttribute('position') || '').indexOf('bottom') >= 0;
- var translate = isBottom ? 'translate3d(0px, -' + (util$1.globals.fabOffset || 0) + 'px, 0px)' : '';
-
- styler(this, { transform: translate + ' scale(' + Number(action) + ')' });
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the element is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- }, {
- key: 'visible',
- get: function get$$1() {
- return this.style.transform.indexOf('scale(0)') === -1 && this.style.display !== 'none';
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'ripple', 'position', 'class'];
- }
- }]);
- return FabElement;
- }(BaseElement);
-
- onsElements.Fab = FabElement;
- customElements.define('ons-fab', FabElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-gesture-detector
- * @category gesture
- * @description
- * [en]
- * Component to detect finger gestures within the wrapped element. Following gestures are supported:
- * - Drag gestures: `drag`, `dragleft`, `dragright`, `dragup`, `dragdown`
- * - Hold gestures: `hold`, `release`
- * - Swipe gestures: `swipe`, `swipeleft`, `swiperight`, `swipeup`, `swipedown`
- * - Tap gestures: `tap`, `doubletap`
- * - Pinch gestures: `pinch`, `pinchin`, `pinchout`
- * - Other gestures: `touch`, `transform`, `rotate`
- * [/en]
- * [ja]要素内のジェスチャー操作を検知します。詳しくはガイドを参照してください。[/ja]
- * @guide features.html#gesture-detection
- * [en]Detecting finger gestures[/en]
- * [ja]ジェスチャー操作の検知[/ja]
- * @example
- * <ons-gesture-detector>
- * <div id="detect-area" style="width: 100px; height: 100px;">
- * Swipe Here
- * </div>
- * </ons-gesture-detector>
- *
- * <script>
- * document.addEventListener('swipeleft', function(event) {
- * if (event.target.matches('#detect-area')) {
- * console.log('Swipe left is detected.');
- * }
- * });
- * </script>
- */
-
- var GestureDetectorElement = function (_BaseElement) {
- inherits(GestureDetectorElement, _BaseElement);
-
- function GestureDetectorElement() {
- classCallCheck(this, GestureDetectorElement);
-
- var _this = possibleConstructorReturn(this, (GestureDetectorElement.__proto__ || Object.getPrototypeOf(GestureDetectorElement)).call(this));
-
- _this._gestureDetector = new GestureDetector(_this, { passive: true });
- return _this;
- }
-
- return GestureDetectorElement;
- }(BaseElement);
-
- onsElements.GestureDetector = GestureDetectorElement;
- customElements.define('ons-gesture-detector', GestureDetectorElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var autoPrefix = 'fa'; // FIXME: To be removed in v3
-
- /**
- * @element ons-icon
- * @category visual
- * @description
- * [en]
- * Displays an icon. The following icon suites are available:
- *
- * * [Font Awesome](https://fortawesome.github.io/Font-Awesome/)
- * * [Ionicons](http://ionicons.com/)
- * * [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font/)
- * [/en]
- * [ja][/ja]
- * @codepen xAhvg
- * @tutorial vanilla/Reference/icon
- * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja][/ja]
- * @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
- * @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
- * @example
- * <ons-icon
- * icon="md-car"
- * size="20px"
- * style="color: red">
- * </ons-icon>
- *
- * <ons-button>
- * <ons-icon icon="md-car"></ons-icon>
- * Car
- * </ons-button>
- */
-
- var IconElement = function (_BaseElement) {
- inherits(IconElement, _BaseElement);
-
- /**
- * @attribute icon
- * @type {String}
- * @description
- * [en]
- * The icon name. `"md-"` prefix for Material Icons, `"fa-"` for Font Awesome and `"ion-"` prefix for Ionicons.
- *
- * See all available icons on the element description (at the top).
- *
- * Icons can also be styled based on modifier presence. Add comma-separated icons with `"modifierName:"` prefix.
- *
- * The code `<ons-icon icon="ion-edit, material:md-edit"></ons-icon>` will display `"md-edit"` for Material Design and `"ion-edit"` as the default icon.
- *
- * `fa-` prefix is added automatically if none is provided. Check [See also](#seealso) section for more information.
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute size
- * @type {String}
- * @description
- * [en]
- * The sizes of the icon. Valid values are lg, 2x, 3x, 4x, 5x, or in the size in pixels.
- * Icons can also be styled based on modifier presence. Add comma-separated icons with `"modifierName:"` prefix.
- *
- * The code:
- *
- * ```
- * <ons-icon
- * icon="ion-edit"
- * size="32px, material:24px">
- * </ons-icon>
- * ```
- *
- * will render as a `24px` icon if the `"material"` modifier is present and `32px` otherwise.
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute rotate
- * @type {Number}
- * @description
- * [en]Number of degrees to rotate the icon. Valid values are 90, 180 and 270.[/en]
- * [ja]アイコンを回転して表示します。90, 180, 270から指定できます。[/ja]
- */
-
- /**
- * @attribute fixed-width
- * @type {Boolean}
- * @default false
- * @description
- * [en]When used in a list, you want the icons to have the same width so that they align vertically by defining this attribute.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute spin
- * @description
- * [en]Specify whether the icon should be spinning.[/en]
- * [ja]アイコンを回転するかどうかを指定します。[/ja]
- */
-
- function IconElement() {
- classCallCheck(this, IconElement);
-
- var _this = possibleConstructorReturn(this, (IconElement.__proto__ || Object.getPrototypeOf(IconElement)).call(this));
-
- contentReady(_this, function () {
- _this._compile();
- });
- return _this;
- }
-
- createClass(IconElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- this._cleanClassAttribute(name === 'icon' ? last : this.getAttribute('icon'), name === 'modifier' ? last : undefined);
- this._update();
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this._update();
- }
- }, {
- key: '_update',
- value: function _update() {
- var _this2 = this;
-
- var _buildClassAndStyle2 = this._buildClassAndStyle(this._parseAttr('icon'), this._parseAttr('size')),
- classList = _buildClassAndStyle2.classList,
- style = _buildClassAndStyle2.style;
-
- util$1.extend(this.style, style);
-
- classList.forEach(function (className) {
- return _this2.classList.add(className);
- });
- }
- }, {
- key: '_parseAttr',
- value: function _parseAttr(attrName) {
- var modifier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getAttribute('modifier') || '';
-
- var attr = this.getAttribute(attrName) || attrName || '';
- var parts = attr.split(/\s*,\s*/);
- var def = parts[0];
- var md = parts[1];
- md = (md || '').split(/\s*:\s*/);
-
- return (modifier && RegExp('(^|\\s+)' + md[0] + '($|\\s+)', 'i').test(modifier) ? md[1] : def) || '';
- }
-
- /**
- * Remove unneeded class value.
- */
-
- }, {
- key: '_cleanClassAttribute',
- value: function _cleanClassAttribute(lastIcon, lastModifier) {
- var _this3 = this;
-
- var _prefixIcon2 = this._prefixIcon(this._parseAttr(lastIcon, lastModifier)),
- className = _prefixIcon2.className,
- prefix = _prefixIcon2.prefix;
-
- var customPrefixRE = className !== prefix ? '|' + prefix + '$|' + prefix + '-' : '|' + className + '$' || '';
- var re = new RegExp('^(fa$|fa-|ion-|zmdi$|zmdi-|ons-icon--' + customPrefixRE + ')');
-
- util$1.arrayFrom(this.classList).filter(function (className) {
- return re.test(className);
- }).forEach(function (className) {
- return _this3.classList.remove(className);
- });
- }
- }, {
- key: '_prefixIcon',
- value: function _prefixIcon(iconName) {
- var className = autoPrefix + (autoPrefix ? '-' : '') + iconName;
- return { className: className, prefix: className.split('-')[0] };
- }
- }, {
- key: '_buildClassAndStyle',
- value: function _buildClassAndStyle(iconName, size) {
- var classList = ['ons-icon'];
- var style = {};
-
- // Icon
- if (iconName.indexOf('ion-') === 0) {
- classList.push(iconName);
- classList.push('ons-icon--ion');
- } else if (iconName.indexOf('fa-') === 0) {
- classList.push(iconName);
- // default icon style to Font Awesome Solid if icon style is not specified already
- if (!(this.classList.contains('far') || this.classList.contains('fab') || this.classList.contains('fal'))) {
- classList.push('fa');
- }
- } else if (iconName.indexOf('md-') === 0) {
- classList.push('zmdi');
- classList.push('zmdi-' + iconName.split(/-(.+)?/)[1]);
- } else {
- var _prefixIcon3 = this._prefixIcon(iconName),
- className = _prefixIcon3.className,
- prefix = _prefixIcon3.prefix;
-
- prefix && classList.push(prefix);
- className && classList.push(className);
- }
-
- // Size
- if (size.match(/^[1-5]x|lg$/)) {
- classList.push('ons-icon--' + size);
- this.style.removeProperty('font-size');
- } else {
- style.fontSize = size;
- }
-
- return {
- classList: classList,
- style: style
- };
- }
- }], [{
- key: 'setAutoPrefix',
- value: function setAutoPrefix(prefix) {
- autoPrefix = prefix ? typeof prefix === 'string' && prefix || 'fa' : '';
- }
- }, {
- key: 'observedAttributes',
- get: function get$$1() {
- return ['icon', 'size', 'modifier', 'class'];
- }
- }]);
- return IconElement;
- }(BaseElement);
-
- onsElements.Icon = IconElement;
- customElements.define('ons-icon', IconElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var LazyRepeatDelegate = function () {
- function LazyRepeatDelegate(userDelegate) {
- var templateElement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
- classCallCheck(this, LazyRepeatDelegate);
-
- if ((typeof userDelegate === 'undefined' ? 'undefined' : _typeof(userDelegate)) !== 'object' || userDelegate === null) {
- util$1.throw('"delegate" parameter must be an object');
- }
- this._userDelegate = userDelegate;
-
- if (!(templateElement instanceof Element) && templateElement !== null) {
- util$1.throw('"templateElement" parameter must be an instance of Element or null');
- }
- this._templateElement = templateElement;
- }
-
- createClass(LazyRepeatDelegate, [{
- key: 'hasRenderFunction',
-
-
- /**
- * @return {Boolean}
- */
- value: function hasRenderFunction() {
- return this._userDelegate._render instanceof Function;
- }
-
- /**
- * @return {void}
- */
-
- }, {
- key: '_render',
- value: function _render() {
- this._userDelegate._render.apply(this._userDelegate, arguments);
- }
-
- /**
- * @param {Number} index
- * @param {Function} done A function that take item object as parameter.
- */
-
- }, {
- key: 'loadItemElement',
- value: function loadItemElement(index, done) {
- if (this._userDelegate.loadItemElement instanceof Function) {
- this._userDelegate.loadItemElement(index, done);
- } else {
- var element = this._userDelegate.createItemContent(index, this._templateElement);
- if (!(element instanceof Element)) {
- util$1.throw('"createItemContent" must return an instance of Element');
- }
-
- done({ element: element });
- }
- }
-
- /**
- * @return {Number}
- */
-
- }, {
- key: 'countItems',
- value: function countItems() {
- var count = this._userDelegate.countItems();
- if (typeof count !== 'number') {
- util$1.throw('"countItems" must return a number');
- }
- return count;
- }
-
- /**
- * @param {Number} index
- * @param {Object} item
- * @param {Element} item.element
- */
-
- }, {
- key: 'updateItem',
- value: function updateItem(index, item) {
- if (this._userDelegate.updateItemContent instanceof Function) {
- this._userDelegate.updateItemContent(index, item);
- }
- }
-
- /**
- * @return {Number}
- */
-
- }, {
- key: 'calculateItemHeight',
- value: function calculateItemHeight(index) {
- if (this._userDelegate.calculateItemHeight instanceof Function) {
- var height = this._userDelegate.calculateItemHeight(index);
-
- if (typeof height !== 'number') {
- util$1.throw('"calculateItemHeight" must return a number');
- }
-
- return height;
- }
-
- return 0;
- }
-
- /**
- * @param {Number} index
- * @param {Object} item
- */
-
- }, {
- key: 'destroyItem',
- value: function destroyItem(index, item) {
- if (this._userDelegate.destroyItem instanceof Function) {
- this._userDelegate.destroyItem(index, item);
- }
- }
-
- /**
- * @return {void}
- */
-
- }, {
- key: 'destroy',
- value: function destroy() {
- if (this._userDelegate.destroy instanceof Function) {
- this._userDelegate.destroy();
- }
-
- this._userDelegate = this._templateElement = null;
- }
- }, {
- key: 'itemHeight',
- get: function get$$1() {
- return this._userDelegate.itemHeight;
- }
- }]);
- return LazyRepeatDelegate;
- }();
-
- /**
- * This class provide core functions for ons-lazy-repeat.
- */
- var LazyRepeatProvider = function () {
-
- /**
- * @param {Element} wrapperElement
- * @param {LazyRepeatDelegate} delegate
- */
- function LazyRepeatProvider(wrapperElement, delegate) {
- classCallCheck(this, LazyRepeatProvider);
-
- if (!(delegate instanceof LazyRepeatDelegate)) {
- util$1.throw('"delegate" parameter must be an instance of LazyRepeatDelegate');
- }
-
- this._wrapperElement = wrapperElement;
- this._delegate = delegate;
- this._insertIndex = this._wrapperElement.children[0] && this._wrapperElement.children[0].tagName === 'ONS-LAZY-REPEAT' ? 1 : 0;
-
- if (wrapperElement.tagName.toLowerCase() === 'ons-list') {
- wrapperElement.classList.add('lazy-list');
- }
-
- this._pageContent = this._findPageContentElement(wrapperElement);
-
- if (!this._pageContent) {
- util$1.throw('LazyRepeat must be descendant of a Page element');
- }
-
- this.lastScrollTop = this._pageContent.scrollTop;
- this.padding = 0;
- this._topPositions = [0];
- this._renderedItems = {};
-
- if (!this._delegate.itemHeight && !this._delegate.calculateItemHeight(0)) {
- this._unknownItemHeight = true;
- }
-
- this._addEventListeners();
- this._onChange();
- }
-
- createClass(LazyRepeatProvider, [{
- key: '_findPageContentElement',
- value: function _findPageContentElement(wrapperElement) {
- var pageContent = util$1.findParent(wrapperElement, '.page__content');
-
- if (pageContent) {
- return pageContent;
- }
-
- var page = util$1.findParent(wrapperElement, 'ons-page');
- if (page) {
- var content = util$1.findChild(page, '.content');
- if (content) {
- return content;
- }
- }
-
- return null;
- }
- }, {
- key: '_checkItemHeight',
- value: function _checkItemHeight(callback) {
- var _this = this;
-
- this._delegate.loadItemElement(0, function (item) {
- if (!_this._unknownItemHeight) {
- util$1.throw('Invalid state');
- }
-
- _this._wrapperElement.appendChild(item.element);
-
- var done = function done() {
- _this._delegate.destroyItem(0, item);
- item.element && item.element.remove();
- delete _this._unknownItemHeight;
- callback();
- };
-
- _this._itemHeight = item.element.offsetHeight;
-
- if (_this._itemHeight > 0) {
- done();
- return;
- }
-
- // retry to measure offset height
- // dirty fix for angular2 directive
- _this._wrapperElement.style.visibility = 'hidden';
- item.element.style.visibility = 'hidden';
-
- setImmediate(function () {
- _this._itemHeight = item.element.offsetHeight;
- if (_this._itemHeight == 0) {
- util$1.throw('Invalid state: "itemHeight" must be greater than zero');
- }
- _this._wrapperElement.style.visibility = '';
- done();
- });
- });
- }
- }, {
- key: '_countItems',
- value: function _countItems() {
- return this._delegate.countItems();
- }
- }, {
- key: '_getItemHeight',
- value: function _getItemHeight(i) {
- // Item is rendered
- if (this._renderedItems.hasOwnProperty(i)) {
- if (!this._renderedItems[i].hasOwnProperty('height')) {
- this._renderedItems[i].height = this._renderedItems[i].element.offsetHeight;
- }
- return this._renderedItems[i].height;
- }
-
- // Item is not rendered, scroll up
- if (this._topPositions[i + 1] && this._topPositions[i]) {
- return this._topPositions[i + 1] - this._topPositions[i];
- }
- // Item is not rendered, scroll down
- return this.staticItemHeight || this._delegate.calculateItemHeight(i);
- }
- }, {
- key: '_calculateRenderedHeight',
- value: function _calculateRenderedHeight() {
- var _this2 = this;
-
- return Object.keys(this._renderedItems).reduce(function (a, b) {
- return a + _this2._getItemHeight(+b);
- }, 0);
- }
- }, {
- key: '_onChange',
- value: function _onChange() {
- this._render();
- }
- }, {
- key: '_lastItemRendered',
- value: function _lastItemRendered() {
- return Math.max.apply(Math, toConsumableArray(Object.keys(this._renderedItems)));
- }
- }, {
- key: '_firstItemRendered',
- value: function _firstItemRendered() {
- return Math.min.apply(Math, toConsumableArray(Object.keys(this._renderedItems)));
- }
- }, {
- key: 'refresh',
- value: function refresh() {
- var forceRender = { forceScrollDown: true };
- var firstItemIndex = this._firstItemRendered();
-
- if (util$1.isInteger(firstItemIndex)) {
- this._wrapperElement.style.height = this._topPositions[firstItemIndex] + this._calculateRenderedHeight() + 'px';
- this.padding = this._topPositions[firstItemIndex];
- forceRender.forceFirstIndex = firstItemIndex;
- }
-
- this._removeAllElements();
- this._render(forceRender);
- this._wrapperElement.style.height = 'inherit';
- }
- }, {
- key: '_render',
- value: function _render() {
- var _this3 = this;
-
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$forceScrollDown = _ref.forceScrollDown,
- forceScrollDown = _ref$forceScrollDown === undefined ? false : _ref$forceScrollDown,
- forceFirstIndex = _ref.forceFirstIndex,
- forceLastIndex = _ref.forceLastIndex;
-
- if (this._unknownItemHeight) {
- return this._checkItemHeight(this._render.bind(this, arguments[0]));
- }
-
- var isScrollUp = !forceScrollDown && this.lastScrollTop > this._pageContent.scrollTop;
- this.lastScrollTop = this._pageContent.scrollTop;
- var keep = {};
-
- var offset = this._wrapperElement.getBoundingClientRect().top;
- var limit = 4 * window.innerHeight - offset;
- var count = this._countItems();
-
- var start = forceFirstIndex || Math.max(0, this._calculateStartIndex(offset) - 30); // Recalculate for 0 or undefined
- var i = start;
-
- for (var top = this._topPositions[i]; i < count && top < limit; i++) {
- if (i >= this._topPositions.length) {
- // perf optimization
- this._topPositions.length += 100;
- }
-
- this._topPositions[i] = top;
- top += this._getItemHeight(i);
- }
-
- if (this._delegate.hasRenderFunction && this._delegate.hasRenderFunction()) {
- return this._delegate._render(start, i, function () {
- _this3.padding = _this3._topPositions[start];
- });
- }
-
- if (isScrollUp) {
- for (var j = i - 1; j >= start; j--) {
- keep[j] = true;
- this._renderElement(j, isScrollUp);
- }
- } else {
- var lastIndex = forceLastIndex || Math.max.apply(Math, [i - 1].concat(toConsumableArray(Object.keys(this._renderedItems)))); // Recalculate for 0 or undefined
- for (var _j = start; _j <= lastIndex; _j++) {
- keep[_j] = true;
- this._renderElement(_j, isScrollUp);
- }
- }
-
- Object.keys(this._renderedItems).forEach(function (key) {
- return keep[key] || _this3._removeElement(key, isScrollUp);
- });
- }
-
- /**
- * @param {Number} index
- * @param {Boolean} isScrollUp
- */
-
- }, {
- key: '_renderElement',
- value: function _renderElement(index, isScrollUp) {
- var _this4 = this;
-
- var item = this._renderedItems[index];
- if (item) {
- this._delegate.updateItem(index, item); // update if it exists
- return;
- }
-
- this._delegate.loadItemElement(index, function (item) {
- if (isScrollUp) {
- _this4._wrapperElement.insertBefore(item.element, _this4._wrapperElement.children[_this4._insertIndex]);
- _this4.padding = _this4._topPositions[index];
- item.height = _this4._topPositions[index + 1] - _this4._topPositions[index];
- } else {
- _this4._wrapperElement.appendChild(item.element);
- }
-
- _this4._renderedItems[index] = item;
- });
- }
-
- /**
- * @param {Number} index
- * @param {Boolean} isScrollUp
- */
-
- }, {
- key: '_removeElement',
- value: function _removeElement(index) {
- var isScrollUp = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
-
- index = +index;
- var item = this._renderedItems[index];
- this._delegate.destroyItem(index, item);
-
- if (isScrollUp) {
- this._topPositions[index + 1] = undefined;
- } else {
- this.padding = this.padding + this._getItemHeight(index);
- }
-
- if (item.element.parentElement) {
- item.element.parentElement.removeChild(item.element);
- }
-
- delete this._renderedItems[index];
- }
- }, {
- key: '_removeAllElements',
- value: function _removeAllElements() {
- var _this5 = this;
-
- Object.keys(this._renderedItems).forEach(function (key) {
- return _this5._removeElement(key);
- });
- }
- }, {
- key: '_recalculateTopPositions',
- value: function _recalculateTopPositions(start, end) {
- for (var i = start; i <= end; i++) {
- this._topPositions[i + 1] = this._topPositions[i] + this._getItemHeight(i);
- }
- }
- }, {
- key: '_calculateStartIndex',
- value: function _calculateStartIndex(current) {
- var firstItemIndex = this._firstItemRendered();
- var lastItemIndex = this._lastItemRendered();
-
- // Fix for Safari scroll and Angular 2
- this._recalculateTopPositions(firstItemIndex, lastItemIndex);
-
- var start = 0;
- var end = this._countItems() - 1;
-
- // Binary search for index at top of screen so we can speed up rendering.
- for (;;) {
- var middle = Math.floor((start + end) / 2);
- var value = current + this._topPositions[middle];
-
- if (end < start) {
- return 0;
- } else if (value <= 0 && value + this._getItemHeight(middle) > 0) {
- return middle;
- } else if (isNaN(value) || value >= 0) {
- end = middle - 1;
- } else {
- start = middle + 1;
- }
- }
- }
- }, {
- key: '_debounce',
- value: function _debounce(func, wait, immediate) {
- var timeout = void 0;
- return function () {
- var _this6 = this,
- _arguments = arguments;
-
- var callNow = immediate && !timeout;
- clearTimeout(timeout);
- if (callNow) {
- func.apply(this, arguments);
- } else {
- timeout = setTimeout(function () {
- timeout = null;
- func.apply(_this6, _arguments);
- }, wait);
- }
- };
- }
- }, {
- key: '_doubleFireOnTouchend',
- value: function _doubleFireOnTouchend() {
- this._render();
- this._debounce(this._render.bind(this), 100);
- }
- }, {
- key: '_addEventListeners',
- value: function _addEventListeners() {
- util$1.bindListeners(this, ['_onChange', '_doubleFireOnTouchend']);
-
- if (platform.isIOS()) {
- this._boundOnChange = this._debounce(this._boundOnChange, 30);
- }
-
- this._pageContent.addEventListener('scroll', this._boundOnChange, true);
-
- if (platform.isIOS()) {
- util$1.addEventListener(this._pageContent, 'touchmove', this._boundOnChange, { capture: true, passive: true });
- this._pageContent.addEventListener('touchend', this._boundDoubleFireOnTouchend, true);
- }
-
- window.document.addEventListener('resize', this._boundOnChange, true);
- }
- }, {
- key: '_removeEventListeners',
- value: function _removeEventListeners() {
- this._pageContent.removeEventListener('scroll', this._boundOnChange, true);
-
- if (platform.isIOS()) {
- util$1.removeEventListener(this._pageContent, 'touchmove', this._boundOnChange, { capture: true, passive: true });
- this._pageContent.removeEventListener('touchend', this._boundDoubleFireOnTouchend, true);
- }
-
- window.document.removeEventListener('resize', this._boundOnChange, true);
- }
- }, {
- key: 'destroy',
- value: function destroy() {
- this._removeAllElements();
- this._delegate.destroy();
- this._parentElement = this._delegate = this._renderedItems = null;
- this._removeEventListeners();
- }
- }, {
- key: 'padding',
- get: function get$$1() {
- return parseInt(this._wrapperElement.style.paddingTop, 10);
- },
- set: function set$$1(newValue) {
- this._wrapperElement.style.paddingTop = newValue + 'px';
- }
- }, {
- key: 'staticItemHeight',
- get: function get$$1() {
- return this._delegate.itemHeight || this._itemHeight;
- }
- }]);
- return LazyRepeatProvider;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- /**
- * @element ons-lazy-repeat
- * @category list
- * @description
- * [en]
- * Using this component a list with millions of items can be rendered without a drop in performance.
- * It does that by "lazily" loading elements into the DOM when they come into view and
- * removing items from the DOM when they are not visible.
- * [/en]
- * [ja]
- * このコンポーネント内で描画されるアイテムのDOM要素の読み込みは、画面に見えそうになった時まで自動的に遅延され、
- * 画面から見えなくなった場合にはその要素は動的にアンロードされます。
- * このコンポーネントを使うことで、パフォーマンスを劣化させること無しに巨大な数の要素を描画できます。
- * [/ja]
- * @codepen QwrGBm
- * @tutorial vanilla/Reference/lazy-repeat
- * @seealso ons-list
- * [en]The `<ons-list>` element is used to render a list.[/en]
- * [ja]`<ons-list>`要素はリストを描画するのに使われます。[/ja]
- * @example
- * <script>
- * window.addEventListener('load', function() {
- * var lazyRepeat = document.querySelector('#list');
- * lazyRepeat.delegate = {
- * createItemContent: function(i, template) {
- * var dom = template.cloneNode(true);
- * dom.innerText = i;
- *
- * return dom;
- * },
- * countItems: function() {
- * return 10000000;
- * },
- * destroyItem: function(index, item) {
- * console.log('Destroyed item with index: ' + index);
- * }
- * };
- * });
- * </script>
- *
- * <ons-list id="list">
- * <ons-lazy-repeat>
- * <ons-list-item></ons-list-item>
- * </ons-lazy-repeat>
- * </ons-list>
- */
-
- var LazyRepeatElement = function (_BaseElement) {
- inherits(LazyRepeatElement, _BaseElement);
-
- function LazyRepeatElement() {
- classCallCheck(this, LazyRepeatElement);
- return possibleConstructorReturn(this, (LazyRepeatElement.__proto__ || Object.getPrototypeOf(LazyRepeatElement)).apply(this, arguments));
- }
-
- createClass(LazyRepeatElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- // not very good idea and also not documented
- if (this.hasAttribute('delegate')) {
- this.delegate = window[this.getAttribute('delegate')];
- }
- }
-
- /**
- * @property delegate
- * @type {Object}
- * @description
- * [en]Specify a delegate object to load and unload item elements.[/en]
- * [ja]要素のロード、アンロードなどの処理を委譲するオブジェクトを指定します。[/ja]
- */
-
- /**
- * @property delegate.createItemContent
- * @type {Function}
- * @description
- * [en]
- * This function should return a `HTMLElement`.
- *
- * To help rendering the element, the current index and a template is supplied as arguments. The template is the initial content of the `<ons-lazy-repeat>` element.
- * [/en]
- * [ja]
- * この関数は`HTMLElement`を返してください。
- * 要素を生成しやすくするために、現在のアイテムのインデックスとテンプレートが引数に渡されます。
- * このテンプレートは、`<ons-lazy-repeat>`要素のコンテンツが渡されます。
- * [/ja]
- */
-
- /**
- * @property delegate.countItems
- * @type {Function}
- * @description
- * [en]Should return the number of items in the list.[/en]
- * [ja]リスト内のアイテム数を返してください。[/ja]
- */
-
- /**
- * @property delegate.calculateItemHeight
- * @type {Function}
- * @description
- * [en]
- * Should return the height of an item. The index is provided as an argument.
- *
- * This is important when rendering lists where the items have different height.
- *
- * The function is optional and if it isn't present the height of the first item will be automatically calculated and used for all other items.
- * [/en]
- * [ja]
- * アイテムの高さ(ピクセル)を返してください。アイテムのインデックス値は引数で渡されます。
- * この関数は、それぞれのアイムが違った高さを持つリストをレンダリングする際に重要です。
- * この関数はオプショナルです。もしこの関数が無い場合には、
- * 最初のアイテムの高さが他のすべてのアイテムの高さとして利用されます。
- * [/ja]
- */
-
- /**
- * @property delegate.destroyItem
- * @type {Function}
- * @description
- * [en]
- * This function is used called when an item is removed from the DOM. The index and DOM element is provided as arguments.
- *
- * The function is optional but may be important in order to avoid memory leaks.
- * [/en]
- * [ja]
- * この関数は、あるアイテムがDOMツリーから除かれた時に呼び出されます。
- * アイテムのインデックス値とDOM要素が引数として渡されます。
- * この関数はオプショナルですが、各アイテムの後処理が必要な場合にはメモリーリークを避けるために重要です。
- * [/ja]
- */
-
- }, {
- key: 'refresh',
-
-
- /**
- * @method refresh
- * @signature refresh()
- * @description
- * [en]Refresh the list. Use this method when the data has changed.[/en]
- * [ja]リストを更新します。もしデータが変わった場合にはこのメソッドを使ってください。[/ja]
- */
- value: function refresh() {
- this._lazyRepeatProvider && this._lazyRepeatProvider.refresh();
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {}
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- if (this._lazyRepeatProvider) {
- this._lazyRepeatProvider.destroy();
- this._lazyRepeatProvider = null;
- }
- }
- }, {
- key: 'delegate',
- set: function set$$1(userDelegate) {
- this._lazyRepeatProvider && this._lazyRepeatProvider.destroy();
-
- if (!this._templateElement && this.children[0]) {
- this._templateElement = this.removeChild(this.children[0]);
- }
-
- var delegate = new LazyRepeatDelegate(userDelegate, this._templateElement || null);
- this._lazyRepeatProvider = new LazyRepeatProvider(this.parentElement, delegate);
- },
- get: function get$$1() {
- util$1.throw('No delegate getter');
- }
- }]);
- return LazyRepeatElement;
- }(BaseElement);
-
- internal$1.LazyRepeatDelegate = LazyRepeatDelegate;
- internal$1.LazyRepeatProvider = LazyRepeatProvider;
-
- onsElements.LazyRepeat = LazyRepeatElement;
- customElements.define('ons-lazy-repeat', LazyRepeatElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$4 = 'list-header';
- var scheme$8 = { '': 'list-header--*' };
-
- /**
- * @element ons-list-header
- * @category list
- * @description
- * [en]Header element for list items. Must be put inside the `<ons-list>` component.[/en]
- * [ja]リスト要素に使用するヘッダー用コンポーネント。ons-listと共に使用します。[/ja]
- * @seealso ons-list
- * [en]The `<ons-list>` component[/en]
- * [ja]ons-listコンポーネント[/ja]
- * @seealso ons-list-item
- * [en]The `<ons-list-item>` component[/en]
- * [ja]ons-list-itemコンポーネント[/ja]
- * @codepen yxcCt
- * @tutorial vanilla/Reference/list
- * @modifier material
- * [en]Display a Material Design list header.[/en]
- * [ja][/ja]
- * @example
- * <ons-list>
- * <ons-list-header>Header Text</ons-list-header>
- * <ons-list-item>Item</ons-list-item>
- * <ons-list-item>Item</ons-list-item>
- * </ons-list>
- */
-
- var ListHeaderElement = function (_BaseElement) {
- inherits(ListHeaderElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the list header.[/en]
- * [ja]ヘッダーの表現を指定します。[/ja]
- */
-
- function ListHeaderElement() {
- classCallCheck(this, ListHeaderElement);
-
- var _this = possibleConstructorReturn(this, (ListHeaderElement.__proto__ || Object.getPrototypeOf(ListHeaderElement)).call(this));
-
- _this._compile();
- return _this;
- }
-
- createClass(ListHeaderElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$4);
- ModifierUtil.initModifier(this, scheme$8);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$4, scheme$8);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$8);
- break;
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return ListHeaderElement;
- }(BaseElement);
-
- onsElements.ListHeader = ListHeaderElement;
- customElements.define('ons-list-header', ListHeaderElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$5 = 'list-title';
- var scheme$9 = { '': 'list-title--*' };
-
- /**
- * @element ons-list-title
- * @category list
- * @description
- * [en]Represents a list title.[/en]
- * [ja]リストのタイトルを表現します。[/ja]
- * @example
- * <ons-list-title>List Title</ons-list-title>
- * <ons-list>
- * <ons-list-item>Item</ons-list-item>
- * </ons-list>
- * @modifier material
- * [en]Display a Material Design list title.[/en]
- * [ja][/ja]
- */
-
- var ListTitleElement = function (_BaseElement) {
- inherits(ListTitleElement, _BaseElement);
-
- function ListTitleElement() {
- classCallCheck(this, ListTitleElement);
-
- var _this = possibleConstructorReturn(this, (ListTitleElement.__proto__ || Object.getPrototypeOf(ListTitleElement)).call(this));
-
- _this._compile();
- return _this;
- }
-
- createClass(ListTitleElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$5);
- ModifierUtil.initModifier(this, scheme$9);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$5, scheme$9);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$9);
- break;
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return ListTitleElement;
- }(BaseElement);
-
- onsElements.ListTitle = ListTitleElement;
- customElements.define('ons-list-title', ListTitleElement);
-
- /*
- Copyright 2013-2018 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var ListItemAnimator = function (_BaseAnimator) {
- inherits(ListItemAnimator, _BaseAnimator);
-
- function ListItemAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, ListItemAnimator);
- return possibleConstructorReturn(this, (ListItemAnimator.__proto__ || Object.getPrototypeOf(ListItemAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- createClass(ListItemAnimator, [{
- key: 'showExpansion',
- value: function showExpansion(listItem, callback) {
- callback();
- }
- }, {
- key: 'hideExpansion',
- value: function hideExpansion(listItem, callback) {
- callback();
- }
- }]);
- return ListItemAnimator;
- }(BaseAnimator);
-
- var SlideListItemAnimator = function (_ListItemAnimator) {
- inherits(SlideListItemAnimator, _ListItemAnimator);
-
- function SlideListItemAnimator() {
- classCallCheck(this, SlideListItemAnimator);
- return possibleConstructorReturn(this, (SlideListItemAnimator.__proto__ || Object.getPrototypeOf(SlideListItemAnimator)).apply(this, arguments));
- }
-
- createClass(SlideListItemAnimator, [{
- key: 'showExpansion',
- value: function showExpansion(listItem, callback) {
- this._animateExpansion(listItem, true, callback);
- }
- }, {
- key: 'hideExpansion',
- value: function hideExpansion(listItem, callback) {
- this._animateExpansion(listItem, false, callback);
- }
- }, {
- key: '_animateExpansion',
- value: function _animateExpansion(listItem, shouldOpen, callback) {
- var _animit;
-
- // To animate the opening of the expansion panel correctly, we need to know its
- // height. To calculate this, we set its height to auto, and then get the computed
- // height and padding. Once this is done, we set the height back to its original value.
- var oldHeight = listItem.expandableContent.style.height;
- var oldDisplay = listItem.expandableContent.style.display;
- listItem.expandableContent.style.height = 'auto';
- listItem.expandableContent.style.display = 'block';
- var computedStyle = window.getComputedStyle(listItem.expandableContent);
-
- var expansionOpenTransition = [{ height: 0, paddingTop: 0, paddingBottom: 0 }, {
- height: computedStyle.height,
- paddingTop: computedStyle.paddingTop,
- paddingBottom: computedStyle.paddingBottom
- }];
- var iconOpenTransition = [{ transform: 'rotate(45deg)' }, { transform: 'rotate(225deg)' }];
-
- // Now that we have the values we need, reset the height back to its original state
- listItem.expandableContent.style.height = oldHeight;
-
- (_animit = Animit(listItem.expandableContent, { duration: this.duration, property: 'height padding-top padding-bottom' })).default.apply(_animit, toConsumableArray(shouldOpen ? expansionOpenTransition : expansionOpenTransition.reverse())).play(function () {
- listItem.expandableContent.style.display = oldDisplay;
- callback && callback();
- });
-
- if (listItem.expandChevron) {
- var _animit2;
-
- (_animit2 = Animit(listItem.expandChevron, { duration: this.duration, property: 'transform' })).default.apply(_animit2, toConsumableArray(shouldOpen ? iconOpenTransition : iconOpenTransition.reverse())).play();
- }
- }
- }]);
- return SlideListItemAnimator;
- }(ListItemAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$6 = 'list-item';
- var scheme$10 = {
- '.list-item': 'list-item--*',
- '.list-item__left': 'list-item--*__left',
- '.list-item__center': 'list-item--*__center',
- '.list-item__right': 'list-item--*__right',
- '.list-item__label': 'list-item--*__label',
- '.list-item__title': 'list-item--*__title',
- '.list-item__subtitle': 'list-item--*__subtitle',
- '.list-item__thumbnail': 'list-item--*__thumbnail',
- '.list-item__icon': 'list-item--*__icon'
- };
-
- var _animatorDict$3 = {
- 'default': SlideListItemAnimator,
- 'none': ListItemAnimator
- };
-
- /**
- * @element ons-list-item
- * @category list
- * @modifier tappable
- * [en]Make the list item change appearance when it's tapped. On iOS it is better to use the "tappable" and "tap-background-color" attribute for better behavior when scrolling.[/en]
- * [ja]タップやクリックした時に効果が表示されるようになります。[/ja]
- * @modifier chevron
- * [en]Display a chevron at the right end of the list item and make it change appearance when tapped.[/en]
- * [ja][/ja]
- * @modifier longdivider
- * [en]Displays a long horizontal divider between items.[/en]
- * [ja][/ja]
- * @modifier nodivider
- * [en]Removes the divider between list items.[/en]
- * [ja][/ja]
- * @modifier material
- * [en]Display a Material Design list item.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * Component that represents each item in a list. The list item is composed of four parts that are represented with the `left`, `center`, `right` and `expandable-content` classes. These classes can be used to ensure that the content of the list items is properly aligned.
- *
- * ```
- * <ons-list-item>
- * <div class="left">Left</div>
- * <div class="center">Center</div>
- * <div class="right">Right</div>
- * <div class="expandable-content">Expandable content</div>
- * </ons-list-item>
- * ```
- *
- * There are also a number of classes (prefixed with `list-item__*`) that help when putting things like icons and thumbnails into the list items.
- * [/en]
- * [ja][/ja]
- * @seealso ons-list
- * [en]ons-list component[/en]
- * [ja]ons-listコンポーネント[/ja]
- * @seealso ons-list-header
- * [en]ons-list-header component[/en]
- * [ja]ons-list-headerコンポーネント[/ja]
- * @codepen yxcCt
- * @tutorial vanilla/Reference/list
- * @example
- * <ons-list-item>
- * <div class="left">
- * <ons-icon icon="md-face" class="list-item__icon"></ons-icon>
- * </div>
- * <div class="center">
- * <div class="list-item__title">Title</div>
- * <div class="list-item__subtitle">Subtitle</div>
- * </div>
- * <div class="right">
- * <ons-switch></ons-switch>
- * </div>
- * </ons-list-item>
- */
-
- var ListItemElement = function (_BaseElement) {
- inherits(ListItemElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the list item.[/en]
- * [ja]各要素の表現を指定します。[/ja]
- */
-
- /**
- * @attribute lock-on-drag
- * @type {String}
- * @description
- * [en]Prevent vertical scrolling when the user drags horizontally.[/en]
- * [ja]この属性があると、ユーザーがこの要素を横方向にドラッグしている時に、縦方向のスクロールが起きないようになります。[/ja]
- */
-
- /**
- * @attribute tappable
- * @type {Boolean}
- * @description
- * [en]Makes the element react to taps. `prevent-tap` attribute can be added to child elements like buttons or inputs to prevent this effect. `ons-*` elements are ignored by default.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute tap-background-color
- * @type {Color}
- * @description
- * [en] Changes the background color when tapped. For this to work, the attribute "tappable" needs to be set. The default color is "#d9d9d9". It will display as a ripple effect on Android.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute expandable
- * @type {Boolean}
- * @description
- * [en]Makes the element able to be expanded to reveal extra content. For this to work, the expandable content must be defined in `div.expandable-content`.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]The animation used when showing and hiding the expandable content. Can be either `"default"` or `"none"`.[/en]
- * [ja][/ja]
- */
-
- function ListItemElement() {
- classCallCheck(this, ListItemElement);
-
- var _this = possibleConstructorReturn(this, (ListItemElement.__proto__ || Object.getPrototypeOf(ListItemElement)).call(this));
-
- _this._animatorFactory = _this._updateAnimatorFactory();
- _this.toggleExpansion = _this.toggleExpansion.bind(_this);
-
- // Elements ignored when tapping
- var re = /^ons-(?!col$|row$|if$)/i;
- _this._shouldIgnoreTap = function (e) {
- return e.hasAttribute('prevent-tap') || re.test(e.tagName);
- };
-
- // show and hide functions for Vue hidable mixin
- _this.show = _this.showExpansion;
- _this.hide = _this.hideExpansion;
-
- contentReady(_this, function () {
- _this._compile();
- });
- return _this;
- }
-
- /**
- * Compiles the list item.
- *
- * Various elements are allowed in the body of a list item:
- *
- * - div.left, div.right, and div.center are allowed as direct children
- * - if div.center is not defined, anything that isn't div.left, div.right or div.expandable-content will be put in a div.center
- * - if div.center is defined, anything that isn't div.left, div.right or div.expandable-content will be ignored
- * - if list item has expandable attribute:
- * - div.expandable-content is allowed as a direct child
- * - div.top is allowed as direct child
- * - if div.top is defined, anything that isn't div.expandable-content should be inside div.top - anything else will be ignored
- * - if div.right is not defined, a div.right will be created with a drop-down chevron
- *
- * See the tests for examples.
- */
-
-
- createClass(ListItemElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$6);
-
- var top = void 0,
- expandableContent = void 0;
- var topContent = [];
- Array.from(this.childNodes).forEach(function (node) {
- if (node.nodeType !== Node.ELEMENT_NODE) {
- topContent.push(node);
- } else if (node.classList.contains('top')) {
- top = node;
- } else if (node.classList.contains('expandable-content')) {
- expandableContent = node;
- } else {
- topContent.push(node);
- }
-
- if (node.nodeName !== 'ONS-RIPPLE') {
- node.remove();
- }
- });
- topContent = top ? Array.from(top.childNodes) : topContent;
-
- var left = void 0,
- right = void 0,
- center = void 0;
- var centerContent = [];
- topContent.forEach(function (node) {
- if (node.nodeType !== Node.ELEMENT_NODE) {
- centerContent.push(node);
- } else if (node.classList.contains('left')) {
- left = node;
- } else if (node.classList.contains('right')) {
- right = node;
- } else if (node.classList.contains('center')) {
- center = node;
- } else {
- centerContent.push(node);
- }
- });
-
- if (this.hasAttribute('expandable')) {
- this.classList.add('list-item--expandable');
-
- if (!top) {
- top = document.createElement('div');
- top.classList.add('top');
- }
- top.classList.add('list-item__top');
- this.appendChild(top);
- this._top = top;
-
- if (expandableContent) {
- expandableContent.classList.add('list-item__expandable-content');
- this.appendChild(expandableContent);
- }
-
- if (!right) {
- right = document.createElement('div');
- right.classList.add('list-item__right', 'right');
-
- // We cannot use a pseudo-element for this chevron, as we cannot animate it using
- // JS. So, we make a chevron span instead.
- var chevron = document.createElement('span');
- chevron.classList.add('list-item__expand-chevron');
- right.appendChild(chevron);
- }
- } else {
- top = this;
- }
-
- if (!center) {
- center = document.createElement('div');
- center.classList.add('center');
- centerContent.forEach(function (node) {
- return center.appendChild(node);
- });
- }
- center.classList.add('list-item__center');
- top.appendChild(center);
-
- if (left) {
- left.classList.add('list-item__left');
- top.appendChild(left);
- }
- if (right) {
- right.classList.add('list-item__right');
- top.appendChild(right);
- }
-
- util$1.updateRipple(this);
- ModifierUtil.initModifier(this, scheme$10);
- }
-
- /**
- * @method showExpansion
- * @signature showExpansion()
- * @description
- * [en]Show the expandable content if the element is expandable.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'showExpansion',
- value: function showExpansion() {
- var _this2 = this;
-
- if (this.hasAttribute('expandable') && !this._expanding) {
- this.expanded = true;
- this._expanding = true;
-
- var animator = this._animatorFactory.newAnimator();
- animator.showExpansion(this, function () {
- _this2.classList.add('expanded');
- _this2._expanding = false;
- });
- }
- }
-
- /**
- * @method hideExpansion
- * @signature hideExpansion()
- * @description
- * [en]Hide the expandable content if the element expandable.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'hideExpansion',
- value: function hideExpansion() {
- var _this3 = this;
-
- if (this.hasAttribute('expandable') && !this._expanding) {
- this.expanded = false;
- this._expanding = true;
-
- var animator = this._animatorFactory.newAnimator();
- animator.hideExpansion(this, function () {
- _this3.classList.remove('expanded');
- _this3._expanding = false;
- });
- }
- }
- }, {
- key: 'toggleExpansion',
- value: function toggleExpansion() {
- this.classList.contains('expanded') ? this.hideExpansion() : this.showExpansion();
- this.dispatchEvent(new Event('expansion'));
- }
- }, {
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- return new AnimatorFactory({
- animators: _animatorDict$3,
- baseClass: ListItemAnimator,
- baseClassName: 'ListItemAnimator',
- defaultAnimation: this.getAttribute('animation') || 'default'
- });
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$6, scheme$10);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$10);
- break;
- case 'ripple':
- util$1.updateRipple(this);
- break;
- case 'animation':
- this._animatorFactory = this._updateAnimatorFactory();
- break;
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this4 = this;
-
- contentReady(this, function () {
- _this4._setupListeners(true);
- _this4._originalBackgroundColor = _this4.style.backgroundColor;
- _this4.tapped = false;
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._setupListeners(false);
- }
- }, {
- key: '_setupListeners',
- value: function _setupListeners(add) {
- var action = (add ? 'add' : 'remove') + 'EventListener';
- util$1[action](this, 'touchstart', this._onTouch, { passive: true });
- util$1[action](this, 'touchmove', this._onRelease, { passive: true });
- this[action]('touchcancel', this._onRelease);
- this[action]('touchend', this._onRelease);
- this[action]('touchleave', this._onRelease);
- this[action]('drag', this._onDrag);
- this[action]('mousedown', this._onTouch);
- this[action]('mouseup', this._onRelease);
- this[action]('mouseout', this._onRelease);
-
- if (this._top) {
- this._top[action]('click', this.toggleExpansion);
- }
- }
- }, {
- key: '_onDrag',
- value: function _onDrag(event) {
- var gesture = event.gesture;
- // Prevent vertical scrolling if the users pans left or right.
- if (this.hasAttribute('lock-on-drag') && ['left', 'right'].indexOf(gesture.direction) > -1) {
- gesture.preventDefault();
- }
- }
- }, {
- key: '_onTouch',
- value: function _onTouch(e) {
- var _this5 = this;
-
- if (this.tapped || this !== e.target && (this._shouldIgnoreTap(e.target) || util$1.findParent(e.target, this._shouldIgnoreTap, function (p) {
- return p === _this5;
- }))) {
- return; // Ignore tap
- }
-
- this.tapped = true;
- var touchStyle = { transition: 'background-color 0.0s linear 0.02s, box-shadow 0.0s linear 0.02s' };
-
- if (this.hasAttribute('tappable')) {
- if (this.style.backgroundColor) {
- this._originalBackgroundColor = this.style.backgroundColor;
- }
-
- touchStyle.backgroundColor = this.getAttribute('tap-background-color') || '#d9d9d9';
- touchStyle.boxShadow = '0px -1px 0px 0px ' + touchStyle.backgroundColor;
- }
-
- styler(this, touchStyle);
- }
- }, {
- key: '_onRelease',
- value: function _onRelease() {
- this.tapped = false;
- this.style.backgroundColor = this._originalBackgroundColor || '';
- styler.clear(this, 'transition boxShadow');
- }
- }, {
- key: 'expandableContent',
- get: function get$$1() {
- return this.querySelector('.list-item__expandable-content');
- }
- }, {
- key: 'expandChevron',
- get: function get$$1() {
- return this.querySelector('.list-item__expand-chevron');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class', 'ripple', 'animation'];
- }
- }]);
- return ListItemElement;
- }(BaseElement);
-
- onsElements.ListItem = ListItemElement;
- customElements.define('ons-list-item', ListItemElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$7 = 'list';
- var scheme$11 = { '': 'list--*' };
-
- /**
- * @element ons-list
- * @category list
- * @modifier inset
- * [en]Inset list that doesn't cover the whole width of the parent.[/en]
- * [ja]親要素の画面いっぱいに広がらないリストを表示します。[/ja]
- * @modifier noborder
- * [en]A list with no borders at the top and bottom.[/en]
- * [ja]リストの上下のボーダーが無いリストを表示します。[/ja]
- * @description
- * [en]Component to define a list, and the container for ons-list-item(s).[/en]
- * [ja]リストを表現するためのコンポーネント。ons-list-itemのコンテナとして使用します。[/ja]
- * @seealso ons-list-item
- * [en]ons-list-item component[/en]
- * [ja]ons-list-itemコンポーネント[/ja]
- * @seealso ons-list-header
- * [en]ons-list-header component[/en]
- * [ja]ons-list-headerコンポーネント[/ja]
- * @seealso ons-lazy-repeat
- * [en]ons-lazy-repeat component[/en]
- * [ja]ons-lazy-repeatコンポーネント[/ja]
- * @codepen yxcCt
- * @tutorial vanilla/Reference/list
- * @example
- * <ons-list>
- * <ons-list-header>Header Text</ons-list-header>
- * <ons-list-item>Item</ons-list-item>
- * <ons-list-item>Item</ons-list-item>
- * </ons-list>
- */
-
- var ListElement = function (_BaseElement) {
- inherits(ListElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the list.[/en]
- * [ja]リストの表現を指定します。[/ja]
- */
-
- function ListElement() {
- classCallCheck(this, ListElement);
-
- var _this = possibleConstructorReturn(this, (ListElement.__proto__ || Object.getPrototypeOf(ListElement)).call(this));
-
- _this._compile();
- return _this;
- }
-
- createClass(ListElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$7);
- ModifierUtil.initModifier(this, scheme$11);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$7, scheme$11);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$11);
- break;
- }
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return ListElement;
- }(BaseElement);
-
- onsElements.List = ListElement;
- customElements.define('ons-list', ListElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var INPUT_ATTRIBUTES = ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'disabled', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'step', 'validator', 'value'];
-
- var BaseInputElement = function (_BaseElement) {
- inherits(BaseInputElement, _BaseElement);
- createClass(BaseInputElement, [{
- key: '_update',
- value: function _update() {} // Optionally implemented
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- util$1.throwMember();
- }
- }, {
- key: '_template',
- get: function get$$1() {
- util$1.throwMember();
- }
- }, {
- key: 'type',
- get: function get$$1() {
- util$1.throwMember();
- }
- }]);
-
- function BaseInputElement() {
- classCallCheck(this, BaseInputElement);
-
- var _this = possibleConstructorReturn(this, (BaseInputElement.__proto__ || Object.getPrototypeOf(BaseInputElement)).call(this));
-
- if (_this.constructor === BaseInputElement) {
- util$1.throwAbstract();
- }
-
- contentReady(_this, function () {
- return _this._compile();
- });
- _this._boundDelegateEvent = _this._delegateEvent.bind(_this);
- return _this;
- }
-
- createClass(BaseInputElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this._defaultClassName && this.classList.add(this._defaultClassName);
-
- if (this.children.length !== 0) {
- return;
- }
-
- this.appendChild(util$1.createFragment(this._template));
-
- this._setInputId();
-
- this._updateBoundAttributes();
-
- ModifierUtil.initModifier(this, this._scheme);
- }
- }, {
- key: '_updateBoundAttributes',
- value: function _updateBoundAttributes() {
- var _this2 = this;
-
- INPUT_ATTRIBUTES.forEach(function (attr) {
- if (_this2.hasAttribute(attr)) {
- _this2._input.setAttribute(attr, _this2.getAttribute(attr));
- } else {
- _this2._input.removeAttribute(attr);
- }
- });
-
- this._update();
- }
- }, {
- key: '_delegateEvent',
- value: function _delegateEvent(event) {
- var e = new CustomEvent(event.type, {
- bubbles: false,
- cancelable: true
- });
-
- return this.dispatchEvent(e);
- }
- }, {
- key: '_setInputId',
- value: function _setInputId() {
- if (this.hasAttribute('input-id')) {
- this._input.id = this.getAttribute('input-id');
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this3 = this;
-
- contentReady(this, function () {
- _this3._input.addEventListener('focus', _this3._boundDelegateEvent);
- _this3._input.addEventListener('blur', _this3._boundDelegateEvent);
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- var _this4 = this;
-
- contentReady(this, function () {
- _this4._input.removeEventListener('focus', _this4._boundDelegateEvent);
- _this4._input.removeEventListener('blur', _this4._boundDelegateEvent);
- });
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this5 = this;
-
- switch (name) {
- case 'modifier':
- contentReady(this, function () {
- return ModifierUtil.onModifierChanged(last, current, _this5, _this5._scheme);
- });
- break;
- case 'input-id':
- contentReady(this, function () {
- return _this5._setInputId();
- });
- break;
- case 'class':
- util$1.restoreClass(this, this._defaultClassName, this._scheme);
- break;
- }
-
- if (INPUT_ATTRIBUTES.indexOf(name) >= 0) {
- contentReady(this, function () {
- return _this5._updateBoundAttributes();
- });
- }
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return '';
- }
- }, {
- key: '_input',
- get: function get$$1() {
- return this.querySelector('input');
- }
- }, {
- key: 'value',
- get: function get$$1() {
- return this._input === null ? this.getAttribute('value') : this._input.value;
- },
- set: function set$$1(val) {
- var _this6 = this;
-
- contentReady(this, function () {
- if (val instanceof Date) {
- val = val.toISOString().substring(0, 10);
- }
- _this6._input.value = val;
- _this6._update();
- });
- }
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'input-id', 'class'].concat(INPUT_ATTRIBUTES);
- }
- }]);
- return BaseInputElement;
- }(BaseElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var scheme$12 = {
- '.text-input': 'text-input--*',
- '.text-input__label': 'text-input--*__label'
- };
-
- /**
- * @element ons-input
- * @category form
- * @modifier material
- * [en]Displays a Material Design input.[/en]
- * [ja][/ja]
- * @modifier underbar
- * [en]Displays a horizontal line underneath a text input.[/en]
- * [ja][/ja]
- * @modifier transparent
- * [en]Displays a transparent input. Works for Material Design.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * An input element. The `type` attribute can be used to change the input type. All text input types are supported.
- *
- * The component will automatically render as a Material Design input on Android devices.
- *
- * Most attributes that can be used for a normal `<input>` element can also be used on the `<ons-input>` element.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/input
- * @seealso ons-checkbox
- * [en]The `<ons-checkbox>` element is used to display a checkbox.[/en]
- * [ja][/ja]
- * @seealso ons-radio
- * [en]The `<ons-radio>` element is used to display a radio button.[/en]
- * [ja][/ja]
- * @seealso ons-range
- * [en]The `<ons-range>` element is used to display a range slider.[/en]
- * [ja][/ja]
- * @seealso ons-switch
- * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
- * [ja][/ja]
- * @seealso ons-select
- * [en]The `<ons-select>` element is used to display a select box.[/en]
- * [ja][/ja]
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- * <ons-input placeholder="Username" float></ons-input>
- */
-
- var InputElement = function (_BaseInputElement) {
- inherits(InputElement, _BaseInputElement);
-
- function InputElement() {
- classCallCheck(this, InputElement);
-
- var _this = possibleConstructorReturn(this, (InputElement.__proto__ || Object.getPrototypeOf(InputElement)).call(this));
-
- _this._boundOnInput = _this._update.bind(_this);
- _this._boundOnFocusin = _this._update.bind(_this);
- return _this;
- }
-
- /* Inherited props */
-
- createClass(InputElement, [{
- key: '_update',
- value: function _update() {
- this._updateLabel();
- this._updateLabelClass();
- }
- }, {
- key: '_updateLabel',
-
-
- /* Own props */
-
- value: function _updateLabel() {
- var label = this.getAttribute('placeholder') || '';
-
- if (typeof this._helper.textContent !== 'undefined') {
- this._helper.textContent = label;
- } else {
- this._helper.innerText = label;
- }
- }
- }, {
- key: '_updateLabelClass',
- value: function _updateLabelClass() {
- if (this.value === '') {
- this._helper.classList.remove('text-input--material__label--active');
- } else {
- this._helper.classList.add('text-input--material__label--active');
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- get(InputElement.prototype.__proto__ || Object.getPrototypeOf(InputElement.prototype), 'connectedCallback', this).call(this);
-
- contentReady(this, function () {
- _this2._input.addEventListener('input', _this2._boundOnInput);
- _this2._input.addEventListener('focusin', _this2._boundOnFocusin);
- });
-
- var type = this.getAttribute('type');
- if (['checkbox', 'radio'].indexOf(type) >= 0) {
- util$1.warn('Warn: <ons-input type="' + type + '"> is deprecated since v2.4.0. Use <ons-' + type + '> instead.');
- }
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- var _this3 = this;
-
- get(InputElement.prototype.__proto__ || Object.getPrototypeOf(InputElement.prototype), 'disconnectedCallback', this).call(this);
-
- contentReady(this, function () {
- _this3._input.removeEventListener('input', _this3._boundOnInput);
- _this3._input.removeEventListener('focusin', _this3._boundOnFocusin);
- });
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this4 = this;
-
- switch (name) {
- case 'type':
- contentReady(this, function () {
- return _this4._input.setAttribute('type', _this4.type);
- });
- break;
- default:
- get(InputElement.prototype.__proto__ || Object.getPrototypeOf(InputElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
- }
-
- /**
- * @attribute placeholder
- * @type {String}
- * @description
- * [en]Placeholder text. In Material Design, this placeholder will be a floating label.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute float
- * @description
- * [en]If this attribute is present, the placeholder will be animated in Material Design.[/en]
- * [ja]この属性が設定された時、ラベルはアニメーションするようになります。[/ja]
- */
-
- /**
- * @attribute type
- * @type {String}
- * @description
- * [en]
- * Specify the input type. This is the same as the "type" attribute for normal inputs. It expects strict text types such as `text`, `password`, etc. For checkbox, radio button, select or range, please have a look at the corresponding elements.
- *
- * Please take a look at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-type) for an exhaustive list of possible values. Depending on the platform and browser version some of these might not work.
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute input-id
- * @type {String}
- * @description
- * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property value
- * @type {String}
- * @description
- * [en]The current value of the input.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the input is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$12;
- }
- }, {
- key: '_template',
- get: function get$$1() {
- return '\n <input type="' + this.type + '" class="text-input">\n <span class="text-input__label"></span>\n ';
- }
- }, {
- key: 'type',
- get: function get$$1() {
- var type = this.getAttribute('type');
- return ['checkbox', 'radio'].indexOf(type) < 0 && type || 'text';
- }
- }, {
- key: '_helper',
- get: function get$$1() {
- return this.querySelector('span');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return [].concat(toConsumableArray(get(InputElement.__proto__ || Object.getPrototypeOf(InputElement), 'observedAttributes', this)), ['type']);
- }
- }]);
- return InputElement;
- }(BaseInputElement);
-
- onsElements.Input = InputElement;
- customElements.define('ons-input', InputElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var BaseCheckboxElement = function (_BaseInputElement) {
- inherits(BaseCheckboxElement, _BaseInputElement);
-
- function BaseCheckboxElement() {
- classCallCheck(this, BaseCheckboxElement);
-
- var _this = possibleConstructorReturn(this, (BaseCheckboxElement.__proto__ || Object.getPrototypeOf(BaseCheckboxElement)).call(this));
-
- if (_this.constructor === BaseCheckboxElement) {
- util.throwAbstract();
- }
-
- contentReady(_this, function () {
- _this.attributeChangedCallback('checked', null, _this.getAttribute('checked'));
- });
- return _this;
- }
-
- /* Inherited props */
-
- createClass(BaseCheckboxElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'checked':
- this.checked = current !== null;
- break;
- default:
- get(BaseCheckboxElement.prototype.__proto__ || Object.getPrototypeOf(BaseCheckboxElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
- }
- }, {
- key: '_template',
- get: function get$$1() {
- return '\n <input type="' + this.type + '" class="' + this._defaultClassName + '__input">\n <span class="' + this._defaultClassName + '__checkmark"></span>\n ';
- }
-
- /* Own props */
-
- }, {
- key: '_helper',
- get: function get$$1() {
- return this.querySelector('span');
- }
- }, {
- key: 'checked',
- get: function get$$1() {
- return this._input.checked;
- },
- set: function set$$1(val) {
- var _this2 = this;
-
- contentReady(this, function () {
- _this2._input.checked = val;
- });
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return [].concat(toConsumableArray(get(BaseCheckboxElement.__proto__ || Object.getPrototypeOf(BaseCheckboxElement), 'observedAttributes', this)), ['checked']);
- }
- }]);
- return BaseCheckboxElement;
- }(BaseInputElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var scheme$13 = {
- '.checkbox': 'checkbox--*',
- '.checkbox__input': 'checkbox--*__input',
- '.checkbox__checkmark': 'checkbox--*__checkmark'
- };
-
- /**
- * @element ons-checkbox
- * @category form
- * @modifier material
- * [en]Displays a Material Design checkbox.[/en]
- * [ja][/ja]
- * @modifier noborder
- * [en]iOS borderless checkbox.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * A checkbox element. The component will automatically render as a Material Design checkbox on Android devices.
- *
- * Most attributes that can be used for a normal `<input type="checkbox">` element can also be used on the `<ons-checkbox>` element.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/checkbox
- * @seealso ons-switch
- * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
- * [ja][/ja]
- * @seealso ons-radio
- * [en]The `<ons-radio>` element is used to display a radio button.[/en]
- * [ja][/ja]
- * @seealso ons-input
- * [en]The `<ons-input>` element is used to display a text input.[/en]
- * [ja][/ja]
- * @seealso ons-search-input
- * [en]The `<ons-search-input>` element is used to display a search input.[/en]
- * [ja][/ja]
- * @seealso ons-range
- * [en]The `<ons-range>` element is used to display a range slider.[/en]
- * [ja][/ja]
- * @seealso ons-select
- * [en]The `<ons-select>` element is used to display a select box.[/en]
- * [ja][/ja]
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- * <ons-checkbox checked></ons-checkbox>
- */
-
- var CheckboxElement = function (_BaseCheckboxElement) {
- inherits(CheckboxElement, _BaseCheckboxElement);
-
- function CheckboxElement() {
- classCallCheck(this, CheckboxElement);
- return possibleConstructorReturn(this, (CheckboxElement.__proto__ || Object.getPrototypeOf(CheckboxElement)).apply(this, arguments));
- }
-
- createClass(CheckboxElement, [{
- key: '_scheme',
- get: function get$$1() {
- return scheme$13;
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'checkbox';
- }
- }, {
- key: 'type',
- get: function get$$1() {
- return 'checkbox';
- }
-
- /**
- * @attribute input-id
- * @type {String}
- * @description
- * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property value
- * @type {String}
- * @description
- * [en]The current value of the checkbox.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property checked
- * @type {Boolean}
- * @description
- * [en]Whether the checkbox is checked or not.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the checkbox is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }]);
- return CheckboxElement;
- }(BaseCheckboxElement);
-
- onsElements.Checkbox = CheckboxElement;
- customElements.define('ons-checkbox', CheckboxElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var scheme$14 = {
- '.radio-button': 'radio-button--*',
- '.radio-button__input': 'radio-button--*__input',
- '.radio-button__checkmark': 'radio-button--*__checkmark'
- };
-
- /**
- * @element ons-radio
- * @category form
- * @modifier material
- * [en]Displays a Material Design radio button.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * A radio button element. The component will automatically render as a Material Design radio button on Android devices.
- *
- * Most attributes that can be used for a normal `<input type="radio">` element can also be used on the `<ons-radio>` element.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/radio
- * @seealso ons-select
- * [en]The `<ons-select>` element is used to display a select box.[/en]
- * [ja][/ja]
- * @seealso ons-checkbox
- * [en]The `<ons-checkbox>` element is used to display a checkbox.[/en]
- * [ja][/ja]
- * @seealso ons-switch
- * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
- * [ja][/ja]
- * @seealso ons-input
- * [en]The `<ons-input>` element is used to display a text input.[/en]
- * [ja][/ja]
- * @seealso ons-search-input
- * [en]The `<ons-search-input>` element is used to display a search input.[/en]
- * [ja][/ja]
- * @seealso ons-range
- * [en]The `<ons-range>` element is used to display a range slider.[/en]
- * [ja][/ja]
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- * <ons-radio checked></ons-radio>
- */
-
- var RadioElement = function (_BaseCheckboxElement) {
- inherits(RadioElement, _BaseCheckboxElement);
-
- function RadioElement() {
- classCallCheck(this, RadioElement);
- return possibleConstructorReturn(this, (RadioElement.__proto__ || Object.getPrototypeOf(RadioElement)).apply(this, arguments));
- }
-
- createClass(RadioElement, [{
- key: '_scheme',
- get: function get$$1() {
- return scheme$14;
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'radio-button';
- }
- }, {
- key: 'type',
- get: function get$$1() {
- return 'radio';
- }
-
- /**
- * @attribute input-id
- * @type {String}
- * @description
- * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property value
- * @type {String}
- * @description
- * [en]The current value of the radio button.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property checked
- * @type {Boolean}
- * @description
- * [en]Whether the radio button is checked or not.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the radio button is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }]);
- return RadioElement;
- }(BaseCheckboxElement);
-
- onsElements.Radio = RadioElement;
- customElements.define('ons-radio', RadioElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var scheme$15 = {
- '.search-input': 'search-input--*'
- };
-
- /**
- * @element ons-search-input
- * @category form
- * @modifier material
- * [en]Displays a Material Design search input.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * A search input element. The component will automatically render as a Material Design search input on Android devices.
- *
- * Most attributes that can be used for a normal `<input>` element can also be used on the `<ons-search-input>` element.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/search-input
- * @seealso ons-input
- * [en]The `<ons-input>` element is used to display a text input.[/en]
- * [ja][/ja]
- * @seealso ons-range
- * [en]The `<ons-range>` element is used to display a range slider.[/en]
- * [ja][/ja]
- * @seealso ons-switch
- * [en]The `<ons-switch>` element is used to display a draggable toggle switch.[/en]
- * [ja][/ja]
- * @seealso ons-select
- * [en]The `<ons-select>` element is used to display a select box.[/en]
- * [ja][/ja]
- * @seealso ons-checkbox
- * [en]The `<ons-checkbox>` element is used to display a checkbox.[/en]
- * [ja][/ja]
- * @seealso ons-radio
- * [en]The `<ons-radio>` element is used to display a radio button.[/en]
- * [ja][/ja]
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- * <ons-search-input placeholder="Search"></ons-search-input>
- */
-
- var SearchInputElement = function (_BaseInputElement) {
- inherits(SearchInputElement, _BaseInputElement);
-
- function SearchInputElement() {
- classCallCheck(this, SearchInputElement);
- return possibleConstructorReturn(this, (SearchInputElement.__proto__ || Object.getPrototypeOf(SearchInputElement)).apply(this, arguments));
- }
-
- createClass(SearchInputElement, [{
- key: '_scheme',
- get: function get$$1() {
- return scheme$15;
- }
- }, {
- key: '_template',
- get: function get$$1() {
- return '\n <input type="' + this.type + '" class="search-input">\n ';
- }
- }, {
- key: 'type',
- get: function get$$1() {
- return 'search';
- }
-
- /**
- * @attribute input-id
- * @type {String}
- * @description
- * [en]Specify the "id" attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property value
- * @type {String}
- * @description
- * [en]The current value of the input.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the input is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }]);
- return SearchInputElement;
- }(BaseInputElement);
-
- onsElements.SearchInput = SearchInputElement;
- customElements.define('ons-search-input', SearchInputElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var ModalAnimator = function (_BaseAnimator) {
- inherits(ModalAnimator, _BaseAnimator);
-
- /**
- * @param {Object} options
- * @param {String} options.timing
- * @param {Number} options.duration
- * @param {Number} options.delay
- */
- function ModalAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, ModalAnimator);
- return possibleConstructorReturn(this, (ModalAnimator.__proto__ || Object.getPrototypeOf(ModalAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
-
- createClass(ModalAnimator, [{
- key: 'show',
- value: function show(modal, callback) {
- callback();
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(modal, callback) {
- callback();
- }
- }]);
- return ModalAnimator;
- }(BaseAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * iOS style animator for dialog.
- */
-
- var FadeModalAnimator = function (_ModalAnimator) {
- inherits(FadeModalAnimator, _ModalAnimator);
-
- function FadeModalAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.3 : _ref$duration;
-
- classCallCheck(this, FadeModalAnimator);
- return possibleConstructorReturn(this, (FadeModalAnimator.__proto__ || Object.getPrototypeOf(FadeModalAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
-
- createClass(FadeModalAnimator, [{
- key: 'show',
- value: function show(modal, callback) {
- callback = callback ? callback : function () {};
-
- Animit(modal, this.def).default({ opacity: 0 }, { opacity: 1 }).queue(function (done) {
- callback();
- done();
- }).play();
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(modal, callback) {
- callback = callback ? callback : function () {};
-
- Animit(modal, this.def).default({ opacity: 1 }, { opacity: 0 }).queue(function (done) {
- callback();
- done();
- }).play();
- }
- }]);
- return FadeModalAnimator;
- }(ModalAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * iOS style animator for modal.
- */
-
- var LiftModalAnimator = function (_ModalAnimator) {
- inherits(LiftModalAnimator, _ModalAnimator);
-
- function LiftModalAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier( .1, .7, .1, 1)' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.4 : _ref$duration;
-
- classCallCheck(this, LiftModalAnimator);
- return possibleConstructorReturn(this, (LiftModalAnimator.__proto__ || Object.getPrototypeOf(LiftModalAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
-
- createClass(LiftModalAnimator, [{
- key: 'show',
- value: function show(modal, callback) {
- callback = callback ? callback : function () {};
-
- Animit(modal, this.def).default({ transform: 'translate3d(0, 100%, 0)' }, { transform: 'translate3d(0, 0, 0)' }).queue(function (done) {
- callback();
- done();
- }).play();
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(modal, callback) {
- callback = callback ? callback : function () {};
-
- Animit(modal, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, 100%, 0)' }).queue(function (done) {
- callback();
- done();
- }).play();
- }
- }]);
- return LiftModalAnimator;
- }(ModalAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$16 = {
- '': 'modal--*',
- 'modal__content': 'modal--*__content'
- };
-
- var defaultClassName$8 = 'modal';
-
- var _animatorDict$4 = {
- 'default': ModalAnimator,
- 'fade': FadeModalAnimator,
- 'lift': LiftModalAnimator,
- 'none': ModalAnimator
- };
-
- /**
- * @element ons-modal
- * @category dialog
- * @description
- * [en]
- * Modal component that masks current screen. Underlying components are not subject to any events while the modal component is shown.
- *
- * This component can be used to block user input while some operation is running or to show some information to the user.
- * [/en]
- * [ja]
- * 画面全体をマスクするモーダル用コンポーネントです。下側にあるコンポーネントは、
- * モーダルが表示されている間はイベント通知が行われません。
- * [/ja]
- * @seealso ons-dialog
- * [en]The `<ons-dialog>` component can be used to create a modal dialog.[/en]
- * [ja][/ja]
- * @codepen devIg
- * @tutorial vanilla/reference/modal
- * @example
- * <ons-modal id="modal">
- * Modal content
- * </ons-modal>
- * <script>
- * var modal = document.getElementById('modal');
- * modal.show();
- * </script>
- */
-
- var ModalElement = function (_BaseDialogElement) {
- inherits(ModalElement, _BaseDialogElement);
-
- /**
- * @event preshow
- * @description
- * [en]Fired just before the modal is displayed.[/en]
- * [ja]モーダルが表示される直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.modal
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute this function to stop the modal from being shown.[/en]
- * [ja]この関数を実行すると、ダイアログの表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event postshow
- * @description
- * [en]Fired just after the modal is displayed.[/en]
- * [ja]モーダルが表示された直後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.modal
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @event prehide
- * @description
- * [en]Fired just before the modal is hidden.[/en]
- * [ja]モーダルが隠れる直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.modal
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Execute this function to stop the modal from being hidden.[/en]
- * [ja]この関数を実行すると、ダイアログの非表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event posthide
- * @description
- * [en]Fired just after the modal is hidden.[/en]
- * [ja]モーダルが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.modal
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]The animation used when showing and hiding the modal. Can be either `"none"`, `"fade"` or `"lift"`.[/en]
- * [ja]モーダルを表示する際のアニメーション名を指定します。"none"もしくは"fade","lift"を指定できます。[/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. <code>{duration: 0.2, delay: 1, timing: 'ease-in'}</code>[/ja]
- */
-
- function ModalElement() {
- classCallCheck(this, ModalElement);
-
- var _this = possibleConstructorReturn(this, (ModalElement.__proto__ || Object.getPrototypeOf(ModalElement)).call(this));
-
- _this._defaultDBB = function () {
- return undefined;
- };
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(ModalElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- return new AnimatorFactory({
- animators: _animatorDict$4,
- baseClass: ModalAnimator,
- baseClassName: 'ModalAnimator',
- defaultAnimation: this.getAttribute('animation')
- });
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: '_compile',
- value: function _compile() {
- this.style.display = 'none';
- this.style.zIndex = 10001;
- this.classList.add(defaultClassName$8);
-
- if (!util$1.findChild(this, '.modal__content')) {
- var content = document.createElement('div');
- content.classList.add('modal__content');
-
- while (this.childNodes[0]) {
- var node = this.childNodes[0];
- this.removeChild(node);
- content.insertBefore(node, null);
- }
-
- this.appendChild(content);
- }
-
- ModifierUtil.initModifier(this, this._scheme);
- }
- }, {
- key: '_toggleStyle',
- value: function _toggleStyle(shouldShow) {
- this.style.display = shouldShow ? 'table' : 'none';
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- get(ModalElement.prototype.__proto__ || Object.getPrototypeOf(ModalElement.prototype), 'connectedCallback', this).call(this);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- get(ModalElement.prototype.__proto__ || Object.getPrototypeOf(ModalElement.prototype), 'disconnectedCallback', this).call(this);
- }
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the element is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- /**
- * @method show
- * @signature show([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"fade"`.[/en]
- * [ja]アニメーション名を指定します。"none", "fade"のいずれかを指定します。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @param {Function} [options.callback]
- * [en]This function is called after the modal has been revealed.[/en]
- * [ja]モーダルが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Show modal.[/en]
- * [ja]モーダルを表示します。[/ja]
- * @return {Promise}
- * [en]Resolves to the displayed element[/en]
- * [ja][/ja]
- */
-
- /**
- * @method toggle
- * @signature toggle([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"fade"`.[/en]
- * [ja]アニメーション名を指定します。"none", "fade"のいずれかを指定します。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @param {Function} [options.callback]
- * [en]This function is called after the modal has been revealed.[/en]
- * [ja]モーダルが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Toggle modal visibility.[/en]
- * [ja]モーダルの表示を切り替えます。[/ja]
- */
-
- /**
- * @method hide
- * @signature hide([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"none"` and `"fade"`.[/en]
- * [ja]アニメーション名を指定します。"none", "fade"のいずれかを指定します。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @param {Function} [options.callback]
- * [en]This function is called after the modal has been revealed.[/en]
- * [ja]モーダルが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Hide modal.[/en]
- * [ja]モーダルを非表示にします。[/ja]
- * @return {Promise}
- * [en]Resolves to the hidden element[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'class') {
- util$1.restoreClass(this, defaultClassName$8, scheme$16);
- } else {
- get(ModalElement.prototype.__proto__ || Object.getPrototypeOf(ModalElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
- }
-
- /**
- * @param {String} name
- * @param {Function} Animator
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$16;
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof ModalAnimator)) {
- util$1.throwAnimator('Modal');
- }
- _animatorDict$4[name] = Animator;
- }
- }, {
- key: 'observedAttributes',
- get: function get$$1() {
- return [].concat(toConsumableArray(get(ModalElement.__proto__ || Object.getPrototypeOf(ModalElement), 'observedAttributes', this)), ['class']);
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$4;
- }
- }, {
- key: 'ModalAnimator',
- get: function get$$1() {
- return ModalAnimator;
- }
- }]);
- return ModalElement;
- }(BaseDialogElement);
-
- onsElements.Modal = ModalElement;
- customElements.define('ons-modal', ModalElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var widthToPx = function widthToPx(width) {
- var _ref = [parseInt(width, 10), /px/.test(width)],
- value = _ref[0],
- px = _ref[1];
-
- return px ? value : Math.round(document.body.offsetWidth * value / 100);
- };
-
- var SwipeReveal = function () {
- function SwipeReveal(params) {
- var _this = this;
-
- classCallCheck(this, SwipeReveal);
-
- 'element ignoreSwipe isInitialState onDragCallback swipeMax swipeMin swipeMid'.split(/\s+/).forEach(function (key) {
- return _this[key] = params[key];
- });
-
- this.elementHandler = params.elementHandler || params.element;
- this.getThreshold = params.getThreshold || function () {
- return .5;
- };
- this.getSide = params.getSide || function () {
- return 'left';
- };
-
- this.handleGesture = this.handleGesture.bind(this);
-
- this._shouldFixScroll = util$1.globals.actualMobileOS === 'ios';
- }
-
- createClass(SwipeReveal, [{
- key: 'update',
- value: function update() {
- var swipeable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.element.hasAttribute('swipeable');
-
- if (!this.gestureDetector) {
- this.gestureDetector = new GestureDetector(this.elementHandler, { dragMinDistance: 1, passive: !this._shouldFixScroll });
- }
-
- var action = swipeable ? 'on' : 'off';
- this.gestureDetector[action]('drag dragstart dragend', this.handleGesture);
- }
- }, {
- key: 'handleGesture',
- value: function handleGesture(e) {
- if (e.gesture) {
- if (e.type === 'dragstart') {
- this.onDragStart(e);
- } else if (!this._ignoreDrag) {
- e.type === 'dragend' ? this.onDragEnd(e) : this.onDrag(e);
- }
- }
- }
- }, {
- key: 'onDragStart',
- value: function onDragStart(event) {
- var _this2 = this;
-
- var getDistance = function getDistance() {
- return _this2.getSide() === 'left' ? event.gesture.center.clientX : window.innerWidth - event.gesture.center.clientX;
- };
- this._ignoreDrag = event.consumed || !util$1.isValidGesture(event) || this.ignoreSwipe(event, getDistance());
-
- if (!this._ignoreDrag) {
- event.consume && event.consume();
- event.consumed = true;
-
- this._width = widthToPx(this.element.style.width || '100%');
- this._startDistance = this._distance = !(this.isInitialState instanceof Function) || this.isInitialState() ? 0 : this._width;
-
- util$1.iosPreventScroll(this.gestureDetector);
- }
- }
- }, {
- key: 'onDrag',
- value: function onDrag(event) {
- event.stopPropagation();
-
- var delta = this.getSide() === 'left' ? event.gesture.deltaX : -event.gesture.deltaX;
- var distance = Math.max(0, Math.min(this._width, this._startDistance + delta));
- if (distance !== this._distance) {
- this._distance = distance;
- this.swipeMid(this._distance, this._width);
- }
- }
- }, {
- key: 'onDragEnd',
- value: function onDragEnd(event) {
- event.stopPropagation();
-
- var direction = event.gesture.interimDirection;
- var isSwipeMax = this.getSide() !== direction && this._distance > this._width * this.getThreshold();
- isSwipeMax ? this.swipeMax() : this.swipeMin();
- }
- }, {
- key: 'dispose',
- value: function dispose() {
- this.gestureDetector && this.gestureDetector.dispose();
- this.gestureDetector = this.element = this.elementHandler = null;
- }
- }]);
- return SwipeReveal;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var NavigatorAnimator = function (_BaseAnimator) {
- inherits(NavigatorAnimator, _BaseAnimator);
-
- /**
- * @param {Object} options
- * @param {String} options.timing
- * @param {Number} options.duration
- * @param {Number} options.delay
- */
- function NavigatorAnimator(options) {
- classCallCheck(this, NavigatorAnimator);
-
- options = util$1.extend({
- timing: 'linear',
- duration: '0.4',
- delay: '0'
- }, options || {});
-
- return possibleConstructorReturn(this, (NavigatorAnimator.__proto__ || Object.getPrototypeOf(NavigatorAnimator)).call(this, options));
- }
-
- createClass(NavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- callback();
- }
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- callback();
- }
- }, {
- key: 'block',
- value: function block(page) {
- var blocker = util$1.createElement('\n <div style="position: absolute; background-color: transparent; width: 100%; height: 100%; z-index: 100000"></div>\n ');
- page.parentNode.appendChild(blocker);
- return function () {
- return blocker.remove();
- };
- }
- }]);
- return NavigatorAnimator;
- }(BaseAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Abstract swipe animator for iOS navigator transition.
- */
-
- var IOSSwipeNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(IOSSwipeNavigatorAnimator, _NavigatorAnimator);
- createClass(IOSSwipeNavigatorAnimator, null, [{
- key: 'swipeable',
- get: function get$$1() {
- return true;
- }
- }]);
-
- function IOSSwipeNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- var _ref$durationRestore = _ref.durationRestore,
- durationRestore = _ref$durationRestore === undefined ? 0.1 : _ref$durationRestore,
- _ref$durationSwipe = _ref.durationSwipe,
- durationSwipe = _ref$durationSwipe === undefined ? 0.15 : _ref$durationSwipe,
- _ref$timingSwipe = _ref.timingSwipe,
- timingSwipe = _ref$timingSwipe === undefined ? 'linear' : _ref$timingSwipe,
- rest = objectWithoutProperties(_ref, ['durationRestore', 'durationSwipe', 'timingSwipe']);
- classCallCheck(this, IOSSwipeNavigatorAnimator);
-
- var _this = possibleConstructorReturn(this, (IOSSwipeNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSSwipeNavigatorAnimator)).call(this, _extends({}, rest)));
-
- if (_this.constructor === IOSSwipeNavigatorAnimator) {
- util$1.throwAbstract();
- }
-
- _this.durationRestore = durationRestore;
- _this.durationSwipe = durationSwipe;
- _this.timingSwipe = timingSwipe;
-
- _this.optSwipe = { timing: timingSwipe, duration: durationSwipe };
- _this.optRestore = { timing: timingSwipe, duration: durationRestore };
-
- _this.swipeShadow = util$1.createElement('<div style="position: absolute; height: 100%; width: 12px; right: 100%; top: 0; bottom: 0; z-index: -1;' + 'background: linear-gradient(to right, transparent 0, rgba(0,0,0,.04) 40%, rgba(0,0,0,.12) 80%, rgba(0,0,0,.16) 100%);"></div>');
-
- _this.isDragStart = true;
- return _this;
- }
-
- createClass(IOSSwipeNavigatorAnimator, [{
- key: '_decompose',
- value: function _decompose() {
- util$1.throwMember();
- }
- }, {
- key: '_shouldAnimateToolbar',
- value: function _shouldAnimateToolbar() {
- util$1.throwMember();
- }
- }, {
- key: '_calculateDelta',
- value: function _calculateDelta() {
- util$1.throwMember();
- }
- }, {
- key: '_dragStartSetup',
- value: function _dragStartSetup(enterPage, leavePage) {
- this.isDragStart = false;
-
- // Avoid content clicks
- this.unblock = get(IOSSwipeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSSwipeNavigatorAnimator.prototype), 'block', this).call(this, leavePage);
-
- // Mask
- enterPage.parentElement.insertBefore(this.backgroundMask, enterPage);
-
- // Decomposition
- this.target = {
- enter: util$1.findToolbarPage(enterPage) || enterPage,
- leave: util$1.findToolbarPage(leavePage) || leavePage
- };
- this.decomp = {
- enter: this._decompose(this.target.enter),
- leave: this._decompose(this.target.leave)
- };
-
- // Animation values
- this.delta = this._calculateDelta(leavePage, this.decomp.leave);
- this.shouldAnimateToolbar = this._shouldAnimateToolbar(this.target.enter, this.target.leave);
-
- // Shadow && styles
- if (this.shouldAnimateToolbar) {
- this.swipeShadow.style.top = this.decomp.leave.toolbar.offsetHeight + 'px';
- this.target.leave.appendChild(this.swipeShadow);
- this._saveStyle(this.target.enter, this.target.leave);
- } else {
- leavePage.appendChild(this.swipeShadow);
- this._saveStyle(enterPage, leavePage);
- }
- leavePage.classList.add('overflow-visible');
- this.overflowElement = leavePage;
- this.decomp.leave.content.classList.add('content-swiping');
- }
- }, {
- key: 'translate',
- value: function translate(distance, maxWidth, enterPage, leavePage) {
- this.isSwiping = true;
-
- if (enterPage.style.display === 'none') {
- enterPage.style.display = '';
- }
-
- if (this.isDragStart) {
- this.maxWidth = maxWidth;
- this._dragStartSetup(enterPage, leavePage);
- }
-
- var swipeRatio = (distance - maxWidth) / maxWidth;
-
- if (this.shouldAnimateToolbar) {
-
- Animit.runAll(
-
- /* Enter page */
-
- Animit([this.decomp.enter.content, this.decomp.enter.bottomToolbar, this.decomp.enter.background]).queue({
- transform: 'translate3d(' + swipeRatio * 25 + '%, 0, 0)',
- opacity: 1 + swipeRatio * 10 / 100 // 0.9 -> 1
- }), Animit(this.decomp.enter.toolbarCenter).queue({
- transform: 'translate3d(' + this.delta.title * swipeRatio + 'px, 0, 0)',
- opacity: 1 + swipeRatio // 0 -> 1
- }), Animit(this.decomp.enter.backButtonLabel).queue({
- opacity: 1 + swipeRatio * 10 / 100, // 0.9 -> 1
- transform: 'translate3d(' + this.delta.label * swipeRatio + 'px, 0, 0)'
- }), Animit(this.decomp.enter.other).queue({
- opacity: 1 + swipeRatio // 0 -> 1
- }),
-
- /* Leave page */
-
- Animit([this.decomp.leave.content, this.decomp.leave.bottomToolbar, this.decomp.leave.background, this.swipeShadow]).queue({
- transform: 'translate3d(' + distance + 'px, 0, 0)'
- }), Animit(this.decomp.leave.toolbar).queue({
- opacity: -1 * swipeRatio // 1 -> 0
- }), Animit(this.decomp.leave.toolbarCenter).queue({
- transform: 'translate3d(' + (1 + swipeRatio) * 125 + '%, 0, 0)'
- }), Animit(this.decomp.leave.backButtonLabel).queue({
- opacity: -1 * swipeRatio, // 1 -> 0
- transform: 'translate3d(' + this.delta.title * (1 + swipeRatio) + 'px, 0, 0)'
- }),
-
- /* Other */
-
- Animit(this.swipeShadow).queue({
- opacity: -1 * swipeRatio // 1 -> 0
- }));
- } else {
- Animit.runAll(Animit(leavePage).queue({
- transform: 'translate3d(' + distance + 'px, 0, 0)'
- }), Animit(enterPage).queue({
- transform: 'translate3d(' + swipeRatio * 25 + '%, 0, 0)',
- opacity: 1 + swipeRatio * 10 / 100 // 0.9 -> 1
- }), Animit(this.swipeShadow).queue({
- opacity: -1 * swipeRatio // 1 -> 0
- }));
- }
- }
- }, {
- key: 'restore',
- value: function restore(enterPage, leavePage, callback) {
- var _this2 = this;
-
- if (this.isDragStart) {
- return;
- }
-
- if (this.shouldAnimateToolbar) {
-
- Animit.runAll(
-
- /* Enter page */
-
- Animit([this.decomp.enter.content, this.decomp.enter.bottomToolbar, this.decomp.enter.background]).queue({
- transform: 'translate3d(-25%, 0, 0)',
- opacity: 0.9
- }, this.optRestore), Animit(this.decomp.enter.toolbarCenter).queue({
- transform: 'translate3d(-' + this.delta.title + 'px, 0, 0)',
- transition: 'opacity ' + this.durationRestore + 's linear, transform ' + this.durationRestore + 's ' + this.timingSwipe,
- opacity: 0
- }), Animit(this.decomp.enter.backButtonLabel).queue({
- transform: 'translate3d(-' + this.delta.label + 'px, 0, 0)'
- }, this.optRestore), Animit(this.decomp.enter.other).queue({
- opacity: 0
- }, this.optRestore),
-
- /* Leave page */
-
- Animit([this.decomp.leave.content, this.decomp.leave.bottomToolbar, this.decomp.leave.background, this.swipeShadow]).queue({
- transform: 'translate3d(0, 0, 0)'
- }, this.optRestore), Animit(this.decomp.leave.toolbar).queue({
- opacity: 1
- }, this.optRestore), Animit(this.decomp.leave.toolbarCenter).queue({
- transform: 'translate3d(0, 0, 0)'
- }, this.optRestore), Animit(this.decomp.leave.backButtonLabel).queue({
- opacity: 1,
- transform: 'translate3d(0, 0, 0)',
- transition: 'opacity ' + this.durationRestore + 's linear, transform ' + this.durationRestore + 's ' + this.timingSwipe
- }),
-
- /* Other */
-
- Animit(this.swipeShadow).queue({
- opacity: 0
- }, this.optRestore).queue(function (done) {
- _this2._reset(_this2.target.enter, _this2.target.leave);
- enterPage.style.display = 'none';
- callback && callback();
- done();
- }));
- } else {
- Animit.runAll(Animit(enterPage).queue({
- transform: 'translate3D(-25%, 0, 0)',
- opacity: 0.9
- }, this.optRestore), Animit(leavePage).queue({
- transform: 'translate3D(0, 0, 0)'
- }, this.optRestore).queue(function (done) {
- _this2._reset(enterPage, leavePage);
- enterPage.style.display = 'none';
- callback && callback();
- done();
- }));
- }
- }
- }, {
- key: 'popSwipe',
- value: function popSwipe(enterPage, leavePage, callback) {
- var _this3 = this;
-
- if (this.isDragStart) {
- return;
- }
-
- if (this.shouldAnimateToolbar) {
-
- Animit.runAll(
-
- /* Enter page */
-
- Animit([this.decomp.enter.content, this.decomp.enter.bottomToolbar, this.decomp.enter.background]).queue({
- transform: 'translate3d(0, 0, 0)',
- opacity: 1
- }, this.optSwipe), Animit(this.decomp.enter.toolbarCenter).queue({
- transform: 'translate3d(0, 0, 0)',
- transition: 'opacity ' + this.durationSwipe + 's linear, transform ' + this.durationSwipe + 's ' + this.timingSwipe,
- opacity: 1
- }), Animit(this.decomp.enter.backButtonLabel).queue({
- transform: 'translate3d(0, 0, 0)'
- }, this.optSwipe), Animit(this.decomp.enter.other).queue({
- opacity: 1
- }, this.optSwipe),
-
- /* Leave page */
-
- Animit([this.decomp.leave.content, this.decomp.leave.bottomToolbar, this.decomp.leave.background]).queue({
- transform: 'translate3d(100%, 0, 0)'
- }, this.optSwipe), Animit(this.decomp.leave.toolbar).queue({
- opacity: 0
- }, this.optSwipe), Animit(this.decomp.leave.toolbarCenter).queue({
- transform: 'translate3d(125%, 0, 0)'
- }, this.optSwipe), Animit(this.decomp.leave.backButtonLabel).queue({
- opacity: 0,
- transform: 'translate3d(' + this.delta.title + 'px, 0, 0)',
- transition: 'opacity ' + this.durationSwipe + 's linear, transform ' + this.durationSwipe + 's ' + this.timingSwipe
- }),
-
- /* Other */
-
- Animit(this.swipeShadow).queue({
- opacity: 0,
- transform: 'translate3d(' + this.maxWidth + 'px, 0, 0)'
- }, this.optSwipe).queue(function (done) {
- _this3._reset(_this3.target.enter, _this3.target.leave);
- callback && callback();
- done();
- }));
- } else {
- Animit.runAll(Animit(enterPage).queue({
- transform: 'translate3D(0, 0, 0)',
- opacity: 1.0
- }, this.optSwipe), Animit(leavePage).queue({
- transform: 'translate3D(100%, 0, 0)'
- }, this.optSwipe).queue(function (done) {
- _this3._reset(enterPage, leavePage);
- callback && callback();
- done();
- }));
- }
- }
- }, {
- key: '_saveStyle',
- value: function _saveStyle() {
- var _this4 = this;
-
- this._savedStyle = new WeakMap();
- var save = function save(el) {
- return _this4._savedStyle.set(el, el.getAttribute('style'));
- };
-
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- args.forEach(save);
-
- Object.keys(this.decomp).forEach(function (p) {
- Object.keys(_this4.decomp[p]).forEach(function (k) {
- (_this4.decomp[p][k] instanceof Array ? _this4.decomp[p][k] : [_this4.decomp[p][k]]).forEach(save);
- });
- });
- }
- }, {
- key: '_restoreStyle',
- value: function _restoreStyle() {
- var _this5 = this;
-
- var restore = function restore(el) {
- _this5._savedStyle.get(el) === null ? el.removeAttribute('style') : el.setAttribute('style', _this5._savedStyle.get(el));
- _this5._savedStyle.delete(el);
- };
-
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- args.forEach(restore);
-
- Object.keys(this.decomp).forEach(function (p) {
- Object.keys(_this5.decomp[p]).forEach(function (k) {
- (_this5.decomp[p][k] instanceof Array ? _this5.decomp[p][k] : [_this5.decomp[p][k]]).forEach(restore);
- });
- });
- }
- }, {
- key: '_reset',
- value: function _reset() {
- this.isSwiping = false;
- this._savedStyle && this._restoreStyle.apply(this, arguments);
- this.unblock && this.unblock();
- this.swipeShadow.remove();
- this.backgroundMask.remove();
- this.overflowElement.classList.remove('overflow-visible');
- this.decomp.leave.content.classList.remove('content-swiping');
- this.decomp = this.target = this.overflowElement = this._savedStyle = null;
- this.isDragStart = true;
- }
- }]);
- return IOSSwipeNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var translate3d = function translate3d() {
- var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
- var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
- var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
- return 'translate3d(' + x + ', ' + y + ', ' + z + ')';
- };
-
- /**
- * Slide animator for navigator transition like iOS's screen slide transition.
- */
-
- var IOSSlideNavigatorAnimator = function (_IOSSwipeNavigatorAni) {
- inherits(IOSSlideNavigatorAnimator, _IOSSwipeNavigatorAni);
-
- function IOSSlideNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- var _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(0.3, .4, 0, .9)' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.4 : _ref$duration,
- rest = objectWithoutProperties(_ref, ['timing', 'delay', 'duration']);
- classCallCheck(this, IOSSlideNavigatorAnimator);
-
- var _this = possibleConstructorReturn(this, (IOSSlideNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSSlideNavigatorAnimator)).call(this, _extends({ timing: timing, delay: delay, duration: duration }, rest)));
-
- _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%;' + 'background-color: black; z-index: 2"></div>');
- return _this;
- }
-
- createClass(IOSSlideNavigatorAnimator, [{
- key: '_decompose',
- value: function _decompose(page) {
- var toolbar = page._getToolbarElement();
- var left = toolbar._getToolbarLeftItemsElement();
- var right = toolbar._getToolbarRightItemsElement();
-
- var excludeBackButton = function excludeBackButton(elements) {
- var result = [];
-
- for (var i = 0; i < elements.length; i++) {
- if (elements[i].nodeName.toLowerCase() !== 'ons-back-button') {
- result.push(elements[i]);
- }
- }
-
- return result;
- };
-
- var other = [].concat(left.children.length === 0 ? left : excludeBackButton(left.children)).concat(right.children.length === 0 ? right : excludeBackButton(right.children));
-
- return {
- toolbarCenter: toolbar._getToolbarCenterItemsElement(),
- backButtonIcon: toolbar._getToolbarBackButtonIconElement(),
- backButtonLabel: toolbar._getToolbarBackButtonLabelElement(),
- other: other,
- content: page._getContentElement(),
- background: page._getBackgroundElement(),
- toolbar: toolbar,
- bottomToolbar: page._getBottomToolbarElement()
- };
- }
- }, {
- key: '_shouldAnimateToolbar',
- value: function _shouldAnimateToolbar(enterPage, leavePage) {
- var toolbars = enterPage._canAnimateToolbar() && leavePage._canAnimateToolbar();
-
- var enterToolbar = enterPage._getToolbarElement();
- var leaveToolbar = leavePage._getToolbarElement();
-
- var isStatic = enterToolbar.hasAttribute('static') || leaveToolbar.hasAttribute('static');
- var isMaterial = util$1.hasModifier(enterToolbar, 'material') || util$1.hasModifier(leaveToolbar, 'material');
- var isTransparent = util$1.hasModifier(enterToolbar, 'transparent') || util$1.hasModifier(leaveToolbar, 'transparent');
-
- return toolbars && !isStatic && !isMaterial && !isTransparent;
- }
- }, {
- key: '_calculateDelta',
- value: function _calculateDelta(element, decomposition) {
- var title = void 0,
- label = void 0;
-
- var pageRect = element.getBoundingClientRect();
- if (decomposition.backButtonLabel.classList.contains('back-button__label')) {
- var labelRect = decomposition.backButtonLabel.getBoundingClientRect();
- title = Math.round(pageRect.width / 2 - labelRect.width / 2 - labelRect.left);
- } else {
- title = Math.round(pageRect.width / 2 * 0.6);
- }
-
- if (decomposition.backButtonIcon.classList.contains('back-button__icon')) {
- label = decomposition.backButtonIcon.getBoundingClientRect().right - 2;
- }
-
- return { title: title, label: label };
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
- }, {
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- var _this2 = this;
-
- this.backgroundMask.remove();
- leavePage.parentNode.insertBefore(this.backgroundMask, leavePage);
-
- var unblock = get(IOSSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- contentReady(enterPage, function () {
- var enterPageTarget = util$1.findToolbarPage(enterPage) || enterPage;
- var leavePageTarget = util$1.findToolbarPage(leavePage) || leavePage;
- var enterPageDecomposition = _this2._decompose(enterPageTarget);
- var leavePageDecomposition = _this2._decompose(leavePageTarget);
-
- var delta = _this2._calculateDelta(leavePage, enterPageDecomposition);
-
- var shouldAnimateToolbar = _this2._shouldAnimateToolbar(enterPageTarget, leavePageTarget);
-
- if (shouldAnimateToolbar) {
-
- Animit.runAll(Animit([enterPageDecomposition.content, enterPageDecomposition.bottomToolbar, enterPageDecomposition.background], _this2.def).default({ transform: translate3d('100%') }, { transform: translate3d() }), Animit(enterPageDecomposition.toolbar, _this2.def).default({ opacity: 0 }, { opacity: 1 }), Animit(enterPageDecomposition.toolbarCenter, _this2.def).default({ transform: translate3d('125%'), opacity: 1 }, { transform: translate3d(), opacity: 1 }), Animit(enterPageDecomposition.backButtonLabel, _this2.def).default({ transform: translate3d(delta.title + 'px'), opacity: 0 }, {
- transform: translate3d(),
- opacity: 1,
- transition: 'opacity ' + _this2.duration + 's linear, transform ' + _this2.duration + 's ' + _this2.timing
- }), Animit(enterPageDecomposition.other, _this2.def).default({ opacity: 0 }, { css: { opacity: 1 }, timing: 'linear' }), Animit([leavePageDecomposition.content, leavePageDecomposition.bottomToolbar, leavePageDecomposition.background], _this2.def).default({ transform: translate3d(), opacity: 1 }, { transform: translate3d('-25%'), opacity: 0.9 }).queue(function (done) {
- _this2.backgroundMask.remove();
- unblock();
- callback();
- done();
- }), Animit(leavePageDecomposition.toolbarCenter, _this2.def).default({ transform: translate3d(), opacity: 1 }, {
- transform: translate3d('-' + delta.title + 'px'),
- opacity: 0,
- transition: 'opacity ' + _this2.duration + 's linear, transform ' + _this2.duration + 's ' + _this2.timing
- }), Animit(leavePageDecomposition.backButtonLabel, _this2.def).default({ transform: translate3d(), opacity: 1 }, { transform: translate3d('-' + delta.label + 'px'), opacity: 0 }), Animit(leavePageDecomposition.other, _this2.def).default({ opacity: 1 }, { css: { opacity: 0 }, timing: 'linear' }));
- } else {
-
- Animit.runAll(Animit(enterPage, _this2.def).default({ transform: translate3d('100%') }, { transform: translate3d() }), Animit(leavePage, _this2.def).default({ transform: translate3d(), opacity: 1 }, { transform: translate3d('-25%'), opacity: .9 }).queue(function (done) {
- _this2.backgroundMask.remove();
- unblock();
- callback();
- done();
- }));
- }
- });
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- var _this3 = this;
-
- if (this.isSwiping) {
- return this.popSwipe(enterPage, leavePage, callback);
- }
-
- this.backgroundMask.remove();
- enterPage.parentNode.insertBefore(this.backgroundMask, enterPage);
-
- var unblock = get(IOSSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- var enterPageTarget = util$1.findToolbarPage(enterPage) || enterPage;
- var leavePageTarget = util$1.findToolbarPage(leavePage) || leavePage;
- var enterPageDecomposition = this._decompose(enterPageTarget);
- var leavePageDecomposition = this._decompose(leavePageTarget);
-
- var delta = this._calculateDelta(leavePage, leavePageDecomposition);
-
- var shouldAnimateToolbar = this._shouldAnimateToolbar(enterPageTarget, leavePageTarget);
-
- if (shouldAnimateToolbar) {
- Animit.runAll(Animit([enterPageDecomposition.content, enterPageDecomposition.bottomToolbar, enterPageDecomposition.background], this.def).default({ transform: translate3d('-25%'), opacity: .9 }, { transform: translate3d(), opacity: 1 }), Animit(enterPageDecomposition.toolbarCenter, this.def).default({ transform: translate3d('-' + delta.title + 'px'), opacity: 0 }, {
- transform: translate3d(),
- opacity: 1,
- transition: 'opacity ' + this.duration + 's linear, transform ' + this.duration + 's ' + this.timing
- }), Animit(enterPageDecomposition.backButtonLabel, this.def).default({ transform: translate3d('-' + delta.label + 'px') }, { transform: translate3d() }), Animit(enterPageDecomposition.other, this.def).default({ opacity: 0 }, { css: { opacity: 1 }, timing: 'linear' }), Animit([leavePageDecomposition.content, leavePageDecomposition.bottomToolbar, leavePageDecomposition.background], this.def).default({ transform: translate3d() }, { transform: translate3d('100%') }).wait(0).queue(function (done) {
- _this3.backgroundMask.remove();
- unblock();
- callback();
- done();
- }), Animit(leavePageDecomposition.toolbar, this.def).default({ opacity: 1 }, { opacity: 0 }), Animit(leavePageDecomposition.toolbarCenter, this.def).default({ transform: translate3d() }, { transform: translate3d('125%') }), Animit(leavePageDecomposition.backButtonLabel, this.def).default({ transform: translate3d(), opacity: 1 }, {
- transform: translate3d(delta.title + 'px'),
- opacity: 0,
- transition: 'opacity ' + this.duration + 's linear, transform ' + this.duration + 's ' + this.timing
- }));
- } else {
- Animit.runAll(Animit(enterPage, this.def).default({ transform: translate3d('-25%'), opacity: .9 }, { transform: translate3d(), opacity: 1 }), Animit(leavePage, this.def).default({ transform: translate3d() }, { transform: translate3d('100%') }).queue(function (done) {
- _this3.backgroundMask.remove();
- unblock();
- callback();
- done();
- }));
- }
- }
- }]);
- return IOSSlideNavigatorAnimator;
- }(IOSSwipeNavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Lift screen transition.
- */
-
- var IOSLiftNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(IOSLiftNavigatorAnimator, _NavigatorAnimator);
-
- function IOSLiftNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .1, 1)' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.4 : _ref$duration;
-
- classCallCheck(this, IOSLiftNavigatorAnimator);
-
- var _this = possibleConstructorReturn(this, (IOSLiftNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSLiftNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%;' + 'background: linear-gradient(black, white);"></div>');
- return _this;
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
-
- createClass(IOSLiftNavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- var _this2 = this;
-
- this.backgroundMask.remove();
- leavePage.parentNode.insertBefore(this.backgroundMask, leavePage);
-
- var unblock = get(IOSLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(enterPage, this.def).default({ transform: 'translate3D(0, 100%, 0)' }, { transform: 'translate3D(0, 0, 0)' }), Animit(leavePage, this.def).default({ transform: 'translate3D(0, 0, 0)', opacity: 1 }, { transform: 'translate3D(0, -10%, 0)', opacity: .9 }).queue(function (done) {
- _this2.backgroundMask.remove();
- unblock();
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- var _this3 = this;
-
- this.backgroundMask.remove();
- enterPage.parentNode.insertBefore(this.backgroundMask, enterPage);
-
- var unblock = get(IOSLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(enterPage, this.def).default({ transform: 'translate3D(0, -43px, 0)', opacity: .9 }, { transform: 'translate3D(0, 0, 0)', opacity: 1 }).queue(function (done) {
- _this3.backgroundMask.remove();
- unblock();
- callback();
- done();
- }), Animit(leavePage, this.def).default({ transform: 'translate3D(0, 0, 0)' }, { transform: 'translate3D(0, 100%, 0)' }));
- }
- }]);
- return IOSLiftNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var transform = 'translate3d(0, 0, 0)';
-
- /**
- * Fade-in screen transition.
- */
-
- var IOSFadeNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(IOSFadeNavigatorAnimator, _NavigatorAnimator);
-
- function IOSFadeNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.4 : _ref$duration;
-
- classCallCheck(this, IOSFadeNavigatorAnimator);
- return possibleConstructorReturn(this, (IOSFadeNavigatorAnimator.__proto__ || Object.getPrototypeOf(IOSFadeNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
-
- createClass(IOSFadeNavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- var unblock = get(IOSFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(enterPage, this.def).default({ transform: transform, opacity: 0 }, { transform: transform, opacity: 1 }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} done
- */
-
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- var unblock = get(IOSFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(IOSFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(leavePage, this.def).default({ transform: transform, opacity: 1 }, { transform: transform, opacity: 0 }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
- }]);
- return IOSFadeNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Slide animator for navigator transition.
- */
-
- var MDSlideNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(MDSlideNavigatorAnimator, _NavigatorAnimator);
-
- function MDSlideNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.3 : _ref$duration;
-
- classCallCheck(this, MDSlideNavigatorAnimator);
-
- var _this = possibleConstructorReturn(this, (MDSlideNavigatorAnimator.__proto__ || Object.getPrototypeOf(MDSlideNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this.blackMaskOpacity = 0.4;
- _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%; z-index: 2;' + 'background-color: black; opacity: 0;"></div>');
- return _this;
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
-
- createClass(MDSlideNavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- var _this2 = this;
-
- this.backgroundMask.remove();
- leavePage.parentElement.insertBefore(this.backgroundMask, leavePage.nextSibling);
-
- var unblock = get(MDSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(this.backgroundMask, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 0 }, { opacity: this.blackMaskOpacity }).queue(function (done) {
- _this2.backgroundMask.remove();
- done();
- }), Animit(enterPage, this.def).default({ transform: 'translate3d(100%, 0, 0)' }, { transform: 'translate3d(0, 0, 0)' }), Animit(leavePage, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(-45%, 0, 0)' }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- var _this3 = this;
-
- this.backgroundMask.remove();
- enterPage.parentNode.insertBefore(this.backgroundMask, enterPage.nextSibling);
-
- var unblock = get(MDSlideNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDSlideNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(this.backgroundMask, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: this.blackMaskOpacity }, { opacity: 0 }).queue(function (done) {
- _this3.backgroundMask.remove();
- done();
- }), Animit(enterPage, this.def).default({ transform: 'translate3d(-45%, 0, 0)', opacity: .9 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }), Animit(leavePage, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(100%, 0, 0)' }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
- }]);
- return MDSlideNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Lift screen transition.
- */
-
- var MDLiftNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(MDLiftNavigatorAnimator, _NavigatorAnimator);
-
- function MDLiftNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .1, 1)' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0.05 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.4 : _ref$duration;
-
- classCallCheck(this, MDLiftNavigatorAnimator);
-
- var _this = possibleConstructorReturn(this, (MDLiftNavigatorAnimator.__proto__ || Object.getPrototypeOf(MDLiftNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this.backgroundMask = util$1.createElement('<div style="position: absolute; width: 100%; height: 100%;' + 'background-color: black;"></div>');
- return _this;
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
-
- createClass(MDLiftNavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- var _this2 = this;
-
- this.backgroundMask.remove();
- leavePage.parentNode.insertBefore(this.backgroundMask, leavePage);
-
- var unblock = get(MDLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- var maskClear = Animit(this.backgroundMask).wait(this.delay + this.duration).queue(function (done) {
- _this2.backgroundMask.remove();
- done();
- });
-
- Animit.runAll(maskClear, Animit(enterPage, this.def).default({ transform: 'translate3d(0, 100%, 0)' }, { transform: 'translate3d(0, 0, 0)' }), Animit(leavePage, this.def).default({ opacity: 1 }, { opacity: .4 }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- var _this3 = this;
-
- this.backgroundMask.remove();
- enterPage.parentNode.insertBefore(this.backgroundMask, enterPage);
-
- var unblock = get(MDLiftNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDLiftNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(this.backgroundMask).wait(this.delay + this.duration).queue(function (done) {
- _this3.backgroundMask.remove();
- done();
- }), Animit(enterPage, this.def).default({ opacity: .4 }, { opacity: 1 }).queue(function (done) {
- unblock();
- callback();
- done();
- }), Animit(leavePage, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, 100%, 0)' }));
- }
- }]);
- return MDLiftNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Fade-in + Lift screen transition.
- */
-
- var MDFadeNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(MDFadeNavigatorAnimator, _NavigatorAnimator);
-
- function MDFadeNavigatorAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(0.4, 0, 0.2, 1)' : _ref$timing,
- _ref$timingPop = _ref.timingPop,
- timingPop = _ref$timingPop === undefined ? 'cubic-bezier(0.4, 0, 1, 1)' : _ref$timingPop,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, MDFadeNavigatorAnimator);
-
- var _this = possibleConstructorReturn(this, (MDFadeNavigatorAnimator.__proto__ || Object.getPrototypeOf(MDFadeNavigatorAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this.timingPop = timingPop;
- return _this;
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} callback
- */
-
-
- createClass(MDFadeNavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- var unblock = get(MDFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(enterPage, this.def).default({ transform: 'translate3D(0, 42px, 0)', opacity: 0 }, { transform: 'translate3D(0, 0, 0)', opacity: 1 }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
-
- /**
- * @param {Object} enterPage
- * @param {Object} leavePage
- * @param {Function} done
- */
-
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- var unblock = get(MDFadeNavigatorAnimator.prototype.__proto__ || Object.getPrototypeOf(MDFadeNavigatorAnimator.prototype), 'block', this).call(this, enterPage);
-
- Animit.runAll(Animit(leavePage, this.def).default({ transform: 'translate3D(0, 0, 0)', opacity: 1 }, { css: { transform: 'translate3D(0, 38px, 0)', opacity: 0 }, timing: this.timingPop }).queue(function (done) {
- unblock();
- callback();
- done();
- }));
- }
- }]);
- return MDFadeNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var NoneNavigatorAnimator = function (_NavigatorAnimator) {
- inherits(NoneNavigatorAnimator, _NavigatorAnimator);
-
- function NoneNavigatorAnimator(options) {
- classCallCheck(this, NoneNavigatorAnimator);
- return possibleConstructorReturn(this, (NoneNavigatorAnimator.__proto__ || Object.getPrototypeOf(NoneNavigatorAnimator)).call(this, options));
- }
-
- createClass(NoneNavigatorAnimator, [{
- key: 'push',
- value: function push(enterPage, leavePage, callback) {
- callback();
- }
- }, {
- key: 'pop',
- value: function pop(enterPage, leavePage, callback) {
- callback();
- }
- }]);
- return NoneNavigatorAnimator;
- }(NavigatorAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var _animatorDict$5 = {
- 'default': function _default() {
- return platform.isAndroid() ? MDFadeNavigatorAnimator : IOSSlideNavigatorAnimator;
- },
- 'slide': function slide() {
- return platform.isAndroid() ? MDSlideNavigatorAnimator : IOSSlideNavigatorAnimator;
- },
- 'lift': function lift() {
- return platform.isAndroid() ? MDLiftNavigatorAnimator : IOSLiftNavigatorAnimator;
- },
- 'fade': function fade() {
- return platform.isAndroid() ? MDFadeNavigatorAnimator : IOSFadeNavigatorAnimator;
- },
- 'slide-ios': IOSSlideNavigatorAnimator,
- 'slide-md': MDSlideNavigatorAnimator,
- 'lift-ios': IOSLiftNavigatorAnimator,
- 'lift-md': MDLiftNavigatorAnimator,
- 'fade-ios': IOSFadeNavigatorAnimator,
- 'fade-md': MDFadeNavigatorAnimator,
- 'none': NoneNavigatorAnimator
- };
-
- var rewritables = {
- /**
- * @param {Element} navigatorSideElement
- * @param {Function} callback
- */
- ready: function ready(navigatorElement, callback) {
- callback();
- }
- };
-
- var verifyPageElement = function verifyPageElement(el) {
- return el.nodeName !== 'ONS-PAGE' && util$1.throw('Only page elements can be children of navigator');
- };
-
- /**
- * @element ons-navigator
- * @category navigation
- * @description
- * [en]
- * A component that provides page stack management and navigation. Stack navigation is the most common navigation pattern for mobile apps.
- *
- * When a page is pushed on top of the stack it is displayed with a transition animation. When the user returns to the previous page the top page will be popped from the top of the stack and hidden with an opposite transition animation.
- * [/en]
- * [ja][/ja]
- * @codepen yrhtv
- * @tutorial vanilla/Reference/navigator
- * @guide lifecycle.html#events
- * [en]Overview of page events[/en]
- * [ja]Overview of page events[/ja]
- * @seealso ons-toolbar
- * [en]The `<ons-toolbar>` component is used to display a toolbar on the top of a page.[/en]
- * [ja][/ja]
- * @seealso ons-back-button
- * [en]The `<ons-back-button>` component lets the user return to the previous page.[/en]
- * [ja][/ja]
- * @example
- * <ons-navigator id="navigator">
- * <ons-page>
- * <ons-toolbar>
- * <div class="center">
- * Title
- * </div>
- * </ons-toolbar>
- * <p>
- * <ons-button
- * onclick="document.getElementById('navigator').pushPage('page.html')">
- * Push page
- * </ons-button>
- * </p>
- * </ons-page>
- * </ons-navigator>
- *
- * <template id="page.html">
- * <ons-page>
- * <ons-toolbar>
- * <div class="left">
- * <ons-back-button>Back</ons-back-button>
- * </div>
- * <div class="center">
- * Another page
- * </div>
- * </ons-toolbar>
- * </ons-page>
- * </template>
- */
-
- var NavigatorElement = function (_BaseElement) {
- inherits(NavigatorElement, _BaseElement);
- createClass(NavigatorElement, [{
- key: 'animatorFactory',
-
-
- /**
- * @attribute page
- * @initonly
- * @type {String}
- * @description
- * [en]First page to show when navigator is initialized.[/en]
- * [ja]ナビゲーターが初期化された時に表示するページを指定します。[/ja]
- */
-
- /**
- * @attribute swipeable
- * @type {Boolean}
- * @description
- * [en]Enable iOS "swipe to pop" feature.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute swipe-target-width
- * @type {String}
- * @default 20px
- * @description
- * [en]The width of swipeable area calculated from the edge (in pixels). Use this to enable swipe only when the finger touch on the screen edge.[/en]
- * [ja]スワイプの判定領域をピクセル単位で指定します。画面の端から指定した距離に達するとページが表示されます。[/ja]
- */
-
- /**
- * @attribute swipe-threshold
- * @type {Number}
- * @default 0.2
- * @description
- * [en]Specify how much the page needs to be swiped before popping. A value between `0` and `1`.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]
- * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
- *
- * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"` depending on the platform.
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`[/ja]
- */
-
- /**
- * @event prepush
- * @description
- * [en]Fired just before a page is pushed.[/en]
- * [ja]pageがpushされる直前に発火されます。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.navigator
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Object} event.currentPage
- * [en]Current page object.[/en]
- * [ja]現在のpageオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Call this function to cancel the push.[/en]
- * [ja]この関数を呼び出すと、push処理がキャンセルされます。[/ja]
- */
-
- /**
- * @event prepop
- * @description
- * [en]Fired just before a page is popped.[/en]
- * [ja]pageがpopされる直前に発火されます。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.navigator
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Object} event.currentPage
- * [en]Current page object.[/en]
- * [ja]現在のpageオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Call this function to cancel the pop.[/en]
- * [ja]この関数を呼び出すと、pageのpopがキャンセルされます。[/ja]
- */
-
- /**
- * @event postpush
- * @description
- * [en]Fired just after a page is pushed.[/en]
- * [ja]pageがpushされてアニメーションが終了してから発火されます。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.navigator
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Object} event.enterPage
- * [en]Object of the next page.[/en]
- * [ja]pushされたpageオブジェクト。[/ja]
- * @param {Object} event.leavePage
- * [en]Object of the previous page.[/en]
- * [ja]以前のpageオブジェクト。[/ja]
- */
-
- /**
- * @event postpop
- * @description
- * [en]Fired just after a page is popped.[/en]
- * [ja]pageがpopされてアニメーションが終わった後に発火されます。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.navigator
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Object} event.enterPage
- * [en]Object of the next page.[/en]
- * [ja]popされて表示されるページのオブジェクト。[/ja]
- * @param {Object} event.leavePage
- * [en]Object of the previous page.[/en]
- * [ja]popされて消えるページのオブジェクト。[/ja]
- */
-
- get: function get$$1() {
- return this._animatorFactory;
- }
- }]);
-
- function NavigatorElement() {
- classCallCheck(this, NavigatorElement);
-
- var _this = possibleConstructorReturn(this, (NavigatorElement.__proto__ || Object.getPrototypeOf(NavigatorElement)).call(this));
-
- _this._isRunning = false;
- _this._initialized = false;
- _this._pageLoader = defaultPageLoader;
- _this._pageMap = new WeakMap();
-
- _this._updateAnimatorFactory();
- return _this;
- }
-
- /**
- * @property pageLoader
- * @type {PageLoader}
- * @description
- * [en]PageLoader instance. It can be overriden to change the way pages are loaded by this element. Useful for lib developers.[/en]
- * [ja]PageLoaderインスタンスを格納しています。[/ja]
- */
-
-
- createClass(NavigatorElement, [{
- key: '_getPageTarget',
- value: function _getPageTarget() {
- return this._page || this.getAttribute('page');
- }
-
- /**
- * @property page
- * @type {*}
- * @description
- * [en]Specify the page to be loaded during initialization. This value takes precedence over the `page` attribute. Useful for lib developers.[/en]
- * [ja]初期化時に読み込むページを指定します。`page`属性で指定した値よりも`page`プロパティに指定した値を優先します。[/ja]
- */
-
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- this.onDeviceBackButton = this._onDeviceBackButton.bind(this);
-
- if (!platform.isAndroid() || this.getAttribute('swipeable') === 'force') {
- var swipeAnimator = void 0;
-
- this._swipe = new SwipeReveal({
- element: this,
- getThreshold: function getThreshold() {
- return Math.max(0.2, parseFloat(_this2.getAttribute('swipe-threshold')) || 0);
- },
-
- swipeMax: function swipeMax() {
- _this2._onSwipe && _this2._onSwipe(1, { duration: swipeAnimator.durationSwipe, timing: swipeAnimator.timingSwipe });
- _this2[_this2.swipeMax ? 'swipeMax' : 'popPage']({ animator: swipeAnimator });
- swipeAnimator = null;
- },
- swipeMid: function swipeMid(distance, width) {
- _this2._onSwipe && _this2._onSwipe(distance / width);
- swipeAnimator.translate(distance, width, _this2.topPage.previousElementSibling, _this2.topPage);
- },
- swipeMin: function swipeMin() {
- _this2._onSwipe && _this2._onSwipe(0, { duration: swipeAnimator.durationRestore, timing: swipeAnimator.timingSwipe });
- swipeAnimator.restore(_this2.topPage.previousElementSibling, _this2.topPage);
- swipeAnimator = null;
- },
-
- ignoreSwipe: function ignoreSwipe(event, distance) {
- // Basic conditions
- if (!_this2._isRunning && _this2.children.length > 1) {
-
- // Area or directional issues
- var area = parseInt(_this2.getAttribute('swipe-target-width') || 25, 10);
- if (event.gesture.direction === 'right' && area > distance) {
-
- // Swipes on ons-back-button and its children
- var isBB = function isBB(el) {
- return (/ons-back-button/i.test(el.tagName)
- );
- };
- if (!isBB(event.target) && !util$1.findParent(event.target, isBB, function (p) {
- return (/ons-page/i.test(p.tagName)
- );
- })) {
-
- // Animator is swipeable
- var animation = (_this2.topPage.pushedOptions || {}).animation || _this2.animatorFactory._animation;
- var Animator = _animatorDict$5[animation] instanceof Function ? _animatorDict$5[animation].call() : _animatorDict$5[animation];
-
- if (typeof Animator !== 'undefined' && Animator.swipeable) {
- swipeAnimator = new Animator(); // Prepare for the swipe
- return false;
- }
- }
- }
- }
-
- return true; // Ignore swipe
- }
- });
-
- this.attributeChangedCallback('swipeable');
- }
-
- if (this._initialized) {
- return;
- }
-
- this._initialized = true;
-
- var deferred = util$1.defer();
- this.loaded = deferred.promise;
-
- rewritables.ready(this, function () {
- var show = !util$1.hasAnyComponentAsParent(_this2);
- var options = { animation: 'none', show: show };
-
- if (_this2.pages.length === 0 && _this2._getPageTarget()) {
- _this2.pushPage(_this2._getPageTarget(), options).then(function () {
- return deferred.resolve();
- });
- } else if (_this2.pages.length > 0) {
- for (var i = 0; i < _this2.pages.length; i++) {
- verifyPageElement(_this2.pages[i]);
- }
-
- if (_this2.topPage) {
- contentReady(_this2.topPage, function () {
- return setTimeout(function () {
- deferred.resolve();
- show && _this2.topPage._show();
- _this2._updateLastPageBackButton();
- }, 0);
- });
- }
- } else {
- contentReady(_this2, function () {
- if (_this2.pages.length === 0 && _this2._getPageTarget()) {
- _this2.pushPage(_this2._getPageTarget(), options).then(function () {
- return deferred.resolve();
- });
- } else {
- deferred.resolve();
- }
- });
- }
- });
- }
- }, {
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- this._animatorFactory = new AnimatorFactory({
- animators: _animatorDict$5,
- baseClass: NavigatorAnimator,
- baseClassName: 'NavigatorAnimator',
- defaultAnimation: this.getAttribute('animation')
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._backButtonHandler.destroy();
- this._backButtonHandler = null;
-
- this._swipe && this._swipe.dispose();
- this._swipe = null;
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'animation':
- this._updateAnimatorFactory();
- break;
- case 'swipeable':
- this._swipe && this._swipe.update();
- break;
- }
- }
-
- /**
- * @method popPage
- * @signature popPage([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]
- * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
- *
- * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"`.
- * [/en]
- * [ja][/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @param {Function} [options.callback]
- * [en]Function that is called when the transition has ended.[/en]
- * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
- * @param {Object} [options.data]
- * [en]Custom data that will be stored in the new page element.[/en]
- * [ja][/ja]
- * @param {Number} [options.times]
- * [en]Number of pages to be popped. Only one animation will be shown.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Promise which resolves to the revealed page.[/en]
- * [ja]明らかにしたページを解決するPromiseを返します。[/ja]
- * @description
- * [en]Pops the current page from the page stack. The previous page will be displayed.[/en]
- * [ja]現在表示中のページをページスタックから取り除きます。一つ前のページに戻ります。[/ja]
- */
-
- }, {
- key: 'popPage',
- value: function popPage() {
- var _this3 = this;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- var _preparePageAndOption = this._preparePageAndOptions(null, options);
-
- options = _preparePageAndOption.options;
-
-
- if (util$1.isInteger(options.times) && options.times > 1) {
- this._removePages(options.times);
- }
-
- var popUpdate = function popUpdate() {
- return new Promise(function (resolve) {
- _this3._pageLoader.unload(_this3.pages[_this3.pages.length - 1]);
- resolve();
- });
- };
-
- return this._popPage(options, popUpdate);
- }
- }, {
- key: '_popPage',
- value: function _popPage(options) {
- var _this4 = this;
-
- var update = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
- return Promise.resolve();
- };
-
- if (this._isRunning) {
- return Promise.reject('popPage is already running.');
- }
-
- if (this.pages.length <= 1) {
- return Promise.reject('ons-navigator\'s page stack is empty.');
- }
-
- if (this._emitPrePopEvent()) {
- return Promise.reject('Canceled in prepop event.');
- }
-
- var length = this.pages.length;
-
- this._isRunning = true;
-
- this.pages[length - 2].updateBackButton(length - 2 > 0);
-
- return new Promise(function (resolve) {
- var leavePage = _this4.pages[length - 1];
- var enterPage = _this4.pages[length - 2];
-
- options = util$1.extend({}, _this4.options || {}, leavePage.pushedOptions || {}, options);
-
- if (options.data) {
- enterPage.data = util$1.extend({}, enterPage.data || {}, options.data || {});
- }
-
- var done = function done() {
- update().then(function () {
- _this4._isRunning = false;
-
- enterPage._show();
- util$1.triggerElementEvent(_this4, 'postpop', { leavePage: leavePage, enterPage: enterPage, navigator: _this4 });
-
- options.callback && options.callback(enterPage);
-
- resolve(enterPage);
- });
- };
-
- leavePage._hide();
- enterPage.style.display = '';
-
- var animator = options.animator || _this4._animatorFactory.newAnimator(options);
- animator.pop(_this4.pages[length - 2], _this4.pages[length - 1], done);
- }).catch(function () {
- return _this4._isRunning = false;
- });
- }
-
- /**
- * @method pushPage
- * @signature pushPage(page, [options])
- * @param {String} page
- * [en]Page URL. Can be either a HTML document or a template defined with the `<template>` tag.[/en]
- * [ja]pageのURLか、もしくは`<template>`で宣言したテンプレートのid属性の値を指定できます。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.page]
- * [en]Page URL. Only necessary if `page` parameter is null or undefined.[/en]
- * [ja][/ja]
- * @param {String} [options.pageHTML]
- * [en]HTML code that will be computed as a new page. Overwrites `page` parameter.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]
- * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
- *
- * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"`.
- * [/en]
- * [ja][/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
- * @param {Function} [options.callback]
- * [en]Function that is called when the transition has ended.[/en]
- * [ja]pushPage()による画面遷移が終了した時に呼び出される関数オブジェクトを指定します。[/ja]
- * @param {Object} [options.data]
- * [en]Custom data that will be stored in the new page element.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Promise which resolves to the pushed page.[/en]
- * [ja]追加したページを解決するPromiseを返します。[/ja]
- * @description
- * [en]Pushes the specified page into the stack.[/en]
- * [ja]指定したpageを新しいページスタックに追加します。新しいページが表示されます。[/ja]
- */
-
- }, {
- key: 'pushPage',
- value: function pushPage(page) {
- var _this5 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var _preparePageAndOption2 = this._preparePageAndOptions(page, options);
-
- page = _preparePageAndOption2.page;
- options = _preparePageAndOption2.options;
-
-
- var prepare = function prepare(pageElement) {
- verifyPageElement(pageElement);
- _this5._pageMap.set(pageElement, page);
- pageElement = util$1.extend(pageElement, {
- data: options.data
- });
- pageElement.style.visibility = 'hidden';
- };
-
- if (options.pageHTML) {
- return this._pushPage(options, function () {
- return new Promise(function (resolve) {
- instantPageLoader.load({ page: options.pageHTML, parent: _this5, params: options.data }, function (pageElement) {
- prepare(pageElement);
- resolve();
- });
- });
- });
- }
-
- return this._pushPage(options, function () {
- return new Promise(function (resolve) {
- _this5._pageLoader.load({ page: page, parent: _this5, params: options.data }, function (pageElement) {
- prepare(pageElement);
- resolve();
- });
- });
- });
- }
- }, {
- key: '_pushPage',
- value: function _pushPage() {
- var _this6 = this;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var update = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
- return Promise.resolve();
- };
-
- if (this._isRunning) {
- return Promise.reject('pushPage is already running.');
- }
-
- if (this._emitPrePushEvent()) {
- return Promise.reject('Canceled in prepush event.');
- }
-
- this._isRunning = true;
-
- var animationOptions = AnimatorFactory.parseAnimationOptionsString(this.getAttribute('animation-options'));
- options = util$1.extend({}, this.options || {}, { animationOptions: animationOptions }, options);
-
- var animator = this._animatorFactory.newAnimator(options);
-
- return update().then(function () {
- var pageLength = _this6.pages.length;
-
- var enterPage = _this6.pages[pageLength - 1];
- var leavePage = options.leavePage || _this6.pages[pageLength - 2];
-
- verifyPageElement(enterPage);
-
- enterPage.updateBackButton(pageLength > (options._replacePage ? 2 : 1));
-
- enterPage.pushedOptions = util$1.extend({}, enterPage.pushedOptions || {}, options || {});
- enterPage.data = util$1.extend({}, enterPage.data || {}, options.data || {});
- enterPage.unload = enterPage.unload || options.unload;
-
- return new Promise(function (resolve) {
- var done = function done() {
- _this6._isRunning = false;
-
- options.show !== false && setImmediate(function () {
- return enterPage._show();
- });
- util$1.triggerElementEvent(_this6, 'postpush', { leavePage: leavePage, enterPage: enterPage, navigator: _this6 });
-
- if (leavePage) {
- leavePage.style.display = 'none';
- }
-
- options.callback && options.callback(enterPage);
-
- resolve(enterPage);
- };
-
- enterPage.style.visibility = '';
- if (leavePage) {
- leavePage._hide();
- animator.push(enterPage, leavePage, done);
- } else {
- done();
- }
- });
- }).catch(function (error) {
- _this6._isRunning = false;
- throw error;
- });
- }
-
- /**
- * @method replacePage
- * @signature replacePage(page, [options])
- * @return {Promise}
- * [en]Promise which resolves to the new page.[/en]
- * [ja]新しいページを解決するPromiseを返します。[/ja]
- * @description
- * [en]Replaces the current top page with the specified one. Extends `pushPage()` parameters.[/en]
- * [ja]現在表示中のページをを指定したページに置き換えます。[/ja]
- */
-
- }, {
- key: 'replacePage',
- value: function replacePage(page) {
- var _this7 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- return this.pushPage(page, options).then(function (resolvedValue) {
- if (_this7.pages.length > 1) {
- _this7._pageLoader.unload(_this7.pages[_this7.pages.length - 2]);
- }
- _this7._updateLastPageBackButton();
-
- return Promise.resolve(resolvedValue);
- });
- }
-
- /**
- * @method insertPage
- * @signature insertPage(index, page, [options])
- * @param {Number} index
- * [en]The index where it should be inserted.[/en]
- * [ja]スタックに挿入する位置のインデックスを指定します。[/ja]
- * @return {Promise}
- * [en]Promise which resolves to the inserted page.[/en]
- * [ja]指定したページを解決するPromiseを返します。[/ja]
- * @description
- * [en]Insert the specified page into the stack with at a position defined by the `index` argument. Extends `pushPage()` parameters.[/en]
- * [ja]指定したpageをページスタックのindexで指定した位置に追加します。[/ja]
- */
-
- }, {
- key: 'insertPage',
- value: function insertPage(index, page) {
- var _this8 = this;
-
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
-
- var _preparePageAndOption3 = this._preparePageAndOptions(page, options);
-
- page = _preparePageAndOption3.page;
- options = _preparePageAndOption3.options;
-
- index = this._normalizeIndex(index);
-
- if (index >= this.pages.length) {
- return this.pushPage(page, options);
- }
-
- page = typeof options.pageHTML === 'string' ? options.pageHTML : page;
- var loader = typeof options.pageHTML === 'string' ? instantPageLoader : this._pageLoader;
-
- return new Promise(function (resolve) {
- loader.load({ page: page, parent: _this8 }, function (pageElement) {
- verifyPageElement(pageElement);
- _this8._pageMap.set(pageElement, page);
- pageElement = util$1.extend(pageElement, {
- data: options.data,
- pushedOptions: options
- });
-
- options.animationOptions = util$1.extend({}, AnimatorFactory.parseAnimationOptionsString(_this8.getAttribute('animation-options')), options.animationOptions || {});
-
- pageElement.style.display = 'none';
- _this8.insertBefore(pageElement, _this8.pages[index]);
- _this8.topPage.updateBackButton(true);
-
- setTimeout(function () {
- pageElement = null;
- resolve(_this8.pages[index]);
- }, 1000 / 60);
- });
- });
- }
-
- /**
- * @method removePage
- * @signature removePage(index, [options])
- * @param {Number} index
- * [en]The index where it should be removed.[/en]
- * [ja]スタックから削除するページのインデックスを指定します。[/ja]
- * @return {Promise}
- * [en]Promise which resolves to the revealed page.[/en]
- * [ja]削除によって表示されたページを解決するPromiseを返します。[/ja]
- * @description
- * [en]Remove the specified page at a position in the stack defined by the `index` argument. Extends `popPage()` parameters.[/en]
- * [ja]指定したインデックスにあるページを削除します。[/ja]
- */
-
- }, {
- key: 'removePage',
- value: function removePage(index) {
- var _this9 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- index = this._normalizeIndex(index);
-
- if (index < this.pages.length - 1) {
- return new Promise(function (resolve) {
- var leavePage = _this9.pages[index];
- var enterPage = _this9.topPage;
-
- _this9._pageMap.delete(leavePage);
- _this9._pageLoader.unload(leavePage);
- if (_this9.pages.length === 1) {
- // edge case
- _this9.topPage.updateBackButton(false);
- }
-
- resolve(enterPage);
- });
- } else {
- return this.popPage(options);
- }
- }
-
- /**
- * @method resetToPage
- * @signature resetToPage(page, [options])
- * @return {Promise}
- * [en]Promise which resolves to the new top page.[/en]
- * [ja]新しいトップページを解決するPromiseを返します。[/ja]
- * @param {Boolean} [options.pop]
- * [en]Performs 'pop' effect if `true` instead of 'push' or none. This also sets `options.animation` value to `default` instead of `none`.[/en]
- * [ja][/ja]
- * @description
- * [en]Clears page stack and adds the specified page to the stack. Extends `pushPage()` parameters.[/en]
- * [ja]ページスタックをリセットし、指定したページを表示します。[/ja]
- */
-
- }, {
- key: 'resetToPage',
- value: function resetToPage(page) {
- var _this10 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var _preparePageAndOption4 = this._preparePageAndOptions(page, options);
-
- page = _preparePageAndOption4.page;
- options = _preparePageAndOption4.options;
-
-
- if (!options.animator && !options.animation && !options.pop) {
- options.animation = 'none';
- }
-
- if (!options.page && !options.pageHTML && this._getPageTarget()) {
- page = options.page = this._getPageTarget();
- }
-
- if (options.pop) {
- this._removePages();
- return this.insertPage(0, page, { data: options.data }).then(function () {
- return _this10.popPage(options);
- });
- }
-
- // Tip: callback runs before resolved promise
- var callback = options.callback;
- options.callback = function (newPage) {
- _this10._removePages();
- newPage.updateBackButton(false);
- callback && callback(newPage);
- };
-
- return this.pushPage(page, options);
- }
-
- /**
- * @method bringPageTop
- * @signature bringPageTop(item, [options])
- * @param {String|Number} item
- * [en]Page URL or index of an existing page in navigator's stack.[/en]
- * [ja]ページのURLかもしくはons-navigatorのページスタックのインデックス値を指定します。[/ja]
- * @return {Promise}
- * [en]Promise which resolves to the new top page.[/en]
- * [ja]新しいトップページを解決するPromiseを返します。[/ja]
- * @description
- * [en]Brings the given page to the top of the page stack if it already exists or pushes it into the stack if doesn't. Extends `pushPage()` parameters.[/en]
- * [ja]指定したページをページスタックの一番上に移動します。もし指定したページが無かった場合新しくpushされます。[/ja]
- */
-
- }, {
- key: 'bringPageTop',
- value: function bringPageTop(item) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (['number', 'string'].indexOf(typeof item === 'undefined' ? 'undefined' : _typeof(item)) === -1) {
- util$1.throw('First argument must be a page name or the index of an existing page. You supplied ' + item);
- }
- var index = typeof item === 'number' ? this._normalizeIndex(item) : this._lastIndexOfPage(item);
- var page = this.pages[index];
-
- if (index < 0) {
- return this.pushPage(item, options);
- }
-
- var _preparePageAndOption5 = this._preparePageAndOptions(page, options);
-
- options = _preparePageAndOption5.options;
-
-
- if (index === this.pages.length - 1) {
- return Promise.resolve(page);
- }
- if (!page) {
- util$1.throw('Failed to find item ' + item);
- }
- if (this._isRunning) {
- return Promise.reject('pushPage is already running.');
- }
- if (this._emitPrePushEvent()) {
- return Promise.reject('Canceled in prepush event.');
- }
-
- page.style.display = '';
- page.style.visibility = 'hidden';
- page.parentNode.appendChild(page);
- return this._pushPage(options);
- }
- }, {
- key: '_preparePageAndOptions',
- value: function _preparePageAndOptions(page) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) != 'object') {
- util$1.throw('options must be an object. You supplied ' + options);
- }
-
- if ((page === null || page === undefined) && options.page) {
- page = options.page;
- }
-
- options = util$1.extend({}, this.options || {}, options, { page: page });
-
- return { page: page, options: options };
- }
- }, {
- key: '_removePages',
- value: function _removePages(times) {
- var pages = this.pages;
- var until = times === undefined ? 0 : pages.length - times;
- until = until < 0 ? 1 : until;
-
- for (var i = pages.length - 2; i >= until; i--) {
- this._pageMap.delete(pages[i]);
- this._pageLoader.unload(pages[i]);
- }
- }
- }, {
- key: '_updateLastPageBackButton',
- value: function _updateLastPageBackButton() {
- var index = this.pages.length - 1;
- if (index >= 0) {
- this.pages[index].updateBackButton(index > 0);
- }
- }
- }, {
- key: '_normalizeIndex',
- value: function _normalizeIndex(index) {
- return index >= 0 ? index : Math.abs(this.pages.length + index) % this.pages.length;
- }
- }, {
- key: '_onDeviceBackButton',
- value: function _onDeviceBackButton(event) {
- if (this.pages.length > 1) {
- this.popPage();
- } else {
- event.callParentHandler();
- }
- }
- }, {
- key: '_lastIndexOfPage',
- value: function _lastIndexOfPage(pageName) {
- var index = void 0;
- for (index = this.pages.length - 1; index >= 0; index--) {
- if (pageName === this._pageMap.get(this.pages[index])) {
- break;
- }
- }
- return index;
- }
- }, {
- key: '_emitPreEvent',
- value: function _emitPreEvent(name) {
- var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var isCanceled = false;
-
- util$1.triggerElementEvent(this, 'pre' + name, util$1.extend({
- navigator: this,
- currentPage: this.pages[this.pages.length - 1],
- cancel: function cancel() {
- return isCanceled = true;
- }
- }, data));
-
- return isCanceled;
- }
- }, {
- key: '_emitPrePushEvent',
- value: function _emitPrePushEvent() {
- return this._emitPreEvent('push');
- }
- }, {
- key: '_emitPrePopEvent',
- value: function _emitPrePopEvent() {
- var l = this.pages.length;
- return this._emitPreEvent('pop', {
- leavePage: this.pages[l - 1],
- enterPage: this.pages[l - 2]
- });
- }
-
- // TODO: 書き直す
-
- }, {
- key: '_createPageElement',
- value: function _createPageElement(templateHTML) {
- var pageElement = util$1.createElement(internal$1.normalizePageHTML(templateHTML));
- verifyPageElement(pageElement);
- return pageElement;
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: '_show',
- value: function _show() {
- var _this11 = this;
-
- this.loaded.then(function () {
- return _this11.topPage && _this11.topPage._show();
- });
- }
- }, {
- key: '_hide',
- value: function _hide() {
- this.topPage && this.topPage._hide();
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- for (var i = this.pages.length - 1; i >= 0; i--) {
- this._pageLoader.unload(this.pages[i]);
- }
-
- this.remove();
- }
-
- /**
- * @param {String} name
- * @param {Function} Animator
- */
-
- }, {
- key: 'pageLoader',
- get: function get$$1() {
- return this._pageLoader;
- },
- set: function set$$1(pageLoader) {
- if (!(pageLoader instanceof PageLoader)) {
- util$1.throwPageLoader();
- }
- this._pageLoader = pageLoader;
- }
- }, {
- key: 'page',
- get: function get$$1() {
- return this._page;
- },
- set: function set$$1(page) {
- this._page = page;
- }
- }, {
- key: 'onDeviceBackButton',
- get: function get$$1() {
- return this._backButtonHandler;
- },
- set: function set$$1(callback) {
- if (this._backButtonHandler) {
- this._backButtonHandler.destroy();
- }
-
- this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
- }
-
- /**
- * @property topPage
- * @readonly
- * @type {HTMLElement}
- * @description
- * [en]Current top page element. Use this method to access options passed by `pushPage()`-like methods.[/en]
- * [ja]現在のページを取得します。pushPage()やresetToPage()メソッドの引数を取得できます。[/ja]
- */
-
- }, {
- key: 'topPage',
- get: function get$$1() {
- var last = this.lastElementChild;
- while (last && last.tagName !== 'ONS-PAGE') {
- last = last.previousElementSibling;
- }
- return last;
- }
-
- /**
- * @property pages
- * @readonly
- * @type {Array}
- * @description
- * [en]Copy of the navigator's page stack.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'pages',
- get: function get$$1() {
- return util$1.arrayFrom(this.children).filter(function (element) {
- return element.tagName === 'ONS-PAGE';
- });
- }
-
- /**
- * @property onSwipe
- * @type {Function}
- * @description
- * [en]Hook called whenever the user slides the navigator (swipe-to-pop). It gets a decimal ratio (0-1) and an animationOptions object as arguments.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onSwipe',
- get: function get$$1() {
- return this._onSwipe;
- },
- set: function set$$1(value) {
- if (value && !(value instanceof Function)) {
- util$1.throw('"onSwipe" must be a function');
- }
- this._onSwipe = value;
- }
-
- /**
- * @property options
- * @type {Object}
- * @description
- * [en]Default options object. Attributes have priority over this property.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property options.animation
- * @type {String}
- * @description
- * [en]
- * Animation name. Available animations are `"slide"`, `"lift"`, `"fade"` and `"none"`.
- * These are platform based animations. For fixed animations, add `"-ios"` or `"-md"` suffix to the animation name. E.g. `"lift-ios"`, `"lift-md"`. Defaults values are `"slide-ios"` and `"fade-md"`.
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @property options.animationOptions
- * @type {String}
- * @description
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}` [/ja]
- */
-
- /**
- * @property options.callback
- * @type {String}
- * @description
- * [en]Function that is called when the transition has ended.[/en]
- * [ja]このメソッドによる画面遷移が終了した際に呼び出される関数オブジェクトを指定します。[/ja]
- */
-
- }, {
- key: 'options',
- get: function get$$1() {
- return this._options;
- },
- set: function set$$1(object) {
- this._options = object;
- }
- }, {
- key: '_isRunning',
- set: function set$$1(value) {
- this.setAttribute('_is-running', value ? 'true' : 'false');
- },
- get: function get$$1() {
- return JSON.parse(this.getAttribute('_is-running'));
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof NavigatorAnimator)) {
- util$1.throwAnimator('Navigator');
- }
-
- _animatorDict$5[name] = Animator;
- }
- }, {
- key: 'observedAttributes',
- get: function get$$1() {
- return ['animation', 'swipeable'];
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$5;
- }
- }, {
- key: 'NavigatorAnimator',
- get: function get$$1() {
- return NavigatorAnimator;
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['prepush', 'postpush', 'prepop', 'postpop'];
- }
- }, {
- key: 'rewritables',
- get: function get$$1() {
- return rewritables;
- }
- }]);
- return NavigatorElement;
- }(BaseElement);
-
- onsElements.Navigator = NavigatorElement;
- customElements.define('ons-navigator', NavigatorElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$10 = 'toolbar';
-
- var scheme$18 = {
- '': 'toolbar--*',
- '.toolbar__left': 'toolbar--*__left',
- '.toolbar__center': 'toolbar--*__center',
- '.toolbar__right': 'toolbar--*__right'
- };
-
- /**
- * @element ons-toolbar
- * @category page
- * @modifier material
- * [en]Material Design toolbar.[/en]
- * [ja][/ja]
- * @modifier transparent
- * [en]Transparent toolbar.[/en]
- * [ja]透明な背景を持つツールバーを表示します。[/ja]
- * @modifier cover-content
- * [en]Displays the toolbar on top of the page's content. Should be combined with `transparent` modifier.[/en]
- * [ja][/ja]
- * @modifier noshadow
- * [en]Toolbar without shadow.[/en]
- * [ja]ツールバーに影を付けずに表示します。[/ja]
- * @description
- * [en]
- * Toolbar component that can be used with navigation.
- *
- * Left, center and right containers can be specified by class names.
- *
- * This component will automatically display as a Material Design toolbar when running on Android devices.
- * [/en]
- * [ja]ナビゲーションで使用するツールバー用コンポーネントです。クラス名により、左、中央、右のコンテナを指定できます。[/ja]
- * @codepen aHmGL
- * @tutorial vanilla/Reference/toolbar
- * @guide compilation.html#toolbar-compilation [en]Adding a toolbar[/en][ja]ツールバーの追加[/ja]
- * @seealso ons-bottom-toolbar
- * [en]The `<ons-bottom-toolbar>` displays a toolbar on the bottom of the page.[/en]
- * [ja]ons-bottom-toolbarコンポーネント[/ja]
- * @seealso ons-back-button
- * [en]The `<ons-back-button>` component displays a back button inside the toolbar.[/en]
- * [ja]ons-back-buttonコンポーネント[/ja]
- * @seealso ons-toolbar-button
- * [en]The `<ons-toolbar-button>` component displays a toolbar button inside the toolbar.[/en]
- * [ja]ons-toolbar-buttonコンポーネント[/ja]
- * @example
- * <ons-page>
- * <ons-toolbar>
- * <div class="left">
- * <ons-back-button>
- * Back
- * </ons-back-button>
- * </div>
- * <div class="center">
- * Title
- * </div>
- * <div class="right">
- * <ons-toolbar-button>
- * <ons-icon icon="md-menu"></ons-icon>
- * </ons-toolbar-button>
- * </div>
- * </ons-toolbar>
- * </ons-page>
- */
-
- var ToolbarElement = function (_BaseElement) {
- inherits(ToolbarElement, _BaseElement);
-
- /**
- * @attribute inline
- * @initonly
- * @description
- * [en]Display the toolbar as an inline element.[/en]
- * [ja]ツールバーをインラインに置きます。スクロール領域内にそのまま表示されます。[/ja]
- */
-
- /**
- * @attribute static
- * @description
- * [en]Static toolbars are not animated by `ons-navigator` when pushing or popping pages. This can be useful to improve performance in some situations.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute modifier
- * @description
- * [en]The appearance of the toolbar.[/en]
- * [ja]ツールバーの表現を指定します。[/ja]
- */
-
- function ToolbarElement() {
- classCallCheck(this, ToolbarElement);
-
- var _this = possibleConstructorReturn(this, (ToolbarElement.__proto__ || Object.getPrototypeOf(ToolbarElement)).call(this));
-
- contentReady(_this, function () {
- _this._compile();
- });
- return _this;
- }
-
- createClass(ToolbarElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$10, scheme$18);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$18);
- break;
- }
- }
-
- /**
- * @method setVisibility
- * @signature setVisibility(visible)
- * @param {Boolean} visible
- * [en]Set to true to show the toolbar, false to hide it[/en]
- * [ja][/ja]
- * @description
- * [en]Shows the toolbar if visible is true, otherwise hides it.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'setVisibility',
- value: function setVisibility(visible) {
- var _this2 = this;
-
- contentReady(this, function () {
- _this2.style.display = visible ? '' : 'none';
-
- if (_this2.parentNode) {
- var siblingBackground = util$1.findChild(_this2.parentNode, '.page__background');
- if (siblingBackground) {
- siblingBackground.style.top = visible ? null : 0;
- }
-
- var siblingContent = util$1.findChild(_this2.parentNode, '.page__content');
- if (siblingContent) {
- siblingContent.style.top = visible ? null : 0;
- }
- }
- });
- }
-
- /**
- * @method show
- * @signature show()
- * @description
- * [en]Show the toolbar.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'show',
- value: function show() {
- this.setVisibility(true);
- }
-
- /**
- * @method hide
- * @signature hide()
- * @description
- * [en]Hide the toolbar.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'hide',
- value: function hide() {
- this.setVisibility(false);
- }
-
- /**
- * @return {HTMLElement}
- */
-
- }, {
- key: '_getToolbarLeftItemsElement',
- value: function _getToolbarLeftItemsElement() {
- return this.querySelector('.left') || internal$1.nullElement;
- }
-
- /**
- * @return {HTMLElement}
- */
-
- }, {
- key: '_getToolbarCenterItemsElement',
- value: function _getToolbarCenterItemsElement() {
- return this.querySelector('.center') || internal$1.nullElement;
- }
-
- /**
- * @return {HTMLElement}
- */
-
- }, {
- key: '_getToolbarRightItemsElement',
- value: function _getToolbarRightItemsElement() {
- return this.querySelector('.right') || internal$1.nullElement;
- }
-
- /**
- * @return {HTMLElement}
- */
-
- }, {
- key: '_getToolbarBackButtonLabelElement',
- value: function _getToolbarBackButtonLabelElement() {
- return this.querySelector('ons-back-button .back-button__label') || internal$1.nullElement;
- }
-
- /**
- * @return {HTMLElement}
- */
-
- }, {
- key: '_getToolbarBackButtonIconElement',
- value: function _getToolbarBackButtonIconElement() {
- return this.querySelector('ons-back-button .back-button__icon') || internal$1.nullElement;
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$10);
- this._ensureToolbarItemElements();
- ModifierUtil.initModifier(this, scheme$18);
- }
- }, {
- key: '_ensureToolbarItemElements',
- value: function _ensureToolbarItemElements() {
- for (var i = this.childNodes.length - 1; i >= 0; i--) {
- // case of not element
- if (this.childNodes[i].nodeType != 1) {
- this.removeChild(this.childNodes[i]);
- }
- }
-
- var center = this._ensureToolbarElement('center');
- center.classList.add('toolbar__title');
-
- if (this.children.length !== 1 || !this.children[0].classList.contains('center')) {
- var left = this._ensureToolbarElement('left');
- var right = this._ensureToolbarElement('right');
-
- if (this.children[0] !== left || this.children[1] !== center || this.children[2] !== right) {
- this.appendChild(left);
- this.appendChild(center);
- this.appendChild(right);
- }
- }
- }
- }, {
- key: '_ensureToolbarElement',
- value: function _ensureToolbarElement(name) {
- if (util$1.findChild(this, '.toolbar__' + name)) {
- var _element = util$1.findChild(this, '.toolbar__' + name);
- _element.classList.add(name);
- return _element;
- }
-
- var element = util$1.findChild(this, '.' + name) || util$1.create('.' + name);
- element.classList.add('toolbar__' + name);
-
- return element;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'];
- }
- }]);
- return ToolbarElement;
- }(BaseElement);
-
- onsElements.Toolbar = ToolbarElement;
- customElements.define('ons-toolbar', ToolbarElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$9 = 'page';
- var scheme$17 = {
- '': 'page--*',
- '.page__content': 'page--*__content',
- '.page__background': 'page--*__background'
- };
-
- /**
- * @element ons-page
- * @category page
- * @modifier material
- * [en]Material Design style[/en]
- * [ja][/ja]
- * @description
- * [en]
- * This component defines the root of each page. If the content is large it will become scrollable.
- *
- * A navigation bar can be added to the top of the page using the `<ons-toolbar>` element.
- * [/en]
- * [ja]ページ定義のためのコンポーネントです。このコンポーネントの内容はスクロールが許可されます。[/ja]
- * @tutorial vanilla/Reference/page
- * @guide lifecycle.html#events
- * [en]Overview of page events[/en]
- * [ja]Overview of page events[/ja]
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages[/en]
- * [ja]複数のページを管理する[/ja]
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @seealso ons-toolbar
- * [en]Use the `<ons-toolbar>` element to add a navigation bar to the top of the page.[/en]
- * [ja][/ja]
- * @example
- * <ons-page>
- * <ons-toolbar>
- * <div class="left">
- * <ons-back-button>Back</ons-back-button>
- * </div>
- * <div class="center">Title</div>
- * <div class="right">
- * <ons-toolbar-button>
- * <ons-icon icon="md-menu"></ons-icon>
- * </ons-toolbar-button>
- * </div>
- * </ons-toolbar>
- *
- * <p>Page content</p>
- * </ons-page>
- *
- * @example
- * <script>
- * myApp.handler = function(done) {
- * loadMore().then(done);
- * }
- * </script>
- *
- * <ons-page on-infinite-scroll="myApp.handler">
- * <ons-toolbar>
- * <div class="center">List</div>
- * </ons-toolbar>
- *
- * <ons-list>
- * <ons-list-item>#1</ons-list-item>
- * <ons-list-item>#2</ons-list-item>
- * <ons-list-item>#3</ons-list-item>
- * ...
- * </ons-list>
- * </ons-page>
- */
-
- var PageElement = function (_BaseElement) {
- inherits(PageElement, _BaseElement);
-
- /**
- * @event init
- * @description
- * [en]Fired right after the page is attached.[/en]
- * [ja]ページがアタッチされた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @event show
- * @description
- * [en]Fired right after the page is shown.[/en]
- * [ja]ページが表示された後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @event hide
- * @description
- * [en]Fired right after the page is hidden.[/en]
- * [ja]ページが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @event destroy
- * @description
- * [en]Fired right before the page is destroyed.[/en]
- * [ja]ページが破棄される前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]Specify modifier name to specify custom styles.[/en]
- * [ja]スタイル定義をカスタマイズするための名前を指定します。[/ja]
- */
-
- /**
- * @attribute on-infinite-scroll
- * @type {String}
- * @description
- * [en]Path of the function to be executed on infinite scrolling. Example: `app.loadData`. The function receives a done callback that must be called when it's finished.[/en]
- * [ja][/ja]
- */
-
- function PageElement() {
- classCallCheck(this, PageElement);
-
- var _this = possibleConstructorReturn(this, (PageElement.__proto__ || Object.getPrototypeOf(PageElement)).call(this));
-
- _this._deriveHooks();
-
- _this._defaultClassName = defaultClassName$9;
- _this.classList.add(defaultClassName$9);
-
- _this._initialized = false;
-
- contentReady(_this, function () {
- _this._compile();
-
- _this._isShown = false;
- _this._contentElement = _this._getContentElement();
- _this._backgroundElement = _this._getBackgroundElement();
- });
- return _this;
- }
-
- createClass(PageElement, [{
- key: '_compile',
- value: function _compile() {
- var _this2 = this;
-
- autoStyle.prepare(this);
-
- var toolbar = util$1.findChild(this, 'ons-toolbar');
-
- var background = util$1.findChild(this, '.page__background') || util$1.findChild(this, '.background') || document.createElement('div');
- background.classList.add('page__background');
- this.insertBefore(background, !toolbar && this.firstChild || toolbar && toolbar.nextSibling);
-
- var content = util$1.findChild(this, '.page__content') || util$1.findChild(this, '.content') || document.createElement('div');
- content.classList.add('page__content');
- if (!content.parentElement) {
- util$1.arrayFrom(this.childNodes).forEach(function (node) {
- if (node.nodeType !== 1 || _this2._elementShouldBeMoved(node)) {
- content.appendChild(node); // Can trigger detached connectedCallbacks
- }
- });
- }
-
- this._tryToFillStatusBar(content); // Must run before child pages try to fill status bar.
- this.insertBefore(content, background.nextSibling); // Can trigger attached connectedCallbacks
-
- if ((!toolbar || !util$1.hasModifier(toolbar, 'transparent')) && content.children.length === 1 && util$1.isPageControl(content.children[0])) {
- this._defaultClassName += ' page--wrapper';
- this.attributeChangedCallback('class');
- }
-
- var bottomToolbar = util$1.findChild(this, 'ons-bottom-toolbar');
- if (bottomToolbar) {
- this._defaultClassName += ' page-with-bottom-toolbar';
- this.attributeChangedCallback('class');
- }
-
- ModifierUtil.initModifier(this, scheme$17);
- }
- }, {
- key: '_elementShouldBeMoved',
- value: function _elementShouldBeMoved(el) {
- if (el.classList.contains('page__background')) {
- return false;
- }
- var tagName = el.tagName.toLowerCase();
- if (tagName === 'ons-fab') {
- return !el.hasAttribute('position');
- }
- var fixedElements = ['script', 'ons-toolbar', 'ons-bottom-toolbar', 'ons-modal', 'ons-speed-dial', 'ons-dialog', 'ons-alert-dialog', 'ons-popover', 'ons-action-sheet'];
- return el.hasAttribute('inline') || fixedElements.indexOf(tagName) === -1;
- }
- }, {
- key: '_tryToFillStatusBar',
- value: function _tryToFillStatusBar() {
- var _this3 = this;
-
- var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._contentElement;
-
- internal$1.autoStatusBarFill(function () {
- util$1.toggleAttribute(_this3, 'status-bar-fill', !util$1.findParent(_this3, function (e) {
- return e.hasAttribute('status-bar-fill');
- }) // Not already filled
- && (_this3._canAnimateToolbar(content) || !util$1.findChild(content, util$1.isPageControl)) // Has toolbar or cannot delegate
- );
- });
- }
- }, {
- key: '_canAnimateToolbar',
- value: function _canAnimateToolbar() {
- var content = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._contentElement;
-
- if (util$1.findChild(this, 'ons-toolbar')) {
- return true;
- }
-
- return !!util$1.findChild(content, function (el) {
- return util$1.match(el, 'ons-toolbar') && !el.hasAttribute('inline');
- });
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this4 = this;
-
- if (!util$1.isAttached(this)) {
- // Avoid detached calls
- return;
- }
-
- contentReady(this, function () {
- _this4._tryToFillStatusBar(); // Ensure status bar when the element was compiled before connected
-
- if (_this4.hasAttribute('on-infinite-scroll')) {
- _this4.attributeChangedCallback('on-infinite-scroll', null, _this4.getAttribute('on-infinite-scroll'));
- }
-
- if (!_this4._initialized) {
- _this4._initialized = true;
-
- setImmediate(function () {
- _this4.onInit && _this4.onInit();
- util$1.triggerElementEvent(_this4, 'init');
- });
-
- if (!util$1.hasAnyComponentAsParent(_this4)) {
- setImmediate(function () {
- return _this4._show();
- });
- }
- }
- });
- }
- }, {
- key: 'updateBackButton',
- value: function updateBackButton(show) {
- if (this.backButton) {
- show ? this.backButton.show() : this.backButton.hide();
- }
- }
- }, {
- key: '_onScroll',
- value: function _onScroll() {
- var _this5 = this;
-
- var c = this._contentElement,
- overLimit = (c.scrollTop + c.clientHeight) / c.scrollHeight >= this._infiniteScrollLimit;
-
- if (this._onInfiniteScroll && !this._loadingContent && overLimit) {
- this._loadingContent = true;
- this._onInfiniteScroll(function () {
- return _this5._loadingContent = false;
- });
- }
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: '_getContentElement',
- value: function _getContentElement() {
- var result = util$1.findChild(this, '.page__content');
- if (result) {
- return result;
- }
- util$1.throw('Fail to get ".page__content" element');
- }
- }, {
- key: '_getBackgroundElement',
- value: function _getBackgroundElement() {
- var result = util$1.findChild(this, '.page__background');
- if (result) {
- return result;
- }
- util$1.throw('Fail to get ".page__background" element');
- }
- }, {
- key: '_getBottomToolbarElement',
- value: function _getBottomToolbarElement() {
- return util$1.findChild(this, 'ons-bottom-toolbar') || internal$1.nullElement;
- }
- }, {
- key: '_getToolbarElement',
- value: function _getToolbarElement() {
- return util$1.findChild(this, 'ons-toolbar') || document.createElement('ons-toolbar');
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this6 = this;
-
- switch (name) {
- case 'class':
- util$1.restoreClass(this, this._defaultClassName, scheme$17);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$17);
- break;
- case 'on-infinite-scroll':
- if (current === null) {
- this.onInfiniteScroll = null;
- } else {
- this.onInfiniteScroll = function (done) {
- var f = util$1.findFromPath(current);
- _this6.onInfiniteScroll = f;
- f(done);
- };
- }
- break;
- }
- }
- }, {
- key: '_show',
- value: function _show() {
- if (!this._isShown && util$1.isAttached(this)) {
- this._isShown = true;
- this.setAttribute('shown', '');
- this.onShow && this.onShow();
- util$1.triggerElementEvent(this, 'show');
- util$1.propagateAction(this, '_show');
- }
- }
- }, {
- key: '_hide',
- value: function _hide() {
- if (this._isShown) {
- this._isShown = false;
- this.removeAttribute('shown');
- this.onHide && this.onHide();
- util$1.triggerElementEvent(this, 'hide');
- util$1.propagateAction(this, '_hide');
- }
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- this._hide();
-
- this.onDestroy && this.onDestroy();
- util$1.triggerElementEvent(this, 'destroy');
-
- if (this.onDeviceBackButton) {
- this.onDeviceBackButton.destroy();
- }
-
- util$1.propagateAction(this, '_destroy');
-
- this.remove();
- }
- }, {
- key: '_deriveHooks',
- value: function _deriveHooks() {
- var _this7 = this;
-
- this.constructor.events.forEach(function (event) {
- var key = 'on' + event.charAt(0).toUpperCase() + event.slice(1);
- Object.defineProperty(_this7, key, {
- configurable: true,
- enumerable: true,
- get: function get$$1() {
- return _this7['_' + key];
- },
- set: function set$$1(value) {
- if (!(value instanceof Function)) {
- util$1.throw('"' + key + '" hook must be a function');
- }
- _this7['_' + key] = value.bind(_this7);
- }
- });
- });
- }
- }, {
- key: 'name',
- set: function set$$1(str) {
- this.setAttribute('name', str);
- },
- get: function get$$1() {
- return this.getAttribute('name');
- }
- }, {
- key: 'backButton',
- get: function get$$1() {
- return this.querySelector('ons-back-button');
- }
-
- /**
- * @property onInfiniteScroll
- * @description
- * [en]Function to be executed when scrolling to the bottom of the page. The function receives a done callback as an argument that must be called when it's finished.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onInfiniteScroll',
- set: function set$$1(value) {
- var _this8 = this;
-
- if (value && !(value instanceof Function)) {
- util$1.throw('"onInfiniteScroll" must be function or null');
- }
-
- contentReady(this, function () {
- if (!value) {
- _this8._contentElement.removeEventListener('scroll', _this8._boundOnScroll);
- } else if (!_this8._onInfiniteScroll) {
- _this8._infiniteScrollLimit = 0.9;
- _this8._boundOnScroll = _this8._onScroll.bind(_this8);
- setImmediate(function () {
- return _this8._contentElement.addEventListener('scroll', _this8._boundOnScroll);
- });
- }
- _this8._onInfiniteScroll = value;
- });
- },
- get: function get$$1() {
- return this._onInfiniteScroll;
- }
- }, {
- key: 'onDeviceBackButton',
- get: function get$$1() {
- return this._backButtonHandler;
- },
- set: function set$$1(callback) {
- if (this._backButtonHandler) {
- this._backButtonHandler.destroy();
- }
-
- this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
- }
- }, {
- key: 'scrollTop',
- get: function get$$1() {
- return this._contentElement.scrollTop;
- },
- set: function set$$1(newValue) {
- this._contentElement.scrollTop = newValue;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'on-infinite-scroll', 'class'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['init', 'show', 'hide', 'destroy'];
- }
-
- /**
- * @property data
- * @type {*}
- * @description
- * [en]User's custom data passed to `pushPage()`-like methods.[/en]
- * [ja][/ja]
- */
-
- }]);
- return PageElement;
- }(BaseElement);
-
- onsElements.Page = PageElement;
- customElements.define('ons-page', PageElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
- var PopoverAnimator = function (_BaseAnimator) {
- inherits(PopoverAnimator, _BaseAnimator);
-
- /**
- * @param {Object} options
- * @param {String} options.timing
- * @param {Number} options.duration
- * @param {Number} options.delay
- */
- function PopoverAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .4, 1)' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, PopoverAnimator);
- return possibleConstructorReturn(this, (PopoverAnimator.__proto__ || Object.getPrototypeOf(PopoverAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- createClass(PopoverAnimator, [{
- key: 'show',
- value: function show(popover, callback) {
- callback();
- }
- }, {
- key: 'hide',
- value: function hide(popover, callback) {
- callback();
- }
- }, {
- key: '_animate',
- value: function _animate(element, _ref2) {
- var from = _ref2.from,
- to = _ref2.to,
- options = _ref2.options,
- callback = _ref2.callback,
- _ref2$restore = _ref2.restore,
- restore = _ref2$restore === undefined ? false : _ref2$restore,
- animation = _ref2.animation;
-
- options = util$1.extend({}, this.options, options);
-
- if (animation) {
- from = animation.from;
- to = animation.to;
- }
-
- animation = Animit(element);
- if (restore) {
- animation = animation.saveStyle();
- }
- animation = animation.queue(from).wait(this.delay).queue({
- css: to,
- duration: this.duration,
- timing: this.timing
- });
- if (restore) {
- animation = animation.restoreStyle();
- }
- if (callback) {
- animation = animation.queue(function (done) {
- callback();
- done();
- });
- }
- return animation;
- }
- }, {
- key: '_animateAll',
- value: function _animateAll(element, animations) {
- var _this2 = this;
-
- Object.keys(animations).forEach(function (key) {
- return _this2._animate(element[key], animations[key]).play();
- });
- }
- }]);
- return PopoverAnimator;
- }(BaseAnimator);
-
- var fade = {
- out: {
- from: { opacity: 1.0 },
- to: { opacity: 0 }
- },
- in: {
- from: { opacity: 0 },
- to: { opacity: 1.0 }
- }
- };
-
- var MDFadePopoverAnimator = function (_PopoverAnimator) {
- inherits(MDFadePopoverAnimator, _PopoverAnimator);
-
- function MDFadePopoverAnimator() {
- classCallCheck(this, MDFadePopoverAnimator);
- return possibleConstructorReturn(this, (MDFadePopoverAnimator.__proto__ || Object.getPrototypeOf(MDFadePopoverAnimator)).apply(this, arguments));
- }
-
- createClass(MDFadePopoverAnimator, [{
- key: 'show',
- value: function show(popover, callback) {
- this._animateAll(popover, {
- _mask: fade.in,
- _popover: { animation: fade.in, restore: true, callback: callback }
- });
- }
- }, {
- key: 'hide',
- value: function hide(popover, callback) {
- this._animateAll(popover, {
- _mask: fade.out,
- _popover: { animation: fade.out, restore: true, callback: callback }
- });
- }
- }]);
- return MDFadePopoverAnimator;
- }(PopoverAnimator);
-
- var IOSFadePopoverAnimator = function (_MDFadePopoverAnimato) {
- inherits(IOSFadePopoverAnimator, _MDFadePopoverAnimato);
-
- function IOSFadePopoverAnimator() {
- classCallCheck(this, IOSFadePopoverAnimator);
- return possibleConstructorReturn(this, (IOSFadePopoverAnimator.__proto__ || Object.getPrototypeOf(IOSFadePopoverAnimator)).apply(this, arguments));
- }
-
- createClass(IOSFadePopoverAnimator, [{
- key: 'show',
- value: function show(popover, callback) {
- this._animateAll(popover, {
- _mask: fade.in,
- _popover: {
- from: {
- transform: 'scale3d(1.3, 1.3, 1.0)',
- opacity: 0
- },
- to: {
- transform: 'scale3d(1.0, 1.0, 1.0)',
- opacity: 1.0
- },
- restore: true,
- callback: callback
- }
- });
- }
- }]);
- return IOSFadePopoverAnimator;
- }(MDFadePopoverAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$19 = {
- '.popover': 'popover--*',
- '.popover-mask': 'popover-mask--*',
- '.popover__content': 'popover--*__content',
- '.popover__arrow': 'popover--*__arrow'
- };
-
- var _animatorDict$6 = {
- 'default': function _default() {
- return platform.isAndroid() ? MDFadePopoverAnimator : IOSFadePopoverAnimator;
- },
- 'none': PopoverAnimator,
- 'fade-ios': IOSFadePopoverAnimator,
- 'fade-md': MDFadePopoverAnimator
- };
-
- var positions = {
- up: 'bottom',
- left: 'right',
- down: 'top',
- right: 'left'
- };
-
- /**
- * @element ons-popover
- * @category dialog
- * @description
- * [en]
- * A component that displays a popover next to an element. The popover can be used to display extra information about a component or a tooltip.
- *
- * To use the element it can either be attached directly to the `<body>` element or dynamically created from a template using the `ons.createPopover(template)` utility function and the `<template>` tag.
- *
- * Another common way to use the popover is to display a menu when a button on the screen is tapped. For Material Design, popover looks exactly as a dropdown menu.
- * [/en]
- * [ja]ある要素を対象とするポップオーバーを表示するコンポーネントです。[/ja]
- * @codepen ZYYRKo
- * @tutorial vanilla/Reference/popover
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- * <ons-button onclick="showPopover(this)">
- * Click me!
- * </ons-button>
- *
- * <ons-popover direction="down" id="popover">
- * <p>This is a popover!</p>
- * </ons-popover>
- *
- * <script>
- * var showPopover = function(element) {
- * var popover = document.getElementById('popover');
- * popover.show(element);
- * };
- * </script>
- */
-
- var PopoverElement = function (_BaseDialogElement) {
- inherits(PopoverElement, _BaseDialogElement);
-
- /**
- * @event preshow
- * @description
- * [en]Fired just before the popover is displayed.[/en]
- * [ja]ポップオーバーが表示される直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.popover
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Call this function to stop the popover from being shown.[/en]
- * [ja]この関数を呼び出すと、ポップオーバーの表示がキャンセルされます。[/ja]
- */
-
- /**
- * @event postshow
- * @description
- * [en]Fired just after the popover is displayed.[/en]
- * [ja]ポップオーバーが表示された直後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.popover
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @event prehide
- * @description
- * [en]Fired just before the popover is hidden.[/en]
- * [ja]ポップオーバーが隠れる直前に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.popover
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Call this function to stop the popover from being hidden.[/en]
- * [ja]この関数を呼び出すと、ポップオーバーが隠れる処理をキャンセルします。[/ja]
- */
-
- /**
- * @event posthide
- * @description
- * [en]Fired just after the popover is hidden.[/en]
- * [ja]ポップオーバーが隠れた後に発火します。[/ja]
- * @param {Object} event [en]Event object.[/en]
- * @param {Object} event.popover
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the popover.[/en]
- * [ja]ポップオーバーの表現を指定します。[/ja]
- */
-
- /**
- * @attribute direction
- * @type {String}
- * @description
- * [en]
- * A space separated list of directions. If more than one direction is specified,
- * it will be chosen automatically. Valid directions are `"up"`, `"down"`, `"left"` and `"right"`.
- * [/en]
- * [ja]
- * ポップオーバーを表示する方向を空白区切りで複数指定できます。
- * 指定できる方向は、"up", "down", "left", "right"の4つです。空白区切りで複数指定することもできます。
- * 複数指定された場合、対象とする要素に合わせて指定した値から自動的に選択されます。
- * [/ja]
- */
-
- /**
- * @attribute cancelable
- * @description
- * [en]If this attribute is set the popover can be closed by tapping the background or by pressing the back button.[/en]
- * [ja]この属性があると、ポップオーバーが表示された時に、背景やバックボタンをタップした時にをポップオーバー閉じます。[/ja]
- */
-
- /**
- * @attribute cover-target
- * @description
- * [en]If set the popover will cover the target on the screen.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @description
- * [en]The animation used when showing an hiding the popover. Can be either `"none"`, `"default"`, `"fade-ios"` or `"fade-md"`.[/en]
- * [ja]ポップオーバーを表示する際のアニメーション名を指定します。[/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
- */
-
- /**
- * @attribute mask-color
- * @type {Color}
- * @description
- * [en]Color of the background mask. Default is `"rgba(0, 0, 0, 0.2)"`.[/en]
- * [ja]背景のマスクの色を指定します。デフォルトは"rgba(0, 0, 0, 0.2)"です。[/ja]
- */
-
- function PopoverElement() {
- classCallCheck(this, PopoverElement);
-
- var _this = possibleConstructorReturn(this, (PopoverElement.__proto__ || Object.getPrototypeOf(PopoverElement)).call(this));
-
- _this._boundOnChange = _this._onChange.bind(_this);
-
- contentReady(_this, function () {
- _this._compile();
- _this.style.display = 'none';
- });
- return _this;
- }
-
- createClass(PopoverElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- return new AnimatorFactory({
- animators: _animatorDict$6,
- baseClass: PopoverAnimator,
- baseClassName: 'PopoverAnimator',
- defaultAnimation: this.getAttribute('animation') || 'default'
- });
- }
- }, {
- key: '_toggleStyle',
- value: function _toggleStyle(shouldShow) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (shouldShow) {
- this.style.display = 'block';
- this._currentTarget = options.target;
- this._positionPopover(options.target);
- } else {
- this.style.display = 'none';
- this._clearStyles();
- }
- }
- }, {
- key: '_positionPopover',
- value: function _positionPopover(target) {
- var radius = this._radius,
- contentElement = this._content,
- margin = this._margin;
-
- var safeAreaLengths = iPhoneXPatch.getSafeAreaLengths();
- var safeAreaRect = iPhoneXPatch.getSafeAreaDOMRect();
- var targetRect = target.getBoundingClientRect();
- var isMD = util$1.hasModifier(this, 'material');
- var cover = isMD && this.hasAttribute('cover-target');
- var parent = util$1.findParent(this, 'ons-page') || document.body;
- var parentDimensions = parent.getBoundingClientRect();
- var maxPositions = {
- top: Math.max(parentDimensions.top, safeAreaRect.top),
- left: Math.max(parentDimensions.left, safeAreaRect.left),
- bottom: Math.min(parentDimensions.bottom, safeAreaRect.bottom),
- right: Math.min(parentDimensions.right, safeAreaRect.right)
- };
-
- // Distance from each side of the safe area (with margin) to the target element
- var targetDistance = {
- top: targetRect.top - (maxPositions.top + margin),
- left: targetRect.left - (maxPositions.left + margin),
- bottom: maxPositions.bottom - margin - targetRect.bottom,
- right: maxPositions.right - margin - targetRect.right
- };
-
- // Distance from each side of the safe area (with margin) to the geometric center of the target element
- var targetCenterDistanceFrom = {
- top: targetRect.top + Math.round(targetRect.height / 2) - (maxPositions.top + margin),
- left: targetRect.left + Math.round(targetRect.width / 2) - (maxPositions.left + margin),
- bottom: maxPositions.bottom - margin - targetRect.bottom + Math.round(targetRect.height / 2),
- right: maxPositions.right - margin - targetRect.right + Math.round(targetRect.width / 2)
- };
-
- var _calculateDirections2 = this._calculateDirections(targetDistance),
- vertical = _calculateDirections2.vertical,
- primaryDirection = _calculateDirections2.primary,
- secondaryDirection = _calculateDirections2.secondary;
-
- this._currentDirection = primaryDirection;
- util$1.addModifier(this, primaryDirection);
-
- var sizeName = vertical ? 'width' : 'height';
- // Get .popover__content size
- var contentSize = function (style) {
- return {
- width: parseInt(style.getPropertyValue('width'), 10),
- height: parseInt(style.getPropertyValue('height'), 10)
- };
- }(window.getComputedStyle(contentElement));
-
- // Setting .popover position.
- var targetAndArrowLength = cover ? 0 : (vertical ? targetRect.height : targetRect.width) + (isMD ? 0 : 14);
- var primaryOffset = Math.max(safeAreaLengths[primaryDirection] + margin, safeAreaLengths[primaryDirection] + margin + targetDistance[primaryDirection] + targetAndArrowLength);
- var secondaryOffset = Math.max(safeAreaLengths[secondaryDirection] + margin, safeAreaLengths[secondaryDirection] + margin + targetCenterDistanceFrom[secondaryDirection] - contentSize[sizeName] / 2);
- this._popover.style[primaryDirection] = primaryOffset + 'px';
- this._popover.style[secondaryDirection] = secondaryOffset + 'px';
-
- // Setting .popover__arrow position.
- this._arrow.style[secondaryDirection] = Math.max(radius, safeAreaLengths[secondaryDirection] + margin + targetCenterDistanceFrom[secondaryDirection] - secondaryOffset) + 'px';
- }
- }, {
- key: '_calculateDirections',
- value: function _calculateDirections(distance) {
- var options = (this.getAttribute('direction') || 'up down left right').split(/\s+/).map(function (e) {
- return positions[e];
- });
- var primary = options.sort(function (a, b) {
- return distance[a] - distance[b];
- })[0];
- var vertical = 'top' == primary || 'bottom' == primary;
- var secondary = void 0;
-
- if (vertical) {
- secondary = distance.left < distance.right ? 'left' : 'right';
- } else {
- secondary = distance.top < distance.bottom ? 'top' : 'bottom';
- }
-
- return { vertical: vertical, primary: primary, secondary: secondary };
- }
- }, {
- key: '_clearStyles',
- value: function _clearStyles() {
- var _this2 = this;
-
- this._currentDirection = null;
- ['top', 'bottom', 'left', 'right'].forEach(function (e) {
- _this2._arrow.style[e] = _this2._content.style[e] = _this2._popover.style[e] = '';
- util$1.removeModifier(_this2, e);
- });
- }
- }, {
- key: '_onChange',
- value: function _onChange() {
- var _this3 = this;
-
- setImmediate(function () {
- if (_this3._currentTarget) {
- _this3._positionPopover(_this3._currentTarget);
- }
- });
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- if (this._popover && this._mask) {
- return;
- }
-
- var hasDefaultContainer = this._popover && this._content;
-
- if (hasDefaultContainer) {
-
- if (!this._mask) {
- var mask = document.createElement('div');
- mask.classList.add('popover-mask');
- this.insertBefore(mask, this.firstChild);
- }
-
- if (!this._arrow) {
- var arrow = document.createElement('div');
- arrow.classList.add('popover__arrow');
- this._popover.appendChild(arrow);
- }
- } else {
-
- var template = util$1.createFragment('\n <div class="popover-mask"></div>\n <div class="popover">\n <div class="popover__content"></div>\n <div class="popover__arrow"></div>\n </div>\n ');
- var content = template.querySelector('.popover__content');
-
- while (this.childNodes[0]) {
- content.appendChild(this.childNodes[0]);
- }
-
- this.appendChild(template);
- }
-
- // FIXME!
- if (this.hasAttribute('style')) {
- this._popover.setAttribute('style', this.getAttribute('style'));
- this.removeAttribute('style');
- }
-
- ModifierUtil.initModifier(this, this._scheme);
- }
-
- /**
- * @method show
- * @signature show(target, [options])
- * @param {String|Event|HTMLElement} target
- * [en]Target element. Can be either a CSS selector, an event object or a DOM element. It can be also provided as 'options.target' instead. [/en]
- * [ja]ポップオーバーのターゲットとなる要素を指定します。CSSセレクタかeventオブジェクトかDOM要素のいずれかを渡せます。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Use one of `"fade-ios"`, `"fade-md"`, `"none"` and `"default"`.[/en]
- * [ja]アニメーション名を指定します。"fade-ios", "fade-md", "none", "default"のいずれかを指定できます。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @param {Function} [options.callback]
- * [en]This function is called after the popover has been revealed.[/en]
- * [ja]ポップオーバーが表示され終わった後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Open the popover and point it at a target. The target can be either an event, a CSS selector or a DOM element..[/en]
- * [ja]対象とする要素にポップオーバーを表示します。target引数には、$eventオブジェクトやDOMエレメントやCSSセレクタを渡すことが出来ます。[/ja]
- * @return {Promise}
- * [en]Resolves to the displayed element[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'show',
- value: function show(target) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- // Copy options and include options.target
- if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && !(target instanceof Event) && !(target instanceof HTMLElement)) {
- options = _extends({}, target);
- } else {
- options = _extends({}, options, { target: target });
- }
-
- if (typeof options.target === 'string') {
- options.target = document.querySelector(options.target);
- } else if (options.target instanceof Event) {
- options.target = options.target.target;
- }
-
- if (!(options.target instanceof HTMLElement)) {
- util$1.throw('Invalid target type or undefined');
- }
-
- return get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'show', this).call(this, options);
- }
-
- /**
- * @method hide
- * @signature hide([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Use one of `"fade-ios"`, `"fade-md"`, `"none"` and `"default"`.[/en]
- * [ja]アニメーション名を指定します。"fade-ios", "fade-md", "none", "default"のいずれかを指定できます。[/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @param {Function} [options.callback]
- * [en]This functions is called after the popover has been hidden.[/en]
- * [ja]ポップオーバーが隠れた後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Close the popover.[/en]
- * [ja]ポップオーバーを閉じます。[/ja]
- * @return {Promise}
- * [en]Resolves to the hidden element[/en]
- * [ja][/ja]
- */
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the element is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- /**
- * @property cancelable
- * @type {Boolean}
- * @description
- * [en]
- * A boolean value that specifies whether the popover is cancelable or not.
- *
- * When the popover is cancelable it can be closed by tapping the background or by pressing the back button on Android devices.
- * [/en]
- * [ja][/ja]
- */
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this4 = this;
-
- get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'connectedCallback', this).call(this);
-
- window.addEventListener('resize', this._boundOnChange, false);
- this._margin = this._margin || parseInt(window.getComputedStyle(this).getPropertyValue('top'));
- this._margin = this._margin || 6; // Fix for iframes
-
- contentReady(this, function () {
- _this4._radius = parseInt(window.getComputedStyle(_this4._content).getPropertyValue('border-top-left-radius'));
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'disconnectedCallback', this).call(this);
- window.removeEventListener('resize', this._boundOnChange, false);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'direction') {
- return this._boundOnChange();
- } else if (name === 'modifier') {
- this._currentDirection && util$1.addModifier(this, this._currentDirection);
- }
- get(PopoverElement.prototype.__proto__ || Object.getPrototypeOf(PopoverElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
-
- /**
- * @param {String} name
- * @param {PopoverAnimator} Animator
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$19;
- }
- }, {
- key: '_mask',
- get: function get$$1() {
- return util$1.findChild(this, '.popover-mask');
- }
- }, {
- key: '_popover',
- get: function get$$1() {
- return util$1.findChild(this, '.popover');
- }
- }, {
- key: '_content',
- get: function get$$1() {
- return util$1.findChild(this._popover, '.popover__content');
- }
- }, {
- key: '_arrow',
- get: function get$$1() {
- return util$1.findChild(this._popover, '.popover__arrow');
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof PopoverAnimator)) {
- util$1.throwAnimator('Popover');
- }
- _animatorDict$6[name] = Animator;
- }
- }, {
- key: 'observedAttributes',
- get: function get$$1() {
- return [].concat(toConsumableArray(get(PopoverElement.__proto__ || Object.getPrototypeOf(PopoverElement), 'observedAttributes', this)), ['direction']);
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$6;
- }
- }, {
- key: 'PopoverAnimator',
- get: function get$$1() {
- return PopoverAnimator;
- }
- }]);
- return PopoverElement;
- }(BaseDialogElement);
-
- onsElements.Popover = PopoverElement;
- customElements.define('ons-popover', PopoverElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$20 = {
- '.progress-bar': 'progress-bar--*',
- '.progress-bar__primary': 'progress-bar--*__primary',
- '.progress-bar__secondary': 'progress-bar--*__secondary'
- };
-
- var template = util$1.createElement('\n <div class="progress-bar">\n <div class="progress-bar__secondary"></div>\n <div class="progress-bar__primary"></div>\n </div>\n');
-
- var INDET = 'indeterminate';
-
- /**
- * @element ons-progress-bar
- * @category visual
- * @modifier material
- * [en]Display a Material Design progress bar.[/en]
- * [ja]マテリアルデザインのスタイルでプログレスバーを表示します。[/ja]
- * @description
- * [en]
- * The component is used to display a linear progress bar. It can either display a progress bar that shows the user how much of a task has been completed. In the case where the percentage is not known it can be used to display an animated progress bar so the user can see that an operation is in progress.
- * [/en]
- * [ja][/ja]
- * @codepen zvQbGj
- * @tutorial vanilla/Reference/progress
- * @seealso ons-progress-circular
- * [en]The `<ons-progress-circular>` component displays a circular progress indicator.[/en]
- * [ja][/ja]
- * @example
- * <ons-progress-bar
- * value="55"
- * secondary-value="87">
- * </ons-progress-bar>
- *
- * <ons-progress-bar
- * indeterminate>
- * </ons-progress-bar>
- */
-
- var ProgressBarElement = function (_BaseElement) {
- inherits(ProgressBarElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]Change the appearance of the progress indicator.[/en]
- * [ja]プログレスインジケータの見た目を変更します。[/ja]
- */
-
- /**
- * @attribute value
- * @type {Number}
- * @description
- * [en]Current progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- /**
- * @attribute secondary-value
- * @type {Number}
- * @description
- * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- /**
- * @attribute indeterminate
- * @description
- * [en]If this attribute is set, an infinite looping animation will be shown.[/en]
- * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
- */
-
- function ProgressBarElement() {
- classCallCheck(this, ProgressBarElement);
-
- var _this = possibleConstructorReturn(this, (ProgressBarElement.__proto__ || Object.getPrototypeOf(ProgressBarElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(ProgressBarElement, [{
- key: '_compile',
- value: function _compile() {
- if (!this._isCompiled()) {
- this._template = template.cloneNode(true);
- } else {
- this._template = util$1.findChild(this, '.progress-bar');
- }
-
- this._primary = util$1.findChild(this._template, '.progress-bar__primary');
- this._secondary = util$1.findChild(this._template, '.progress-bar__secondary');
-
- this._updateDeterminate();
- this._updateValue();
-
- this.appendChild(this._template);
-
- autoStyle.prepare(this);
- ModifierUtil.initModifier(this, scheme$20);
- }
- }, {
- key: '_isCompiled',
- value: function _isCompiled() {
- if (!util$1.findChild(this, '.progress-bar')) {
- return false;
- }
-
- var barElement = util$1.findChild(this, '.progress-bar');
-
- if (!util$1.findChild(barElement, '.progress-bar__secondary')) {
- return false;
- }
-
- if (!util$1.findChild(barElement, '.progress-bar__primary')) {
- return false;
- }
-
- return true;
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'modifier') {
- ModifierUtil.onModifierChanged(last, current, this, scheme$20);
- this.hasAttribute(INDET) && this._updateDeterminate();
- } else if (name === 'value' || name === 'secondary-value') {
- this._updateValue();
- } else if (name === INDET) {
- this._updateDeterminate();
- }
- }
- }, {
- key: '_updateDeterminate',
- value: function _updateDeterminate() {
- var _this2 = this;
-
- contentReady(this, function () {
- return util$1.toggleModifier(_this2, INDET, { force: _this2.hasAttribute(INDET) });
- });
- }
- }, {
- key: '_updateValue',
- value: function _updateValue() {
- var _this3 = this;
-
- contentReady(this, function () {
- _this3._primary.style.width = _this3.hasAttribute('value') ? _this3.getAttribute('value') + '%' : '0%';
- _this3._secondary.style.width = _this3.hasAttribute('secondary-value') ? _this3.getAttribute('secondary-value') + '%' : '0%';
- });
- }
-
- /**
- * @property value
- * @type {Number}
- * @description
- * [en]Current progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- }, {
- key: 'value',
- set: function set$$1(value) {
- if (typeof value !== 'number' || value < 0 || value > 100) {
- util$1.throw('Invalid value');
- }
-
- this.setAttribute('value', Math.floor(value));
- },
- get: function get$$1() {
- return parseInt(this.getAttribute('value') || '0');
- }
-
- /**
- * @property secondaryValue
- * @type {Number}
- * @description
- * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- }, {
- key: 'secondaryValue',
- set: function set$$1(value) {
- if (typeof value !== 'number' || value < 0 || value > 100) {
- util$1.throw('Invalid value');
- }
-
- this.setAttribute('secondary-value', Math.floor(value));
- },
- get: function get$$1() {
- return parseInt(this.getAttribute('secondary-value') || '0');
- }
-
- /**
- * @property indeterminate
- * @type {Boolean}
- * @description
- * [en]If this property is `true`, an infinite looping animation will be shown.[/en]
- * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
- */
-
- }, {
- key: 'indeterminate',
- set: function set$$1(value) {
- if (value) {
- this.setAttribute(INDET, '');
- } else {
- this.removeAttribute(INDET);
- }
- },
- get: function get$$1() {
- return this.hasAttribute(INDET);
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'value', 'secondary-value', INDET];
- }
- }]);
- return ProgressBarElement;
- }(BaseElement);
-
- onsElements.ProgressBar = ProgressBarElement;
- customElements.define('ons-progress-bar', ProgressBarElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$21 = {
- '.progress-circular': 'progress-circular--*',
- '.progress-circular__background': 'progress-circular--*__background',
- '.progress-circular__primary': 'progress-circular--*__primary',
- '.progress-circular__secondary': 'progress-circular--*__secondary'
- };
-
- var template$1 = util$1.createElement('\n <svg class="progress-circular">\n <circle class="progress-circular__background" />\n <circle class="progress-circular__secondary" cx="50%" cy="50%" r="40%" />\n <circle class="progress-circular__primary" cx="50%" cy="50%" r="40%" />\n </svg>\n');
-
- var INDET$1 = 'indeterminate';
-
- /**
- * @element ons-progress-circular
- * @category visual
- * @description
- * [en]
- * This component displays a circular progress indicator. It can either be used to show how much of a task has been completed or to show a looping animation to indicate that an operation is currently running.
- * [/en]
- * [ja][/ja]
- * @codepen EVzMjR
- * @tutorial vanilla/Reference/progress-circular
- * @seealso ons-progress-bar
- * [en]The `<ons-progress-bar>` component displays a bar progress indicator.[/en]
- * [ja][/ja]
- * @example
- * <ons-progress-circular
- * value="55"
- * secondary-value="87">
- * </ons-progress-circular>
- *
- * <ons-progress-circular
- * indeterminate>
- * </ons-progress-circular>
- */
-
- var ProgressCircularElement = function (_BaseElement) {
- inherits(ProgressCircularElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]Change the appearance of the progress indicator.[/en]
- * [ja]プログレスインジケータの見た目を変更します。[/ja]
- */
-
- /**
- * @attribute value
- * @type {Number}
- * @description
- * [en]Current progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- /**
- * @attribute secondary-value
- * @type {Number}
- * @description
- * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- /**
- * @attribute indeterminate
- * @description
- * [en]If this attribute is set, an infinite looping animation will be shown.[/en]
- * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
- */
-
- function ProgressCircularElement() {
- classCallCheck(this, ProgressCircularElement);
-
- var _this = possibleConstructorReturn(this, (ProgressCircularElement.__proto__ || Object.getPrototypeOf(ProgressCircularElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(ProgressCircularElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'modifier') {
- ModifierUtil.onModifierChanged(last, current, this, scheme$21);
- this.hasAttribute(INDET$1) && this._updateDeterminate();
- } else if (name === 'value' || name === 'secondary-value') {
- this._updateValue();
- } else if (name === INDET$1) {
- this._updateDeterminate();
- }
- }
- }, {
- key: '_updateDeterminate',
- value: function _updateDeterminate() {
- var _this2 = this;
-
- contentReady(this, function () {
- return util$1.toggleModifier(_this2, INDET$1, { force: _this2.hasAttribute(INDET$1) });
- });
- }
- }, {
- key: '_updateValue',
- value: function _updateValue() {
- var _this3 = this;
-
- if (this.hasAttribute('value')) {
- contentReady(this, function () {
- var per = Math.ceil(_this3.getAttribute('value') * 251.32 * 0.01);
- _this3._primary.style['stroke-dasharray'] = per + '%, 251.32%';
- });
- }
- if (this.hasAttribute('secondary-value')) {
- contentReady(this, function () {
- var per = Math.ceil(_this3.getAttribute('secondary-value') * 251.32 * 0.01);
- _this3._secondary.style.display = null;
- _this3._secondary.style['stroke-dasharray'] = per + '%, 251.32%';
- });
- } else {
- contentReady(this, function () {
- _this3._secondary.style.display = 'none';
- });
- }
- }
-
- /**
- * @property value
- * @type {Number}
- * @description
- * [en]Current progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- }, {
- key: '_compile',
- value: function _compile() {
- if (this._isCompiled()) {
- this._template = util$1.findChild(this, '.progress-circular');
- } else {
- this._template = template$1.cloneNode(true);
- }
-
- this._primary = util$1.findChild(this._template, '.progress-circular__primary');
- this._secondary = util$1.findChild(this._template, '.progress-circular__secondary');
-
- this._updateDeterminate();
- this._updateValue();
-
- this.appendChild(this._template);
-
- autoStyle.prepare(this);
- ModifierUtil.initModifier(this, scheme$21);
- }
- }, {
- key: '_isCompiled',
- value: function _isCompiled() {
- if (!util$1.findChild(this, '.progress-circular')) {
- return false;
- }
-
- var svg = util$1.findChild(this, '.progress-circular');
-
- if (!util$1.findChild(svg, '.progress-circular__secondary')) {
- return false;
- }
-
- if (!util$1.findChild(svg, '.progress-circular__primary')) {
- return false;
- }
-
- return true;
- }
- }, {
- key: 'value',
- set: function set$$1(value) {
- if (typeof value !== 'number' || value < 0 || value > 100) {
- util$1.throw('Invalid value');
- }
-
- this.setAttribute('value', Math.floor(value));
- },
- get: function get$$1() {
- return parseInt(this.getAttribute('value') || '0');
- }
-
- /**
- * @property secondaryValue
- * @type {Number}
- * @description
- * [en]Current secondary progress. Should be a value between 0 and 100.[/en]
- * [ja]現在の2番目の進行状況の値を指定します。0から100の間の値を指定して下さい。[/ja]
- */
-
- }, {
- key: 'secondaryValue',
- set: function set$$1(value) {
- if (typeof value !== 'number' || value < 0 || value > 100) {
- util$1.throw('Invalid value');
- }
-
- this.setAttribute('secondary-value', Math.floor(value));
- },
- get: function get$$1() {
- return parseInt(this.getAttribute('secondary-value') || '0');
- }
-
- /**
- * @property indeterminate
- * @type {Boolean}
- * @description
- * [en]If this property is `true`, an infinite looping animation will be shown.[/en]
- * [ja]この属性が設定された場合、ループするアニメーションが表示されます。[/ja]
- */
-
- }, {
- key: 'indeterminate',
- set: function set$$1(value) {
- if (value) {
- this.setAttribute(INDET$1, '');
- } else {
- this.removeAttribute(INDET$1);
- }
- },
- get: function get$$1() {
- return this.hasAttribute(INDET$1);
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'value', 'secondary-value', INDET$1];
- }
- }]);
- return ProgressCircularElement;
- }(BaseElement);
-
- onsElements.ProgressCircular = ProgressCircularElement;
- customElements.define('ons-progress-circular', ProgressCircularElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var STATE_INITIAL = 'initial';
- var STATE_PREACTION = 'preaction';
- var STATE_ACTION = 'action';
-
- var throwType = function throwType(el, type) {
- return util$1.throw('"' + el + '" must be ' + type);
- };
-
- /**
- * @element ons-pull-hook
- * @category control
- * @description
- * [en]
- * Component that adds **Pull to refresh** functionality to an `<ons-page>` element.
- *
- * It can be used to perform a task when the user pulls down at the top of the page. A common usage is to refresh the data displayed in a page.
- * [/en]
- * [ja][/ja]
- * @codepen WbJogM
- * @tutorial vanilla/Reference/pull-hook
- * @example
- * <ons-page>
- * <ons-pull-hook>
- * Release to refresh
- * </ons-pull-hook>
- * </ons-page>
- *
- * <script>
- * document.querySelector('ons-pull-hook').onAction = function(done) {
- * setTimeout(done, 1000);
- * };
- * </script>
- */
-
- var PullHookElement = function (_BaseElement) {
- inherits(PullHookElement, _BaseElement);
-
- /**
- * @event changestate
- * @description
- * [en]Fired when the state is changed. The state can be either "initial", "preaction" or "action".[/en]
- * [ja]コンポーネントの状態が変わった場合に発火します。状態は、"initial", "preaction", "action"のいずれかです。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクト。[/ja]
- * @param {Object} event.pullHook
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {String} event.state
- * [en]Current state.[/en]
- * [ja]現在の状態名を参照できます。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]If this attribute is set the "pull-to-refresh" functionality is disabled.[/en]
- * [ja]この属性がある時、disabled状態になりアクションが実行されなくなります[/ja]
- */
-
- /**
- * @attribute height
- * @type {String}
- * @description
- * [en]Specify the height of the component. When pulled down further than this value it will switch to the "preaction" state. The default value is "64px".[/en]
- * [ja]コンポーネントの高さを指定します。この高さ以上にpull downすると"preaction"状態に移行します。デフォルトの値は"64px"です。[/ja]
- */
-
- /**
- * @attribute threshold-height
- * @type {String}
- * @description
- * [en]Specify the threshold height. The component automatically switches to the "action" state when pulled further than this value. The default value is "96px". A negative value will disable this property. If this value is lower than the height, it will skip "preaction" state.[/en]
- * [ja]閾値となる高さを指定します。この値で指定した高さよりもpull downすると、このコンポーネントは自動的に"action"状態に移行します。[/ja]
- */
-
- /**
- * @attribute fixed-content
- * @description
- * [en]If this attribute is set the content of the page will not move when pulling.[/en]
- * [ja]この属性がある時、プルフックが引き出されている時にもコンテンツは動きません。[/ja]
- */
-
- function PullHookElement() {
- classCallCheck(this, PullHookElement);
-
- var _this = possibleConstructorReturn(this, (PullHookElement.__proto__ || Object.getPrototypeOf(PullHookElement)).call(this));
-
- _this._shouldFixScroll = util$1.globals.isUIWebView;
-
- _this._onDrag = _this._onDrag.bind(_this);
- _this._onDragStart = _this._onDragStart.bind(_this);
- _this._onDragEnd = _this._onDragEnd.bind(_this);
- _this._onScroll = _this._onScroll.bind(_this);
-
- _this._setState(STATE_INITIAL, true);
- _this._hide(); // Fix for transparent toolbar transitions
- return _this;
- }
-
- createClass(PullHookElement, [{
- key: '_setStyle',
- value: function _setStyle() {
- var height = this.height + 'px';
- styler(this, { height: height, lineHeight: height });
- this.style.display === '' && this._show();
- }
- }, {
- key: '_onScroll',
- value: function _onScroll(event) {
- var element = this._pageElement;
-
- if (element.scrollTop < 0) {
- element.scrollTop = 0;
- }
- }
- }, {
- key: '_canConsumeGesture',
- value: function _canConsumeGesture(gesture) {
- return gesture.direction === 'up' || gesture.direction === 'down';
- }
- }, {
- key: '_onDragStart',
- value: function _onDragStart(event) {
- var _this2 = this;
-
- if (!event.gesture || this.disabled) {
- return;
- }
-
- var tapY = event.gesture.center.clientY + this._pageElement.scrollTop;
- var maxY = window.innerHeight;
- // Only use drags that start near the pullHook to reduce flickerings
- var draggableAreaRatio = this._shouldFixScroll ? .8 : 1;
-
- this._ignoreDrag = event.consumed || tapY > maxY * draggableAreaRatio;
-
- if (!this._ignoreDrag) {
- var consume = event.consume;
- event.consume = function () {
- consume && consume();
- _this2._ignoreDrag = true;
- // This elements resizes .page__content so it is safer
- // to hide it when other components are dragged.
- _this2._hide();
- };
-
- if (this._canConsumeGesture(event.gesture)) {
- consume && consume();
- event.consumed = true;
- this._show(); // Not enough due to 'dragLockAxis'
- }
- }
-
- this._startScroll = this._pageElement.scrollTop;
- }
- }, {
- key: '_onDrag',
- value: function _onDrag(event) {
- var _this3 = this;
-
- if (!event.gesture || this.disabled || this._ignoreDrag || !this._canConsumeGesture(event.gesture)) {
- return;
- }
-
- // Necessary due to 'dragLockAxis' (25px)
- if (this.style.display === 'none') {
- this._show();
- }
-
- event.stopPropagation();
-
- var tapY = event.gesture.center.clientY + this._pageElement.scrollTop;
- var maxY = window.innerHeight;
-
- // Hack to make it work on Android 4.4 WebView and iOS UIWebView. Scrolls manually
- // near the top of the page so there will be no inertial scroll when scrolling down.
- // Allowing default scrolling will kill all 'touchmove' events.
- if (this._shouldFixScroll) {
- this._pageElement.scrollTop = this._startScroll - event.gesture.deltaY;
- // Allow inertia when scrolling down below 50% of the view to reduce flickerings
- if (event.gesture.interimDirection !== 'up' || tapY <= maxY * .5) {
- event.gesture.preventDefault();
- }
- }
-
- var scroll = Math.max(event.gesture.deltaY - this._startScroll, 0);
- if (scroll !== this._currentTranslation) {
-
- var th = this.thresholdHeight;
- if (th > 0 && scroll >= th) {
- event.gesture.stopDetect();
- setImmediate(function () {
- return _this3._finish();
- });
- } else if (scroll >= this.height) {
- this._setState(STATE_PREACTION);
- } else {
- this._setState(STATE_INITIAL);
- }
-
- this._translateTo(scroll);
- }
- }
- }, {
- key: '_onDragEnd',
- value: function _onDragEnd(event) {
- if (!event.gesture || this.disabled || this._ignoreDrag) {
- return;
- }
-
- event.stopPropagation();
-
- if (this._currentTranslation > 0) {
- var scroll = this._currentTranslation;
-
- if (scroll > this.height) {
- this._finish();
- } else {
- this._translateTo(0, { animate: true });
- }
- }
- }
-
- /**
- * @property onAction
- * @type {Function}
- * @description
- * [en]This will be called in the `action` state if it exists. The function will be given a `done` callback as it's first argument.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: '_finish',
- value: function _finish() {
- var _this4 = this;
-
- this._setState(STATE_ACTION);
- this._translateTo(this.height, { animate: true });
- var action = this.onAction || function (done) {
- return done();
- };
- action(function () {
- _this4._translateTo(0, { animate: true });
- _this4._setState(STATE_INITIAL);
- });
- }
-
- /**
- * @property height
- * @type {Number}
- * @description
- * [en]The height of the pull hook in pixels. The default value is `64px`.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: '_setState',
- value: function _setState(state, noEvent) {
- var lastState = this.state;
-
- this.setAttribute('state', state);
-
- if (!noEvent && lastState !== this.state) {
- util$1.triggerElementEvent(this, 'changestate', {
- pullHook: this,
- state: state,
- lastState: lastState
- });
- }
- }
-
- /**
- * @property state
- * @readonly
- * @type {String}
- * @description
- * [en]Current state of the element.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: '_show',
- value: function _show() {
- var _this5 = this;
-
- // Run asyncrhonously to avoid conflicts with Animit's style clean
- setImmediate(function () {
- _this5.style.display = '';
- if (_this5._pageElement) {
- _this5._pageElement.style.marginTop = '-' + _this5.height + 'px';
- }
- });
- }
- }, {
- key: '_hide',
- value: function _hide() {
- this.style.display = 'none';
- if (this._pageElement) {
- this._pageElement.style.marginTop = '';
- }
- }
-
- /**
- * @param {Number} scroll
- * @param {Object} options
- * @param {Function} [options.callback]
- */
-
- }, {
- key: '_translateTo',
- value: function _translateTo(scroll) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (this._currentTranslation == 0 && scroll == 0) {
- return;
- }
-
- this._currentTranslation = scroll;
- var opt = options.animate ? { duration: .3, timing: 'cubic-bezier(.1, .7, .1, 1)' } : {};
- this._onPull && this._onPull((scroll / this.height).toFixed(2), opt);
- var scrollElement = this.hasAttribute('fixed-content') ? this : this._pageElement;
-
- Animit(scrollElement).queue({ transform: 'translate3d(0px, ' + scroll + 'px, 0px)' }, opt).play(function () {
- scroll === 0 && styler.clear(scrollElement, 'transition transform');
- options.callback instanceof Function && options.callback();
- });
- }
- }, {
- key: '_disableDragLock',
- value: function _disableDragLock() {
- // e2e tests need it
- this._dragLockDisabled = true;
- this._setupListeners(true);
- }
- }, {
- key: '_setupListeners',
- value: function _setupListeners(add) {
- var _this6 = this;
-
- var scrollToggle = function scrollToggle(action) {
- return _this6._pageElement[action + 'EventListener']('scroll', _this6._onScroll, false);
- };
- var gdToggle = function gdToggle(action) {
- var passive = { passive: true };
- _this6._gestureDetector[action]('drag', _this6._onDrag, passive);
- _this6._gestureDetector[action]('dragstart', _this6._onDragStart, passive);
- _this6._gestureDetector[action]('dragend', _this6._onDragEnd, passive);
- };
-
- if (this._gestureDetector) {
- gdToggle('off');
- this._gestureDetector.dispose();
- this._gestureDetector = null;
- }
- scrollToggle('remove');
-
- if (add) {
- this._gestureDetector = new GestureDetector(this._pageElement, {
- dragMinDistance: 1,
- dragDistanceCorrection: false,
- dragLockToAxis: !this._dragLockDisabled,
- passive: !this._shouldFixScroll
- });
-
- gdToggle('on');
- scrollToggle('add');
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this._currentTranslation = 0;
- this._pageElement = this.parentNode;
-
- this._setupListeners(true);
- this._setStyle();
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._hide();
- this._setupListeners(false);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'height' && this._pageElement) {
- this._setStyle();
- }
- }
- }, {
- key: 'onAction',
- get: function get$$1() {
- return this._onAction;
- },
- set: function set$$1(value) {
- if (value && !(value instanceof Function)) {
- throwType('onAction', 'function or null');
- }
- this._onAction = value;
- }
-
- /**
- * @property onPull
- * @type {Function}
- * @description
- * [en]Hook called whenever the user pulls the element. It gets the pulled distance ratio (scroll / height) and an animationOptions object as arguments.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onPull',
- get: function get$$1() {
- return this._onPull;
- },
- set: function set$$1(value) {
- if (value && !(value instanceof Function)) {
- throwType('onPull', 'function or null');
- }
- this._onPull = value;
- }
- }, {
- key: 'height',
- set: function set$$1(value) {
- if (!util$1.isInteger(value)) {
- throwType('height', 'integer');
- }
-
- this.setAttribute('height', value + 'px');
- },
- get: function get$$1() {
- return parseInt(this.getAttribute('height') || '64', 10);
- }
-
- /**
- * @property thresholdHeight
- * @type {Number}
- * @description
- * [en]The thresholdHeight of the pull hook in pixels. The default value is `96px`.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'thresholdHeight',
- set: function set$$1(value) {
- if (!util$1.isInteger(value)) {
- throwType('thresholdHeight', 'integer');
- }
-
- this.setAttribute('threshold-height', value + 'px');
- },
- get: function get$$1() {
- return parseInt(this.getAttribute('threshold-height') || '96', 10);
- }
- }, {
- key: 'state',
- get: function get$$1() {
- return this.getAttribute('state');
- }
-
- /**
- * @property pullDistance
- * @readonly
- * @type {Number}
- * @description
- * [en]The current number of pixels the pull hook has moved.[/en]
- * [ja]現在のプルフックが引き出された距離をピクセル数。[/ja]
- */
-
- }, {
- key: 'pullDistance',
- get: function get$$1() {
- return this._currentTranslation;
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['height'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['changestate'];
- }
- }]);
- return PullHookElement;
- }(BaseElement);
-
- onsElements.PullHook = PullHookElement;
- customElements.define('ons-pull-hook', PullHookElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var scheme$22 = {
- '': 'range--*',
- '.range__input': 'range--*__input',
- '.range__focus-ring': 'range--*__focus-ring'
- };
-
- var activeClassToken = 'range__input--active';
-
- /**
- * @element ons-range
- * @category form
- * @modifier material
- * [en]Material Design slider[/en]
- * [ja][/ja]
- * @description
- * [en]
- * Range input component. Used to display a draggable slider.
- *
- * Works very similar to the `<input type="range">` element.
- * [/en]
- * [ja][/ja]
- * @codepen xZQomM
- * @tutorial vanilla/Reference/range
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @seealso ons-input
- * [en]The `<ons-input>` component is used to display text inputs, radio buttons and checkboxes.[/en]
- * [ja][/ja]
- * @example
- * <ons-range value="20"></ons-range>
- * <ons-range modifier="material" value="10"></range>
- */
-
- var RangeElement = function (_BaseInputElement) {
- inherits(RangeElement, _BaseInputElement);
-
- function RangeElement() {
- classCallCheck(this, RangeElement);
-
- var _this = possibleConstructorReturn(this, (RangeElement.__proto__ || Object.getPrototypeOf(RangeElement)).call(this));
-
- _this._onMouseDown = _this._onMouseDown.bind(_this);
- _this._onMouseUp = _this._onMouseUp.bind(_this);
- _this._onTouchStart = _this._onTouchStart.bind(_this);
- _this._onTouchEnd = _this._onTouchEnd.bind(_this);
- _this._onInput = _this._update.bind(_this);
- _this._onDragstart = _this._onDragstart.bind(_this);
- _this._onDragend = _this._onDragend.bind(_this);
- return _this;
- }
-
- createClass(RangeElement, [{
- key: '_compile',
- value: function _compile() {
- get(RangeElement.prototype.__proto__ || Object.getPrototypeOf(RangeElement.prototype), '_compile', this).call(this);
- this._updateDisabled(this.hasAttribute('disabled'));
- }
-
- /* Inherited props */
-
- }, {
- key: '_update',
- value: function _update() {
- var input = this._input;
- var focusRing = this._focusRing;
-
- input.style.backgroundSize = 100 * this._ratio + '% 2px';
- focusRing.value = this.value;
-
- // NOTE: "_zero" attribute is used for CSS styling.
- if (input.min === '' && input.value === '0' || input.min === input.value) {
- input.setAttribute('_zero', '');
- } else {
- input.removeAttribute('_zero');
- }
-
- ['min', 'max'].forEach(function (attr) {
- return focusRing[attr] = input[attr];
- });
- }
- }, {
- key: '_onMouseDown',
-
-
- /* Own props */
-
- value: function _onMouseDown(e) {
- var _this2 = this;
-
- this._input.classList.add(activeClassToken);
- setImmediate(function () {
- return _this2._input.focus();
- });
- }
- }, {
- key: '_onTouchStart',
- value: function _onTouchStart(e) {
- this._onMouseDown();
- }
- }, {
- key: '_onMouseUp',
- value: function _onMouseUp(e) {
- this._input.classList.remove(activeClassToken);
- }
- }, {
- key: '_onTouchEnd',
- value: function _onTouchEnd(e) {
- this._onMouseUp(e);
- }
- }, {
- key: '_onDragstart',
- value: function _onDragstart(e) {
- e.consumed = true;
- e.gesture.stopPropagation();
- this._input.classList.add(activeClassToken);
- this.addEventListener('drag', this._onDrag);
- }
- }, {
- key: '_onDrag',
- value: function _onDrag(e) {
- e.stopPropagation();
- }
- }, {
- key: '_onDragend',
- value: function _onDragend(e) {
- this._input.classList.remove(activeClassToken);
- this.removeEventListener('drag', this._onDrag);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'disabled') {
- this._updateDisabled(current);
- }
- get(RangeElement.prototype.__proto__ || Object.getPrototypeOf(RangeElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
-
- /**
- * @param {boolean} disabled
- */
-
- }, {
- key: '_updateDisabled',
- value: function _updateDisabled(disabled) {
- if (disabled) {
- this.classList.add('range--disabled');
- } else {
- this.classList.remove('range--disabled');
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this._setupListeners(true);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._setupListeners(false);
- }
- }, {
- key: '_setupListeners',
- value: function _setupListeners(add) {
- var action = (add ? 'add' : 'remove') + 'EventListener';
- util$1[action](this, 'touchstart', this._onTouchStart, { passive: true });
- this[action]('mousedown', this._onMouseDown);
- this[action]('mouseup', this._onMouseUp);
- this[action]('touchend', this._onTouchEnd);
- this[action]('dragstart', this._onDragstart);
- this[action]('dragend', this._onDragend);
- this[action]('input', this._onInput);
- }
-
- /**
- * @attribute disabled
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- /**
- * @property value
- * @type {Number}
- * @description
- * [en]Current value.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$22;
- }
- }, {
- key: '_template',
- get: function get$$1() {
- return '\n <input type="' + this.type + '" class="' + this._defaultClassName + '__input">\n <input type="range" class="range__focus-ring" tabIndex="-1">\n ';
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'range';
- }
- }, {
- key: 'type',
- get: function get$$1() {
- return 'range';
- }
- }, {
- key: '_focusRing',
- get: function get$$1() {
- return this.children[1];
- }
- }, {
- key: '_ratio',
- get: function get$$1() {
- // Returns the current ratio.
- var min = this._input.min === '' ? 0 : parseInt(this._input.min);
- var max = this._input.max === '' ? 100 : parseInt(this._input.max);
-
- return (this.value - min) / (max - min);
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['disabled'].concat(toConsumableArray(BaseInputElement.observedAttributes));
- }
- }]);
- return RangeElement;
- }(BaseInputElement);
-
- onsElements.Range = RangeElement;
- customElements.define('ons-range', RangeElement);
-
- /*
- Copyright 2013-2016 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @class AnimatorCSS - implementation of Animator class using css transitions
- */
-
- var AnimatorCSS = function () {
- createClass(AnimatorCSS, [{
- key: 'animate',
-
-
- /**
- * @method animate
- * @desc main animation function
- * @param {Element} element
- * @param {Object} finalCSS
- * @param {number} [duration=200] - duration in milliseconds
- * @return {Object} result
- * @return {Function} result.then(callback) - sets a callback to be executed after the animation has stopped
- * @return {Function} result.stop(options) - stops the animation; if options.stopNext is true then it doesn't call the callback
- * @return {Function} result.finish(ms) - finishes the animation in the specified time in milliseconds
- * @return {Function} result.speed(ms) - sets the animation speed so that it finishes as if the original duration was the one specified here
- * @example
- * ````
- * var result = animator.animate(el, {opacity: 0.5}, 1000);
- *
- * el.addEventListener('click', function(e){
- * result.speed(200).then(function(){
- * console.log('done');
- * });
- * }, 300);
- * ````
- */
- value: function animate(el, final) {
- var duration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 200;
-
- var start = new Date().getTime(),
- initial = {},
- stopped = false,
- next = false,
- timeout = false,
- properties = Object.keys(final);
-
- var updateStyles = function updateStyles() {
- var s = window.getComputedStyle(el);
- properties.forEach(s.getPropertyValue.bind(s));
- s = el.offsetHeight;
- };
-
- var result = {
- stop: function stop() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- timeout && clearTimeout(timeout);
- var k = Math.min(1, (new Date().getTime() - start) / duration);
- properties.forEach(function (i) {
- el.style[i] = (1 - k) * initial[i] + k * final[i] + (i == 'opacity' ? '' : 'px');
- });
- el.style.transitionDuration = '0s';
-
- if (options.stopNext) {
- next = false;
- } else if (!stopped) {
- stopped = true;
- next && next();
- }
- return result;
- },
- then: function then(cb) {
- next = cb;
- if (stopped) {
- next && next();
- }
- return result;
- },
- speed: function speed(newDuration) {
- if (internal$1.config.animationsDisabled) {
- newDuration = 0;
- }
- if (!stopped) {
- timeout && clearTimeout(timeout);
-
- var passed = new Date().getTime() - start;
- var k = passed / duration;
- var remaining = newDuration * (1 - k);
-
- properties.forEach(function (i) {
- el.style[i] = (1 - k) * initial[i] + k * final[i] + (i == 'opacity' ? '' : 'px');
- });
-
- updateStyles();
-
- start = el.speedUpTime;
- duration = remaining;
-
- el.style.transitionDuration = duration / 1000 + 's';
-
- properties.forEach(function (i) {
- el.style[i] = final[i] + (i == 'opacity' ? '' : 'px');
- });
-
- timeout = setTimeout(result.stop, remaining);
- }
- return result;
- },
- finish: function finish() {
- var milliseconds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 50;
-
- var k = (new Date().getTime() - start) / duration;
-
- result.speed(milliseconds / (1 - k));
- return result;
- }
- };
-
- if (el.hasAttribute('disabled') || stopped || internal$1.config.animationsDisabled) {
- return result;
- }
-
- var style = window.getComputedStyle(el);
- properties.forEach(function (e) {
- var v = parseFloat(style.getPropertyValue(e));
- initial[e] = isNaN(v) ? 0 : v;
- });
-
- if (!stopped) {
- el.style.transitionProperty = properties.join(',');
- el.style.transitionDuration = duration / 1000 + 's';
-
- properties.forEach(function (e) {
- el.style[e] = final[e] + (e == 'opacity' ? '' : 'px');
- });
- }
-
- timeout = setTimeout(result.stop, duration);
- this._onStopAnimations(el, result.stop);
-
- return result;
- }
- }]);
-
- function AnimatorCSS() {
- classCallCheck(this, AnimatorCSS);
-
- this._queue = [];
- this._index = 0;
- }
-
- createClass(AnimatorCSS, [{
- key: '_onStopAnimations',
- value: function _onStopAnimations(el, listener) {
- var queue = this._queue;
- var i = this._index++;
- queue[el] = queue[el] || [];
- queue[el][i] = function (options) {
- delete queue[el][i];
- if (queue[el] && queue[el].length == 0) {
- delete queue[el];
- }
- return listener(options);
- };
- }
-
- /**
- * @method stopAnimations
- * @desc stops active animations on a specified element
- * @param {Element|Array} element - element or array of elements
- * @param {Object} [options={}]
- * @param {Boolean} [options.stopNext] - the callbacks after the animations won't be called if this option is true
- */
-
- }, {
- key: 'stopAnimations',
- value: function stopAnimations(el) {
- var _this = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (Array.isArray(el)) {
- return el.forEach(function (el) {
- _this.stopAnimations(el, options);
- });
- }
-
- (this._queue[el] || []).forEach(function (e) {
- e(options || {});
- });
- }
-
- /**
- * @method stopAll
- * @desc stops all active animations
- * @param {Object} [options={}]
- * @param {Boolean} [options.stopNext] - the callbacks after the animations won't be called if this option is true
- */
-
- }, {
- key: 'stopAll',
- value: function stopAll() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- this.stopAnimations(Object.keys(this._queue), options);
- }
-
- /**
- * @method fade
- * @desc fades the element (short version for animate(el, {opacity: 0}))
- * @param {Element} element
- * @param {number} [duration=200]
- */
-
- }, {
- key: 'fade',
- value: function fade(el) {
- var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
-
- return this.animate(el, { opacity: 0 }, duration);
- }
- }]);
- return AnimatorCSS;
- }();
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$11 = 'ripple';
- var scheme$23 = {
- '': 'ripple--*',
- '.ripple__wave': 'ripple--*__wave',
- '.ripple__background': 'ripple--*__background'
- };
-
- /**
- * @element ons-ripple
- * @category visual
- * @description
- * [en]
- * Adds a Material Design "ripple" effect to an element. The ripple effect will spread from the position where the user taps.
- *
- * Some elements such as `<ons-button>` and `<ons-fab>` support a `ripple` attribute.
- * [/en]
- * [ja]マテリアルデザインのリップル効果をDOM要素に追加します。[/ja]
- * @codepen wKQWdZ
- * @tutorial vanilla/Reference/ripple
- * @modifier light-gray
- * [en]Change the color of effects to light gray.[/en]
- * [ja]エフェクトの色が明るい灰色になります。[/ja]
- * @guide theming.html#cross-platform-styling-autostyling
- * [en]Cross platform styling[/en]
- * [ja]Cross platform styling[/ja]
- * @example
- * <div class="my-div">
- * <ons-ripple></ons-ripple>
- * </div>
- *
- * @example
- * <ons-button ripple>Click me!</ons-button>
- */
-
- var RippleElement = function (_BaseElement) {
- inherits(RippleElement, _BaseElement);
-
- /**
- * @attribute color
- * @type {String}
- * @description
- * [en]Color of the ripple effect.[/en]
- * [ja]リップルエフェクトの色を指定します。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the ripple effect.[/en]
- * [ja]エフェクトの表現を指定します。[/ja]
- */
-
- /**
- * @attribute background
- * @type {String}
- * @description
- * [en]Color of the background.[/en]
- * [ja]背景の色を設定します。[/ja]
- */
-
- /**
- * @attribute size
- * @type {String}
- * @description
- * [en]Sizing of the wave on ripple effect. Set "cover" or "contain". Default is "cover".[/en]
- * [ja]エフェクトのサイズを指定します。"cover"もしくは"contain"を指定します。デフォルトは"cover"です。[/ja]
- */
-
- /**
- * @attribute center
- * @type {Boolean}
- * @description
- * [en]If this attribute presents, change the position of wave effect to center of the target element.[/en]
- * [ja]この要素を設定すると、エフェクトの位置が要素の真ん中から始まります。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]If this attribute is set, the ripple effect will be disabled.[/en]
- * [ja]この属性が設定された場合、リップルエフェクトは無効になります。[/ja]
- */
-
- function RippleElement() {
- classCallCheck(this, RippleElement);
-
- var _this = possibleConstructorReturn(this, (RippleElement.__proto__ || Object.getPrototypeOf(RippleElement)).call(this));
-
- _this._onTap = _this._onTap.bind(_this);
- _this._onHold = _this._onHold.bind(_this);
- _this._onDragStart = _this._onDragStart.bind(_this);
- _this._onRelease = _this._onRelease.bind(_this);
-
- contentReady(_this, function () {
- return _this._compile();
- });
-
- _this._animator = new AnimatorCSS();
-
- ['color', 'center', 'start-radius', 'background', 'modifier'].forEach(function (e) {
- _this.attributeChangedCallback(e, null, _this.getAttribute(e));
- });
- return _this;
- }
-
- createClass(RippleElement, [{
- key: '_compile',
- value: function _compile() {
- this.classList.add(defaultClassName$11);
-
- this._wave = this.getElementsByClassName('ripple__wave')[0];
- this._background = this.getElementsByClassName('ripple__background')[0];
-
- if (!(this._background && this._wave)) {
- this._wave = util$1.create('.ripple__wave');
- this._background = util$1.create('.ripple__background');
-
- this.appendChild(this._wave);
- this.appendChild(this._background);
- }
-
- ModifierUtil.initModifier(this, scheme$23);
- }
- }, {
- key: '_getEffectSize',
- value: function _getEffectSize() {
- var sizes = ['cover', 'contain'];
- if (this.hasAttribute('size')) {
- var size = this.getAttribute('size');
- if (sizes.indexOf(size) !== -1) {
- return size;
- }
- }
-
- return 'cover';
- }
- }, {
- key: '_calculateCoords',
- value: function _calculateCoords(e) {
- var x = void 0,
- y = void 0,
- h = void 0,
- w = void 0,
- r = void 0;
- var b = this.getBoundingClientRect();
- var size = this._getEffectSize();
- var error = function error() {
- return util$1.throw('Ripple invalid state');
- };
-
- if (this._center) {
- x = b.width / 2;
- y = b.height / 2;
-
- if (size === 'cover') {
- r = Math.sqrt(x * x + y * y);
- } else if (size === 'contain') {
- r = Math.min(x, y);
- } else {
- error();
- }
- } else {
- x = (typeof e.clientX === 'number' ? e.clientX : e.changedTouches[0].clientX) - b.left;
- y = (typeof e.clientY === 'number' ? e.clientY : e.changedTouches[0].clientY) - b.top;
- h = Math.max(y, b.height - y);
- w = Math.max(x, b.width - x);
-
- if (size === 'cover') {
- r = Math.sqrt(h * h + w * w);
- } else if (size === 'contain') {
- r = Math.min(Math.round(h / 2), Math.round(w / 2));
- } else {
- error();
- }
- }
-
- return { x: x, y: y, r: r };
- }
- }, {
- key: '_rippleAnimation',
- value: function _rippleAnimation(e) {
- var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
- var _animator = this._animator,
- _wave = this._wave,
- _background = this._background,
- _minR = this._minR;
-
- var _calculateCoords2 = this._calculateCoords(e),
- x = _calculateCoords2.x,
- y = _calculateCoords2.y,
- r = _calculateCoords2.r;
-
- _animator.stopAll({ stopNext: 1 });
- _animator.animate(_background, { opacity: 1 }, duration);
-
- util$1.extend(_wave.style, {
- opacity: 1,
- top: y - _minR + 'px',
- left: x - _minR + 'px',
- width: 2 * _minR + 'px',
- height: 2 * _minR + 'px'
- });
-
- return _animator.animate(_wave, {
- top: y - r,
- left: x - r,
- height: 2 * r,
- width: 2 * r
- }, duration);
- }
- }, {
- key: '_updateParent',
- value: function _updateParent() {
- if (!this._parentUpdated && this.parentNode) {
- var computedStyle = window.getComputedStyle(this.parentNode);
- if (computedStyle.getPropertyValue('position') === 'static') {
- this.parentNode.style.position = 'relative';
- }
- this._parentUpdated = true;
- }
- }
- }, {
- key: '_onTap',
- value: function _onTap(e) {
- var _this2 = this;
-
- if (!this.disabled && !e.ripple) {
- e.ripple = true;
- this._updateParent();
- this._rippleAnimation(e.gesture.srcEvent).then(function () {
- _this2._animator.fade(_this2._wave);
- _this2._animator.fade(_this2._background);
- });
- }
- }
- }, {
- key: '_onHold',
- value: function _onHold(e) {
- if (!this.disabled && !e.ripple) {
- e.ripple = true;
- this._updateParent();
- this._holding = this._rippleAnimation(e.gesture.srcEvent, 2000);
- document.addEventListener('release', this._onRelease);
- }
- }
- }, {
- key: '_onRelease',
- value: function _onRelease(e) {
- var _this3 = this;
-
- if (this._holding && !e.ripple) {
- e.ripple = true;
- this._holding.speed(300).then(function () {
- _this3._animator.stopAll({ stopNext: true });
- _this3._animator.fade(_this3._wave);
- _this3._animator.fade(_this3._background);
- });
-
- this._holding = false;
- }
-
- document.removeEventListener('release', this._onRelease);
- }
- }, {
- key: '_onDragStart',
- value: function _onDragStart(e) {
- if (this._holding) {
- return this._onRelease(e);
- }
- if (['left', 'right'].indexOf(e.gesture.direction) != -1) {
- this._onTap(e);
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this._parentNode = this.parentNode;
-
- if (internal$1.config.animationsDisabled) {
- this.disabled = true;
- } else {
- this._parentNode.addEventListener('tap', this._onTap);
- this._parentNode.addEventListener('hold', this._onHold);
- this._parentNode.addEventListener('dragstart', this._onDragStart);
- }
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- var pn = this._parentNode || this.parentNode;
- pn.removeEventListener('tap', this._onTap);
- pn.removeEventListener('hold', this._onHold);
- pn.removeEventListener('dragstart', this._onDragStart);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this4 = this;
-
- switch (name) {
-
- case 'class':
- util$1.restoreClass(this, defaultClassName$11, scheme$23);
- break;
-
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$23);
- break;
-
- case 'start-radius':
- this._minR = Math.max(0, parseFloat(current) || 0);
- break;
-
- case 'color':
- if (current) {
- contentReady(this, function () {
- _this4._wave.style.background = current;
- if (!_this4.hasAttribute('background')) {
- _this4._background.style.background = current;
- }
- });
- }
- break;
-
- case 'background':
- if (current || last) {
- if (current === 'none') {
- contentReady(this, function () {
- _this4._background.setAttribute('disabled', 'disabled');
- _this4._background.style.background = 'transparent';
- });
- } else {
- contentReady(this, function () {
- if (_this4._background.hasAttribute('disabled')) {
- _this4._background.removeAttribute('disabled');
- }
- _this4._background.style.background = current;
- });
- }
- }
- break;
-
- case 'center':
- if (name === 'center') {
- this._center = current != null && current != 'false';
- }
- break;
-
- }
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['start-radius', 'color', 'background', 'center', 'class', 'modifier'];
- }
- }]);
- return RippleElement;
- }(BaseElement);
-
- onsElements.Ripple = RippleElement;
- customElements.define('ons-ripple', RippleElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-row
- * @category grid
- * @description
- * [en]Represents a row in the grid system. Use with `<ons-col>` to layout components.[/en]
- * [ja]グリッドシステムにて行を定義します。ons-colとともに使用し、コンポーネントの配置に使用します。[/ja]
- * @codepen GgujC {wide}
- * @guide theming.html
- * [en]Layouting guide[/en]
- * [ja]レイアウト調整[/ja]
- * @seealso ons-col
- * [en]The `<ons-col>` component is used as children of `<ons-row>`.[/en]
- * [ja]ons-colコンポーネント[/ja]
- * @note
- * [en]For Android 4.3 and earlier, and iOS6 and earlier, when using mixed alignment with ons-row and ons-col, they may not be displayed correctly. You can use only one vertical-align.[/en]
- * [ja]Android 4.3以前、もしくはiOS 6以前のOSの場合、ons-rowとons-colを組み合わせてそれぞれのons-col要素のvertical-align属性の値に別々の値を指定すると、描画が崩れる場合があります。vertical-align属性の値には一つの値だけを指定できます。[/ja]
- * @example
- * <ons-row>
- * <ons-col width="50px"><ons-icon icon="fa-twitter"></ons-icon></ons-col>
- * <ons-col>Text</ons-col>
- * </ons-row>
- */
-
- /**
- * @attribute vertical-align
- * @type {String}
- * @description
- * [en]Short hand attribute for aligning vertically. Valid values are top, bottom, and center.[/en]
- * [ja]縦に整列するために指定します。top、bottom、centerのいずれかを指定できます。[/ja]
- */
-
- var RowElement = function (_BaseElement) {
- inherits(RowElement, _BaseElement);
-
- function RowElement() {
- classCallCheck(this, RowElement);
- return possibleConstructorReturn(this, (RowElement.__proto__ || Object.getPrototypeOf(RowElement)).apply(this, arguments));
- }
-
- return RowElement;
- }(BaseElement);
-
- onsElements.Row = RowElement;
- customElements.define('ons-row', RowElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$12 = 'segment';
- var scheme$24 = {
- '': 'segment--*',
- '.segment__item': 'segment--*__item',
- '.segment__input': 'segment--*__input',
- '.segment__button': 'segment--*__button'
- };
-
- var generateId$1 = function () {
- var i = 0;
- return function () {
- return 'ons-segment-gen-' + i++;
- };
- }();
-
- /**
- * @element ons-segment
- * @category control
- * @modifier material
- * [en]Material Design segment[/en]
- * [ja][/ja]
- * @description
- * [en]
- * Segment component. Use this component to have a button bar with automatic styles that switch on click of another button.
- *
- * Will automatically display as a Material Design segment on Android.
- * [/en]
- * [ja][/ja]
- * @codepen hLayx
- * @tutorial vanilla/Reference/segment
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
- * @example
- * <ons-segment>
- * <ons-button>Label 1</ons-button>
- * <ons-button>Label 2</ons-button>
- * <ons-button>Label 3</ons-button>
- * </ons-segment>
- */
-
- var SegmentElement = function (_BaseElement) {
- inherits(SegmentElement, _BaseElement);
-
- /**
- * @event postchange
- * @description
- * [en]Fires after the active button is changed.[/en]
- * [ja][/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja][/ja]
- * @param {Number} event.index
- * [en]Tapped button index.[/en]
- * [ja][/ja]
- * @param {Object} event.segmentItem
- * [en]Segment item object.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the segment.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute tabbar-id
- * @initonly
- * @type {String}
- * @description
- * [en]ID of the tabbar element to "connect" to the segment. Must be inside the same page.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute active-index
- * @initonly
- * @default 0
- * @type {Number}
- * @description
- * [en]Index of the first active button, only works if there is no connected tabbar (in which case the active tab sets the active button).[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Specify if segment should be disabled.[/en]
- * [ja]ボタンを無効化する場合は指定します。[/ja]
- */
-
- function SegmentElement() {
- classCallCheck(this, SegmentElement);
-
- var _this = possibleConstructorReturn(this, (SegmentElement.__proto__ || Object.getPrototypeOf(SegmentElement)).call(this));
-
- _this._segmentId = generateId$1();
- _this._tabbar = null;
- _this._onChange = _this._onChange.bind(_this);
- _this._onTabbarPreChange = _this._onTabbarPreChange.bind(_this);
-
- contentReady(_this, function () {
- _this._compile();
- setImmediate(function () {
- return _this._lastActiveIndex = _this._tabbar ? _this._tabbar.getActiveTabIndex() : _this.getActiveButtonIndex();
- });
- });
- return _this;
- }
-
- createClass(SegmentElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$12);
-
- for (var index = this.children.length - 1; index >= 0; index--) {
- var item = this.children[index];
- item.classList.add('segment__item');
-
- var input = util$1.findChild(item, '.segment__input') || util$1.create('input.segment__input');
- input.type = 'radio';
- input.value = index;
- input.name = input.name || this._segmentId;
- input.checked = !this.hasAttribute('tabbar-id') && index === (parseInt(this.getAttribute('active-index')) || 0);
-
- var button = util$1.findChild(item, '.segment__button') || util$1.create('.segment__button');
- if (button.parentElement !== item) {
- while (item.firstChild) {
- button.appendChild(item.firstChild);
- }
- }
-
- item.appendChild(input);
- item.appendChild(button);
- }
-
- ModifierUtil.initModifier(this, scheme$24);
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- contentReady(this, function () {
- if (_this2.hasAttribute('tabbar-id')) {
- var page = util$1.findParent(_this2, 'ons-page');
- _this2._tabbar = page && page.querySelector('#' + _this2.getAttribute('tabbar-id'));
- if (!_this2._tabbar || _this2._tabbar.tagName !== 'ONS-TABBAR') {
- util$1.throw('No tabbar with id ' + _this2.getAttribute('tabbar-id') + ' was found.');
- }
-
- _this2._tabbar.setAttribute('hide-tabs', '');
- setImmediate(function () {
- return _this2._setChecked(_this2._tabbar.getActiveTabIndex());
- });
-
- _this2._tabbar.addEventListener('prechange', _this2._onTabbarPreChange);
- }
- });
-
- this.addEventListener('change', this._onChange);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- var _this3 = this;
-
- contentReady(this, function () {
- if (_this3._tabbar) {
- _this3._tabbar.removeEventListener('prechange', _this3._onTabbarPreChange);
- _this3._tabbar = null;
- }
- });
- this.removeEventListener('change', this._onChange);
- }
- }, {
- key: '_setChecked',
- value: function _setChecked(index) {
- this.children[index].firstElementChild.checked = true;
- }
-
- /**
- * @method setActiveButton
- * @signature setActiveButton(index, [options])
- * @param {Number} index
- * [en]Button index.[/en]
- * [ja][/ja]
- * @param {Object} [options]
- * [en]Parameter object, works only if there is a connected tabbar. Supports the same options as `ons-tabbar`'s `setActiveTab` method.[/en]
- * [ja][/ja]
- * @description
- * [en]Make button with the specified index active. If there is a connected tabbar it shows the corresponding tab page. In this case animations and their options can be specified by the second parameter.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the selected index or to the new page element if there is a connected tabbar.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'setActiveButton',
- value: function setActiveButton(index, options) {
- if (this._tabbar) {
- return this._tabbar.setActiveTab(index, options);
- }
-
- this._setChecked(index);
- this._postChange(index);
- return Promise.resolve(index);
- }
-
- /**
- * @method getActiveButtonIndex
- * @signature getActiveButtonIndex()
- * @return {Number}
- * [en]The index of the currently active button.[/en]
- * [ja][/ja]
- * @description
- * [en]Returns button index of current active button. If active button is not found, returns -1.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'getActiveButtonIndex',
- value: function getActiveButtonIndex() {
- for (var i = this.children.length - 1; i >= 0; i--) {
- // Array.findIndex
- if (this.children[i].firstElementChild.checked) {
- return i;
- }
- }
- return -1;
- }
- }, {
- key: '_onChange',
- value: function _onChange(event) {
- event.stopPropagation();
- this._tabbar ? this._tabbar.setActiveTab(this.getActiveButtonIndex(), { reject: false }) : this._postChange(this.getActiveButtonIndex());
- }
- }, {
- key: '_onTabbarPreChange',
- value: function _onTabbarPreChange(event) {
- var _this4 = this;
-
- setImmediate(function () {
- if (!event.detail.canceled) {
- _this4._setChecked(event.index);
- _this4._postChange(event.index);
- }
- });
- }
- }, {
- key: '_postChange',
- value: function _postChange(index) {
- util$1.triggerElementEvent(this, 'postchange', {
- index: index,
- activeIndex: index,
- lastActiveIndex: this._lastActiveIndex,
- segmentItem: this.children[index]
- });
- this._lastActiveIndex = index;
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the segment is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$12, scheme$24);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$24);
- break;
- }
- }
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['class', 'modifier'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['postchange'];
- }
- }]);
- return SegmentElement;
- }(BaseElement);
-
- onsElements.Segment = SegmentElement;
- customElements.define('ons-segment', SegmentElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$25 = {
- '': 'select-* select--*',
- '.select-input': 'select-input--*'
- };
-
- var defaultClassName$13 = 'select';
-
- var INPUT_ATTRIBUTES$1 = ['autofocus', 'disabled', 'form', 'multiple', 'name', 'required', 'size'];
-
- /**
- * @element ons-select
- * @category form
- * @modifier material
- * [en]Displays a Material Design select input.[/en]
- * [ja][/ja]
- * @modifier underbar
- * [en]Displays a horizontal line underneath a select input.[/en]
- * [ja][/ja]
- * @description
- * [en]
- * Select component. If you want to place a select with an ID of `my-id` on a page, use `<ons-select select-id="my-id">`.
- *
- * The component will automatically display as a Material Design select on Android.
- *
- * Most attributes that can be used for a normal `<select>` element can also be used on the `<ons-select>` element.
- * [/en]
- * [ja]セレクトボックスを表示するコンポーネントです。`select` 要素に使用できる属性の多くが `ons-select` 要素でも利用できます。[/ja]
- * @codepen hLayx
- * @tutorial vanilla/Reference/select
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
- * @example
- * <ons-select>
- * <option value="1">1</option>
- * <option value="2">2nd</option>
- * <option value="3">3rd option</option>
- * </ons-select>
- */
-
- var SelectElement = function (_BaseElement) {
- inherits(SelectElement, _BaseElement);
-
- /**
- * @attribute autofocus
- * @type {Boolean}
- * @default false
- * @description
- * [en]Element automatically gains focus on page load.[/en]
- * [ja]ページロード時にこのセレクトボックスにフォーカスが移るようにします。[/ja]
- */
-
- /**
- * @attribute disabled
- * @type {Boolean}
- * @default false
- * @description
- * [en]Specify if select input should be disabled.[/en]
- * [ja]このセレクトボックスを無効化する場合に指定します。[/ja]
- */
-
- /**
- * @attribute form
- * @type {String}
- * @description
- * [en]Associate a select element to an existing form on the page, even if not nested.[/en]
- * [ja]このセレクトボックスを、指定した `form` 要素に紐付けます。セレクトボックスを `form` 要素の外側に配置する際に使用します。[/ja]
- */
-
- /**
- * @attribute multiple
- * @type {Boolean}
- * @default false
- * @description
- * [en]If this attribute is defined, multiple options can be selected at once.[/en]
- * [ja]選択肢の複数選択を有効にします。[/ja]
- */
-
- /**
- * @attribute name
- * @type {String}
- * @description
- * [en]Name the select element, useful for instance if it is part of a form.[/en]
- * [ja]このセレクトボックスの名前を指定します。通常 `form` 要素と共に使用します。[/ja]
- */
-
- /**
- * @attribute required
- * @type {Boolean}
- * @description
- * [en]Make the select input required for submitting the form it is part of.[/en]
- * [ja]このセレクトボックスを入力必須にする場合に指定します。通常 `form` 要素と共に使用します。[/ja]
- */
-
- /**
- * @attribute select-id
- * @type {String}
- * @description
- * [en]ID given to the inner select, useful for dynamic manipulation.[/en]
- * [ja]このセレクトボックスが内部に持つ select 要素に与える ID を指定します。セレクトボックスの内容を動的に変更する必要がある場合に使用します。[/ja]
- */
-
- /**
- * @attribute size
- * @type {Number}
- * @default 1
- * @description
- * [en]How many options are displayed; if there are more than the size then a scroll appears to navigate them.[/en]
- * [ja]一度に表示する選択肢の個数を指定します。選択肢がこの属性で指定した個数よりも多い場合、スクロールが有効になります。[/ja]
- */
-
- function SelectElement() {
- classCallCheck(this, SelectElement);
-
- var _this = possibleConstructorReturn(this, (SelectElement.__proto__ || Object.getPrototypeOf(SelectElement)).call(this));
-
- contentReady(_this, function () {
- return _this._compile();
- });
-
- _this._deriveGetters();
- return _this;
- }
-
- createClass(SelectElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this2 = this;
-
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$13, scheme$25);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$25);
- break;
- }
-
- if (INPUT_ATTRIBUTES$1.indexOf(name) >= 0) {
- contentReady(this, function () {
- return _this2._updateBoundAttributes();
- });
- }
- }
- }, {
- key: '_updateBoundAttributes',
- value: function _updateBoundAttributes() {
- var _this3 = this;
-
- INPUT_ATTRIBUTES$1.forEach(function (attr) {
- if (_this3.hasAttribute(attr)) {
- _this3._select.setAttribute(attr, _this3.getAttribute(attr));
- } else {
- _this3._select.removeAttribute(attr);
- }
- });
- }
-
- /**
- * @property length
- * @description
- * [en]Number of options in the select box.[/en]
- * [ja]このセレクトボックスに含まれる選択肢の個数を返します。 `select` 要素[/ja]
- */
-
- /**
- * @property options
- * @description
- * [en]Several options for handling the select DOM object.[/en]
- * [ja]このセレクトボックスに含まれる `option` 要素の配列を返します。[/ja]
- */
-
- /**
- * @property selectedIndex
- * @description
- * [en]Index of the currently selected option.[/en]
- * [ja]現在選択されている選択肢のインデックスを返します。[/ja]
- */
-
- /**
- * @property value
- * @description
- * [en]Value of the currently selected option.[/en]
- * [ja]現在選択されている選択肢の値を返します。[/ja]
- */
-
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.classList.add(defaultClassName$13);
- var sel = this._select || document.createElement('select');
- if (!sel.id && this.hasAttribute('select-id')) {
- sel.id = this.getAttribute('select-id');
- }
- sel.classList.add('select-input');
- if (!this._select) {
- util$1.arrayFrom(this.childNodes).forEach(function (element) {
- return sel.appendChild(element);
- });
- this.appendChild(sel);
- }
-
- ModifierUtil.initModifier(this, scheme$25);
- }
- }, {
- key: '_deriveGetters',
- value: function _deriveGetters() {
- var _this4 = this;
-
- ['disabled', 'length', 'multiple', 'name', 'options', 'selectedIndex', 'size', 'value', 'form', 'type'].forEach(function (key) {
- Object.defineProperty(_this4, key, {
- configurable: true,
- enumerable: true,
- get: function get$$1() {
- return _this4._select[key];
- },
- set: ['form', 'type'].indexOf(key) === -1 ? function (value) {
- return contentReady(_this4, function () {
- return _this4._select[key] = value;
- });
- } : undefined
- });
- });
- }
- }, {
- key: 'add',
- value: function add(option) {
- var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
-
- this._select.add(option, index);
- }
- }, {
- key: 'remove',
- value: function remove(index) {
- this._select.remove(index);
- }
- }, {
- key: '_select',
- get: function get$$1() {
- return this.querySelector('select');
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'class'].concat(INPUT_ATTRIBUTES$1);
- }
- }]);
- return SelectElement;
- }(BaseElement);
-
- onsElements.Select = SelectElement;
- customElements.define('ons-select', SelectElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var defaultClassName$14 = 'fab fab--mini speed-dial__item';
-
- var scheme$26 = {
- '': 'fab--* speed-dial__item--*'
- };
-
- /**
- * @element ons-speed-dial-item
- * @category control
- * @description
- * [en]
- * This component displays the child elements of the Material Design Speed dial component.
- * [/en]
- * [ja]
- * Material DesignのSpeed dialの子要素を表現する要素です。
- * [/ja]
- * @codepen dYQYLg
- * @tutorial vanilla/Reference/speed-dial
- * @seealso ons-speed-dial
- * [en]The `<ons-speed-dial>` component.[/en]
- * [ja]ons-speed-dialコンポーネント[/ja]
- * @seealso ons-fab
- * [en]ons-fab component[/en]
- * [ja]ons-fabコンポーネント[/ja]
- * @example
- * <ons-speed-dial position="left bottom">
- * <ons-fab>
- * <ons-icon icon="fa-twitter"></ons-icon>
- * </ons-fab>
- * <ons-speed-dial-item>A</ons-speed-dial-item>
- * <ons-speed-dial-item>B</ons-speed-dial-item>
- * <ons-speed-dial-item>C</ons-speed-dial-item>
- * </ons-speed-dial>
- */
-
- var SpeedDialItemElement = function (_BaseElement) {
- inherits(SpeedDialItemElement, _BaseElement);
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the component.[/en]
- * [ja]このコンポーネントの表現を指定します。[/ja]
- */
-
- /**
- * @attribute ripple
- * @description
- * [en]If this attribute is defined, the button will have a ripple effect when tapped.[/en]
- * [ja][/ja]
- */
-
- function SpeedDialItemElement() {
- classCallCheck(this, SpeedDialItemElement);
-
- var _this = possibleConstructorReturn(this, (SpeedDialItemElement.__proto__ || Object.getPrototypeOf(SpeedDialItemElement)).call(this));
-
- _this._compile();
- _this._boundOnClick = _this._onClick.bind(_this);
- return _this;
- }
-
- createClass(SpeedDialItemElement, [{
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$14, scheme$26);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$26);
- util$1.addModifier(this, 'mini');
- break;
- case 'ripple':
- this._updateRipple();
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this.addEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this.removeEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: '_updateRipple',
- value: function _updateRipple() {
- util$1.updateRipple(this);
- }
- }, {
- key: '_onClick',
- value: function _onClick(e) {
- e.stopPropagation();
- }
- }, {
- key: '_compile',
- value: function _compile() {
- var _this2 = this;
-
- autoStyle.prepare(this);
-
- defaultClassName$14.split(/\s+/).forEach(function (token) {
- return _this2.classList.add(token);
- });
-
- util$1.addModifier(this, 'mini');
- this._updateRipple();
-
- ModifierUtil.initModifier(this, scheme$26);
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'ripple', 'class'];
- }
- }]);
- return SpeedDialItemElement;
- }(BaseElement);
-
- onsElements.SpeedDialItem = SpeedDialItemElement;
- customElements.define('ons-speed-dial-item', SpeedDialItemElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
- var defaultClassName$15 = 'speed-dial';
- var scheme$27 = {
- '': 'speed-dial--*'
- };
-
- /**
- * @element ons-speed-dial
- * @category control
- * @description
- * [en]
- * Element that displays a Material Design Speed Dialog component. It is useful when there are more than one primary action that can be performed in a page.
- *
- * The Speed dial looks like a `<ons-fab>` element but will expand a menu when tapped.
- * [/en]
- * [ja][/ja]
- * @codepen dYQYLg
- * @tutorial vanilla/Reference/speed-dial
- * @seealso ons-speed-dial-item
- * [en]The `<ons-speed-dial-item>` represents a menu item.[/en]
- * [ja]ons-speed-dial-itemコンポーネント[/ja]
- * @seealso ons-fab
- * [en]ons-fab component[/en]
- * [ja]ons-fabコンポーネント[/ja]
- * @example
- * <ons-speed-dial position="left bottom">
- * <ons-fab>
- * <ons-icon icon="fa-twitter"></ons-icon>
- * </ons-fab>
- * <ons-speed-dial-item>A</ons-speed-dial-item>
- * <ons-speed-dial-item>B</ons-speed-dial-item>
- * <ons-speed-dial-item>C</ons-speed-dial-item>
- * </ons-speed-dial>
- */
-
- var SpeedDialElement = function (_BaseElement) {
- inherits(SpeedDialElement, _BaseElement);
-
- /**
- * @event open
- * @description
- * [en]Fired when the menu items are shown.[/en]
- * [ja][/ja]
- */
-
- /**
- * @event close
- * @description
- * [en]Fired when the menu items are hidden.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the component.[/en]
- * [ja]このコンポーネントの表現を指定します。[/ja]
- */
-
- /**
- * @attribute ripple
- * @description
- * [en]If this attribute is defined, the button will have a ripple effect when tapped.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute position
- * @type {String}
- * @description
- * [en]
- * Specify the vertical and horizontal position of the component.
- * I.e. to display it in the top right corner specify "right top".
- * Choose from "right", "left", "top" and "bottom".
- * [/en]
- * [ja]
- * この要素を表示する左右と上下の位置を指定します。
- * 例えば、右上に表示する場合には"right top"を指定します。
- * 左右と上下の位置の指定には、rightとleft、topとbottomがそれぞれ指定できます。
- * [/ja]
- */
-
- /**
- * @attribute direction
- * @type {String}
- * @description
- * [en]Specify the direction the items are displayed. Possible values are "up", "down", "left" and "right".[/en]
- * [ja]
- * 要素が表示する方向を指定します。up, down, left, rightが指定できます。
- * [/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Specify if button should be disabled.[/en]
- * [ja]無効化する場合に指定します。[/ja]
- */
-
- function SpeedDialElement() {
- classCallCheck(this, SpeedDialElement);
-
- var _this = possibleConstructorReturn(this, (SpeedDialElement.__proto__ || Object.getPrototypeOf(SpeedDialElement)).call(this));
-
- contentReady(_this, function () {
- _this._compile();
- });
-
- _this._itemShown = false;
- _this._boundOnClick = _this._onClick.bind(_this);
- return _this;
- }
-
- createClass(SpeedDialElement, [{
- key: '_compile',
- value: function _compile() {
- this.classList.add(defaultClassName$15);
- autoStyle.prepare(this);
- this._updateRipple();
- ModifierUtil.initModifier(this, scheme$27);
-
- if (this.hasAttribute('direction')) {
- this._updateDirection(this.getAttribute('direction'));
- } else {
- this._updateDirection('up');
- }
-
- this._updatePosition();
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this2 = this;
-
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$15, scheme$27);
- break;
- case 'modifier':
- ModifierUtil.onModifierChanged(last, current, this, scheme$27);
- break;
- case 'ripple':
- contentReady(this, function () {
- return _this2._updateRipple();
- });
- break;
- case 'direction':
- contentReady(this, function () {
- return _this2._updateDirection(current);
- });
- break;
- case 'position':
- contentReady(this, function () {
- return _this2._updatePosition();
- });
- break;
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this.addEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this.removeEventListener('click', this._boundOnClick, false);
- }
- }, {
- key: '_onClick',
- value: function _onClick(e) {
- if (this.onClick) {
- this.onClick.apply(this);
- return Promise.resolve();
- } else if (!this.disabled && this.visible) {
- return this.toggleItems();
- }
- }
- }, {
- key: '_show',
- value: function _show() {
- if (!this.inline) {
- return this.show();
- }
- return Promise.resolve();
- }
- }, {
- key: '_hide',
- value: function _hide() {
- var _this3 = this;
-
- return new Promise(function (resolve) {
- if (!_this3.inline) {
- setImmediate(function () {
- return _this3.hide().then(resolve);
- });
- } else {
- resolve();
- }
- });
- }
- }, {
- key: '_updateRipple',
- value: function _updateRipple() {
- if (this._fab) {
- this.hasAttribute('ripple') ? this._fab.setAttribute('ripple', '') : this._fab.removeAttribute('ripple');
- }
- }
- }, {
- key: '_updateDirection',
- value: function _updateDirection(direction) {
- var children = this.items;
- for (var i = 0; i < children.length; i++) {
- styler(children[i], {
- transitionDelay: 25 * i + 'ms',
- bottom: 'auto',
- right: 'auto',
- top: 'auto',
- left: 'auto'
- });
- }
- switch (direction) {
- case 'up':
- for (var _i = 0; _i < children.length; _i++) {
- children[_i].style.bottom = 72 + 56 * _i + 'px';
- children[_i].style.right = '8px';
- }
- break;
- case 'down':
- for (var _i2 = 0; _i2 < children.length; _i2++) {
- children[_i2].style.top = 72 + 56 * _i2 + 'px';
- children[_i2].style.left = '8px';
- }
- break;
- case 'left':
- for (var _i3 = 0; _i3 < children.length; _i3++) {
- children[_i3].style.top = '8px';
- children[_i3].style.right = 72 + 56 * _i3 + 'px';
- }
- break;
- case 'right':
- for (var _i4 = 0; _i4 < children.length; _i4++) {
- children[_i4].style.top = '8px';
- children[_i4].style.left = 72 + 56 * _i4 + 'px';
- }
- break;
- default:
- util$1.throw('Argument must be one of up, down, left or right.');
- }
- }
- }, {
- key: '_updatePosition',
- value: function _updatePosition() {
- var position = this.getAttribute('position');
- this.classList.remove('fab--top__left', 'fab--bottom__right', 'fab--bottom__left', 'fab--top__right', 'fab--top__center', 'fab--bottom__center');
- switch (position) {
- case 'top right':
- case 'right top':
- this.classList.add('fab--top__right');
- break;
- case 'top left':
- case 'left top':
- this.classList.add('fab--top__left');
- break;
- case 'bottom right':
- case 'right bottom':
- this.classList.add('fab--bottom__right');
- break;
- case 'bottom left':
- case 'left bottom':
- this.classList.add('fab--bottom__left');
- break;
- case 'center top':
- case 'top center':
- this.classList.add('fab--top__center');
- break;
- case 'center bottom':
- case 'bottom center':
- this.classList.add('fab--bottom__center');
- break;
- default:
- break;
- }
- }
- }, {
- key: '_getTranslate',
- value: function _getTranslate() {
- var isBottom = (this.getAttribute('position') || '').indexOf('bottom') >= 0;
- var translate = isBottom ? 'translate3d(0px, -' + (util$1.globals.fabOffset || 0) + 'px, 0px) ' : '';
- return translate;
- }
-
- /**
- * @method show
- * @signature show()
- * @description
- * [en]Show the speed dial.[/en]
- * [ja]Speed dialを表示します。[/ja]
- */
-
- }, {
- key: 'show',
- value: function show() {
- this._fab.show();
- styler(this, { transform: this._getTranslate });
- return Promise.resolve();
- }
-
- /**
- * @method hide
- * @signature hide()
- * @description
- * [en]Hide the speed dial.[/en]
- * [ja]Speed dialを非表示にします。[/ja]
- */
-
- }, {
- key: 'hide',
- value: function hide() {
- var _this4 = this;
-
- return this.hideItems().then(function () {
- return _this4._fab.hide();
- });
- }
-
- /**
- * @method showItems
- * @signature showItems()
- * @description
- * [en]Show the speed dial items.[/en]
- * [ja]Speed dialの子要素を表示します。[/ja]
- */
-
- }, {
- key: 'showItems',
- value: function showItems() {
- if (this.hasAttribute('direction')) {
- this._updateDirection(this.getAttribute('direction'));
- } else {
- this._updateDirection('up');
- }
-
- var totalDelay = 0;
- if (!this._itemShown) {
- var children = this.items;
- for (var i = 0; i < children.length; i++) {
- var delay = 25 * i;
- totalDelay += delay;
- styler(children[i], {
- transform: 'scale(1)',
- transitionDelay: delay + 'ms'
- });
- }
- totalDelay += 50;
-
- this._itemShown = true;
- util$1.triggerElementEvent(this, 'open');
- }
-
- var deferred = util$1.defer();
- setTimeout(deferred.resolve, totalDelay);
- return deferred.promise;
- }
-
- /**
- * @method hideItems
- * @signature hideItems()
- * @description
- * [en]Hide the speed dial items.[/en]
- * [ja]Speed dialの子要素を非表示にします。[/ja]
- */
-
- }, {
- key: 'hideItems',
- value: function hideItems() {
- var totalDelay = 0;
- if (this._itemShown) {
- var children = this.items;
- for (var i = 0; i < children.length; i++) {
- var delay = 25 * (children.length - i);
- totalDelay += delay;
- styler(children[i], {
- transform: 'scale(0)',
- transitionDelay: delay + 'ms'
- });
- }
- totalDelay += 50;
-
- this._itemShown = false;
- util$1.triggerElementEvent(this, 'close');
- }
-
- var deferred = util$1.defer();
- setTimeout(deferred.resolve, totalDelay);
- return deferred.promise;
- }
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- }, {
- key: 'isOpen',
-
-
- /**
- * @method isOpen
- * @signature isOpen()
- * @description
- * [en]Returns whether the menu is open or not.[/en]
- * [ja][/ja]
- */
- value: function isOpen() {
- return this._itemShown;
- }
-
- /**
- * @method toggle
- * @signature toggle()
- * @description
- * [en]Toggle visibility.[/en]
- * [ja]Speed dialの表示非表示を切り替えます。[/ja]
- */
-
- }, {
- key: 'toggle',
- value: function toggle() {
- return this.visible ? this.hide() : this.show();
- }
-
- /**
- * @method toggleItems
- * @signature toggleItems()
- * @description
- * [en]Toggle item visibility.[/en]
- * [ja]Speed dialの子要素の表示非表示を切り替えます。[/ja]
- */
-
- }, {
- key: 'toggleItems',
- value: function toggleItems() {
- return this.isOpen() ? this.hideItems() : this.showItems();
- }
- }, {
- key: 'items',
- get: function get$$1() {
- return util$1.arrayFrom(this.querySelectorAll('ons-speed-dial-item'));
- }
- }, {
- key: '_fab',
- get: function get$$1() {
- return util$1.findChild(this, 'ons-fab');
- }
- }, {
- key: 'disabled',
- set: function set$$1(value) {
- if (value) {
- this.hideItems();
- }
- util$1.arrayFrom(this.children).forEach(function (e) {
- util$1.match(e, '.fab') && util$1.toggleAttribute(e, 'disabled', value);
- });
-
- return util$1.toggleAttribute(this, 'disabled', value);
- },
- get: function get$$1() {
- return this.hasAttribute('disabled');
- }
-
- /**
- * @property inline
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the element is inline or not.[/en]
- * [ja]インライン要素の場合に`true`。[/ja]
- */
-
- }, {
- key: 'inline',
- get: function get$$1() {
- return this.hasAttribute('inline');
- }
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the element is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- }, {
- key: 'visible',
- get: function get$$1() {
- return this._fab.visible && this.style.display !== 'none';
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['class', 'modifier', 'ripple', 'direction', 'position'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['open', 'close'];
- }
- }]);
- return SpeedDialElement;
- }(BaseElement);
-
- onsElements.SpeedDial = SpeedDialElement;
- customElements.define('ons-speed-dial', SpeedDialElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var rewritables$1 = {
- /**
- * @param {Element} element
- * @param {Function} callback
- */
- ready: function ready(element, callback) {
- setImmediate(callback);
- }
- };
-
- /**
- * @element ons-splitter-content
- * @category menu
- * @description
- * [en]
- * The `<ons-splitter-content>` element is used as a child element of `<ons-splitter>`.
- *
- * It contains the main content of the page while `<ons-splitter-side>` contains the list.
- * [/en]
- * [ja]ons-splitter-content要素は、ons-splitter要素の子要素として利用します。[/ja]
- * @codepen rOQOML
- * @tutorial vanilla/Reference/splitter
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages.[/en]
- * [ja]複数のページを管理する[/ja]
- * @seealso ons-splitter
- * [en]The `<ons-splitter>` component is the parent element.[/en]
- * [ja]ons-splitterコンポーネント[/ja]
- * @seealso ons-splitter-side
- * [en]The `<ons-splitter-side>` component contains the menu.[/en]
- * [ja]ons-splitter-sideコンポーネント[/ja]
- * @example
- * <ons-splitter>
- * <ons-splitter-content>
- * ...
- * </ons-splitter-content>
- *
- * <ons-splitter-side side="left" width="80%" collapse>
- * ...
- * </ons-splitter-side>
- * </ons-splitter>
- */
-
- var SplitterContentElement = function (_BaseElement) {
- inherits(SplitterContentElement, _BaseElement);
-
- /**
- * @attribute page
- * @type {String}
- * @description
- * [en]
- * The url of the content page. If this attribute is used the content will be loaded from a `<template>` tag or a remote file.
- *
- * It is also possible to put `<ons-page>` element as a child of the element.
- * [/en]
- * [ja]ons-splitter-content要素に表示するページのURLを指定します。[/ja]
- */
-
- function SplitterContentElement() {
- classCallCheck(this, SplitterContentElement);
-
- var _this = possibleConstructorReturn(this, (SplitterContentElement.__proto__ || Object.getPrototypeOf(SplitterContentElement)).call(this));
-
- _this._page = null;
- _this._pageLoader = defaultPageLoader;
-
- contentReady(_this, function () {
- rewritables$1.ready(_this, function () {
- var page = _this._getPageTarget();
-
- if (page) {
- _this.load(page);
- }
- });
- });
- return _this;
- }
-
- createClass(SplitterContentElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- if (!util$1.match(this.parentNode, 'ons-splitter')) {
- util$1.throw('"ons-splitter-content" must have "ons-splitter" as parent');
- }
- }
- }, {
- key: '_getPageTarget',
- value: function _getPageTarget() {
- return this._page || this.getAttribute('page');
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {}
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {}
-
- /**
- * @property page
- * @type {HTMLElement}
- * @description
- * [en]The page to load in the splitter content.[/en]
- * [ja]この要素内に表示するページを指定します。[/ja]
- */
-
- }, {
- key: 'load',
-
-
- /**
- * @method load
- * @signature load(page, [options])
- * @param {String} page, [options]
- * [en]Page URL. Can be either an HTML document or an `<template>` id.[/en]
- * [ja]pageのURLか、`<template>`で宣言したテンプレートのid属性の値を指定します。[/ja]
- * @param {Object} [options]
- * @param {Function} [options.callback]
- * @description
- * [en]Show the page specified in `page` in the content.[/en]
- * [ja]指定したURLをメインページを読み込みます。[/ja]
- * @return {Promise}
- * [en]Resolves to the new `<ons-page>` element[/en]
- * [ja]`<ons-page>`要素を解決するPromiseオブジェクトを返します。[/ja]
- */
- value: function load(page) {
- var _this2 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- this._page = page;
- var callback = options.callback || function () {};
-
- return new Promise(function (resolve) {
- var oldContent = _this2._content || null;
-
- _this2._pageLoader.load({ page: page, parent: _this2 }, function (pageElement) {
- if (oldContent) {
- _this2._pageLoader.unload(oldContent);
- oldContent = null;
- }
-
- setImmediate(function () {
- return _this2._show();
- });
-
- callback(pageElement);
- resolve(pageElement);
- });
- });
- }
- }, {
- key: '_show',
- value: function _show() {
- if (this._content) {
- this._content._show();
- }
- }
- }, {
- key: '_hide',
- value: function _hide() {
- if (this._content) {
- this._content._hide();
- }
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- if (this._content) {
- this._pageLoader.unload(this._content);
- }
- this.remove();
- }
- }, {
- key: 'page',
- get: function get$$1() {
- return this._page;
- }
-
- /**
- * @param {*} page
- */
- ,
- set: function set$$1(page) {
- this._page = page;
- }
- }, {
- key: '_content',
- get: function get$$1() {
- return this.children[0];
- }
-
- /**
- * @property pageLoader
- * @type {Function}
- * @description
- * [en]Page element loaded in the splitter content.[/en]
- * [ja]この要素内に表示するページを指定します。[/ja]
- */
-
- }, {
- key: 'pageLoader',
- get: function get$$1() {
- return this._pageLoader;
- },
- set: function set$$1(loader) {
- if (!(loader instanceof PageLoader)) {
- util$1.throwPageLoader();
- }
- this._pageLoader = loader;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return [];
- }
- }, {
- key: 'rewritables',
- get: function get$$1() {
- return rewritables$1;
- }
- }]);
- return SplitterContentElement;
- }(BaseElement);
-
- onsElements.SplitterContent = SplitterContentElement;
- customElements.define('ons-splitter-content', SplitterContentElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var SplitterMaskElement = function (_BaseElement) {
- inherits(SplitterMaskElement, _BaseElement);
-
- function SplitterMaskElement() {
- classCallCheck(this, SplitterMaskElement);
-
- var _this = possibleConstructorReturn(this, (SplitterMaskElement.__proto__ || Object.getPrototypeOf(SplitterMaskElement)).call(this));
-
- _this._boundOnClick = _this._onClick.bind(_this);
- contentReady(_this, function () {
- if (_this.parentNode._sides.every(function (side) {
- return side.mode === 'split';
- })) {
- _this.setAttribute('style', 'display: none !important');
- }
- });
- return _this;
- }
-
- createClass(SplitterMaskElement, [{
- key: '_onClick',
- value: function _onClick(event) {
- if (this.onClick instanceof Function) {
- this.onClick();
- } else if (util$1.match(this.parentNode, 'ons-splitter')) {
- this.parentNode._sides.forEach(function (side) {
- return side.close('left').catch(function () {});
- });
- }
- event.stopPropagation();
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {}
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- this.addEventListener('click', this._boundOnClick);
- util$1.iosMaskScrollFix(this, true);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this.removeEventListener('click', this._boundOnClick);
- util$1.iosMaskScrollFix(this, false);
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return [];
- }
- }]);
- return SplitterMaskElement;
- }(BaseElement);
-
- onsElements.SplitterMask = SplitterMaskElement;
- customElements.define('ons-splitter-mask', SplitterMaskElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var SplitterAnimator$1 = function (_BaseAnimator) {
- inherits(SplitterAnimator, _BaseAnimator);
-
- function SplitterAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'cubic-bezier(.1, .7, .1, 1)' : _ref$timing,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.3 : _ref$duration,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay;
-
- classCallCheck(this, SplitterAnimator);
- return possibleConstructorReturn(this, (SplitterAnimator.__proto__ || Object.getPrototypeOf(SplitterAnimator)).call(this, { timing: timing, duration: duration, delay: delay }));
- }
-
- createClass(SplitterAnimator, [{
- key: 'updateOptions',
- value: function updateOptions() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- util$1.extend(this, {
- timing: this.timing, duration: this.duration, delay: this.delay
- }, options);
- }
-
- /**
- * @param {Element} sideElement
- */
-
- }, {
- key: 'activate',
- value: function activate(sideElement) {
- var _this2 = this;
-
- var splitter = sideElement.parentNode;
-
- contentReady(splitter, function () {
- _this2._side = sideElement;
- _this2._oppositeSide = splitter.right !== sideElement && splitter.right || splitter.left !== sideElement && splitter.left;
- _this2._content = splitter.content;
- _this2._mask = splitter.mask;
- });
- }
- }, {
- key: 'deactivate',
- value: function deactivate() {
- this.clearTransition();
- this._mask && this.clearMask();
- this._content = this._side = this._oppositeSide = this._mask = null;
- }
- }, {
- key: 'clearTransition',
- value: function clearTransition() {
- var _this3 = this;
-
- 'side mask content'.split(/\s+/).forEach(function (e) {
- return _this3['_' + e] && styler.clear(_this3['_' + e], 'transform transition');
- });
- }
- }, {
- key: 'clearMask',
- value: function clearMask() {
- // Check if the other side needs the mask before clearing
- if (!this._oppositeSide || this._oppositeSide.mode === 'split' || !this._oppositeSide.isOpen) {
- this._mask.style.opacity = '';
- this._mask.style.display = 'none';
- }
- }
-
- /**
- * @param {Number} distance
- */
-
- }, {
- key: 'translate',
- value: function translate(distance) {}
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'open',
- value: function open(done) {
- done();
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'close',
- value: function close(done) {
- done();
- }
- }, {
- key: 'minus',
- get: function get$$1() {
- return this._side.side === 'right' ? '-' : '';
- }
- }]);
- return SplitterAnimator;
- }(BaseAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var OverlaySplitterAnimator = function (_SplitterAnimator) {
- inherits(OverlaySplitterAnimator, _SplitterAnimator);
-
- function OverlaySplitterAnimator() {
- classCallCheck(this, OverlaySplitterAnimator);
- return possibleConstructorReturn(this, (OverlaySplitterAnimator.__proto__ || Object.getPrototypeOf(OverlaySplitterAnimator)).apply(this, arguments));
- }
-
- createClass(OverlaySplitterAnimator, [{
- key: 'translate',
- value: function translate(distance) {
- this._mask.style.display = 'block'; // Avoid content clicks
-
- Animit(this._side).queue({
- transform: 'translate3d(' + (this.minus + distance) + 'px, 0, 0)'
- }).play();
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'open',
- value: function open(done) {
- Animit.runAll(Animit(this._side).wait(this.delay).queue({
- transform: 'translate3d(' + this.minus + '100%, 0, 0)'
- }, this.def).queue(function (callback) {
- callback();
- done && done();
- }), Animit(this._mask).wait(this.delay).queue({
- display: 'block'
- }).queue({
- opacity: '1'
- }, {
- duration: this.duration,
- timing: 'linear'
- }));
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'close',
- value: function close(done) {
-
- Animit.runAll(Animit(this._side).wait(this.delay).queue({
- transform: 'translate3d(0, 0, 0)'
- }, this.def).queue(function (callback) {
- done && done();
- callback();
- }), Animit(this._mask).wait(this.delay).queue({
- opacity: '0'
- }, {
- duration: this.duration,
- timing: 'linear'
- }).queue({
- display: 'none'
- }));
- }
- }]);
- return OverlaySplitterAnimator;
- }(SplitterAnimator$1);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var PushSplitterAnimator = function (_SplitterAnimator) {
- inherits(PushSplitterAnimator, _SplitterAnimator);
-
- function PushSplitterAnimator() {
- classCallCheck(this, PushSplitterAnimator);
- return possibleConstructorReturn(this, (PushSplitterAnimator.__proto__ || Object.getPrototypeOf(PushSplitterAnimator)).apply(this, arguments));
- }
-
- createClass(PushSplitterAnimator, [{
- key: '_getSlidingElements',
- value: function _getSlidingElements() {
- var slidingElements = [this._side, this._content];
- if (this._oppositeSide && this._oppositeSide.mode === 'split') {
- slidingElements.push(this._oppositeSide);
- }
-
- return slidingElements;
- }
- }, {
- key: 'translate',
- value: function translate(distance) {
- if (!this._slidingElements) {
- this._slidingElements = this._getSlidingElements();
- }
-
- this._mask.style.display = 'block'; // Avoid content clicks
-
- Animit(this._slidingElements).queue({
- transform: 'translate3d(' + (this.minus + distance) + 'px, 0, 0)'
- }).play();
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'open',
- value: function open(done) {
- var _this2 = this;
-
- var max = this._side.offsetWidth;
- this._slidingElements = this._getSlidingElements();
-
- Animit.runAll(Animit(this._slidingElements).wait(this.delay).queue({
- transform: 'translate3d(' + (this.minus + max) + 'px, 0, 0)'
- }, this.def).queue(function (callback) {
- _this2._slidingElements = null;
- callback();
- done && done();
- }), Animit(this._mask).wait(this.delay).queue({
- display: 'block'
- }));
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'close',
- value: function close(done) {
- var _this3 = this;
-
- this._slidingElements = this._getSlidingElements();
-
- Animit.runAll(Animit(this._slidingElements).wait(this.delay).queue({
- transform: 'translate3d(0, 0, 0)'
- }, this.def).queue(function (callback) {
- _this3._slidingElements = null;
- get(PushSplitterAnimator.prototype.__proto__ || Object.getPrototypeOf(PushSplitterAnimator.prototype), 'clearTransition', _this3).call(_this3);
- done && done();
- callback();
- }), Animit(this._mask).wait(this.delay).queue({
- display: 'none'
- }));
- }
- }]);
- return PushSplitterAnimator;
- }(SplitterAnimator$1);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var RevealSplitterAnimator = function (_SplitterAnimator) {
- inherits(RevealSplitterAnimator, _SplitterAnimator);
-
- function RevealSplitterAnimator() {
- classCallCheck(this, RevealSplitterAnimator);
- return possibleConstructorReturn(this, (RevealSplitterAnimator.__proto__ || Object.getPrototypeOf(RevealSplitterAnimator)).apply(this, arguments));
- }
-
- createClass(RevealSplitterAnimator, [{
- key: '_getSlidingElements',
- value: function _getSlidingElements() {
- var slidingElements = [this._content, this._mask];
- if (this._oppositeSide && this._oppositeSide.mode === 'split') {
- slidingElements.push(this._oppositeSide);
- }
-
- return slidingElements;
- }
- }, {
- key: 'activate',
- value: function activate(sideElement) {
- get(RevealSplitterAnimator.prototype.__proto__ || Object.getPrototypeOf(RevealSplitterAnimator.prototype), 'activate', this).call(this, sideElement);
- if (sideElement.mode === 'collapse') {
- this._setStyles(sideElement);
- }
- }
- }, {
- key: 'deactivate',
- value: function deactivate() {
- this._side && this._unsetStyles(this._side);
- get(RevealSplitterAnimator.prototype.__proto__ || Object.getPrototypeOf(RevealSplitterAnimator.prototype), 'deactivate', this).call(this);
- }
- }, {
- key: '_setStyles',
- value: function _setStyles(sideElement) {
- styler(sideElement, {
- left: sideElement.side === 'right' ? 'auto' : 0,
- right: sideElement.side === 'right' ? 0 : 'auto',
- zIndex: 0,
- backgroundColor: 'black',
- transform: this._generateBehindPageStyle(0).container.transform,
- display: 'none'
- });
-
- var splitter = sideElement.parentElement;
- contentReady(splitter, function () {
- return splitter.content && styler(splitter.content, { boxShadow: '0 0 12px 0 rgba(0, 0, 0, 0.2)' });
- });
- }
- }, {
- key: '_unsetStyles',
- value: function _unsetStyles(sideElement) {
- styler.clear(sideElement, 'left right zIndex backgroundColor display');
- if (sideElement._content) {
- sideElement._content.style.opacity = '';
- }
-
- // Check if the other side needs the common styles
- if (!this._oppositeSide || this._oppositeSide.mode === 'split') {
- sideElement.parentElement.content && styler.clear(sideElement.parentElement.content, 'boxShadow');
- }
- }
- }, {
- key: '_generateBehindPageStyle',
- value: function _generateBehindPageStyle(distance) {
- var max = this.maxWidth;
-
- var behindDistance = (distance - max) / max * 10;
- behindDistance = isNaN(behindDistance) ? 0 : Math.max(Math.min(behindDistance, 0), -10);
-
- var behindTransform = 'translate3d(' + (this.minus ? -1 : 1) * behindDistance + '%, 0, 0)';
- var opacity = 1 + behindDistance / 100;
-
- return {
- content: {
- opacity: opacity
- },
- container: {
- transform: behindTransform
- }
- };
- }
- }, {
- key: 'translate',
- value: function translate(distance) {
- this._side.style.display = '';
- this._side.style.zIndex = 1;
- this.maxWidth = this.maxWidth || this._getMaxWidth();
- var menuStyle = this._generateBehindPageStyle(Math.min(distance, this.maxWidth));
-
- if (!this._slidingElements) {
- this._slidingElements = this._getSlidingElements();
- }
-
- this._mask.style.display = 'block'; // Avoid content clicks
-
- Animit.runAll(Animit(this._slidingElements).queue({
- transform: 'translate3d(' + (this.minus + distance) + 'px, 0, 0)'
- }), Animit(this._side._content).queue(menuStyle.content), Animit(this._side).queue(menuStyle.container));
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'open',
- value: function open(done) {
- var _this2 = this;
-
- this._side.style.display = '';
- this._side.style.zIndex = 1;
- this.maxWidth = this.maxWidth || this._getMaxWidth();
- var menuStyle = this._generateBehindPageStyle(this.maxWidth);
- this._slidingElements = this._getSlidingElements();
-
- setTimeout(function () {
- // Fix: Time to update previous translate3d after changing style.display
- Animit.runAll(Animit(_this2._slidingElements).wait(_this2.delay).queue({
- transform: 'translate3d(' + (_this2.minus + _this2.maxWidth) + 'px, 0, 0)'
- }, _this2.def), Animit(_this2._mask).wait(_this2.delay).queue({
- display: 'block'
- }), Animit(_this2._side._content).wait(_this2.delay).queue(menuStyle.content, _this2.def), Animit(_this2._side).wait(_this2.delay).queue(menuStyle.container, _this2.def).queue(function (callback) {
- _this2._slidingElements = null;
- callback();
- done && done();
- }));
- }, 1000 / 60);
- }
-
- /**
- * @param {Function} done
- */
-
- }, {
- key: 'close',
- value: function close(done) {
- var _this3 = this;
-
- var menuStyle = this._generateBehindPageStyle(0);
- this._slidingElements = this._getSlidingElements();
-
- Animit.runAll(Animit(this._slidingElements).wait(this.delay).queue({
- transform: 'translate3d(0, 0, 0)'
- }, this.def), Animit(this._mask).wait(this.delay).queue({
- display: 'none'
- }), Animit(this._side._content).wait(this.delay).queue(menuStyle.content, this.def), Animit(this._side).wait(this.delay).queue(menuStyle.container, this.def).queue(function (callback) {
- _this3._slidingElements = null;
- _this3._side.style.zIndex = 0;
- _this3._side.style.display = 'none';
- _this3._side._content.style.opacity = '';
- done && done();
- callback();
- }));
- }
- }, {
- key: '_getMaxWidth',
- value: function _getMaxWidth() {
- return this._side.offsetWidth;
- }
- }]);
- return RevealSplitterAnimator;
- }(SplitterAnimator$1);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var _animatorDict$7 = {
- default: OverlaySplitterAnimator,
- overlay: OverlaySplitterAnimator,
- push: PushSplitterAnimator,
- reveal: RevealSplitterAnimator
- };
-
- /**
- * @element ons-splitter
- * @category menu
- * @description
- * [en]
- * A component that enables responsive layout by implementing both a two-column layout and a sliding menu layout.
- *
- * It can be configured to automatically expand into a column layout on large screens and collapse the menu on smaller screens. When the menu is collapsed the user can open it by swiping.
- * [/en]
- * [ja][/ja]
- * @codepen rOQOML
- * @tutorial vanilla/Reference/splitter
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages.[/en]
- * [ja]複数のページを管理する[/ja]
- * @seealso ons-splitter-content
- * [en]The `<ons-splitter-content>` component contains the main content of the page.[/en]
- * [ja]ons-splitter-contentコンポーネント[/ja]
- * @seealso ons-splitter-side
- * [en]The `<ons-splitter-side>` component contains the menu.[/en]
- * [ja]ons-splitter-sideコンポーネント[/ja]
- * @example
- * <ons-splitter id="splitter">
- * <ons-splitter-content>
- * ...
- * </ons-splitter-content>
- *
- * <ons-splitter-side side="left" width="80%" collapse swipeable>
- * ...
- * </ons-splitter-side>
- * </ons-splitter>
- *
- * <script>
- * var splitter = document.getElementById('splitter');
- * splitter.left.open();
- * </script>
- */
-
- var SplitterElement = function (_BaseElement) {
- inherits(SplitterElement, _BaseElement);
- createClass(SplitterElement, [{
- key: '_getSide',
- value: function _getSide(side) {
- var element = util$1.findChild(this, function (e) {
- return util$1.match(e, 'ons-splitter-side') && e.getAttribute('side') === side;
- });
- return element;
- }
-
- /**
- * @property left
- * @readonly
- * @type {HTMLElement}
- * @description
- * [en]Left `<ons-splitter-side>` element.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: '_onDeviceBackButton',
- value: function _onDeviceBackButton(event) {
- this._sides.some(function (s) {
- return s.isOpen ? s.close() : false;
- }) || event.callParentHandler();
- }
- }, {
- key: '_onModeChange',
- value: function _onModeChange(e) {
- var _this2 = this;
-
- if (e.target.parentNode) {
- contentReady(this, function () {
- _this2._layout();
- });
- }
- }
- }, {
- key: '_layout',
- value: function _layout() {
- var _this3 = this;
-
- this._sides.forEach(function (side) {
- if (_this3.content) {
- _this3.content.style[side.side] = side.mode === 'split' ? side.style.width : 0;
- }
- });
- }
- }, {
- key: 'left',
- get: function get$$1() {
- return this._getSide('left');
- }
- /**
- * @property right
- * @readonly
- * @type {HTMLElement}
- * @description
- * [en]Right `<ons-splitter-side>` element.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'right',
- get: function get$$1() {
- return this._getSide('right');
- }
-
- /**
- * @property side
- * @readonly
- * @type {HTMLElement}
- * @description
- * [en]First `<ons-splitter-side>` element regardless the actual side.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'side',
- get: function get$$1() {
- return util$1.findChild(this, 'ons-splitter-side');
- }
- }, {
- key: '_sides',
- get: function get$$1() {
- return [this.left, this.right].filter(function (e) {
- return e;
- });
- }
- /**
- * @property content
- * @readonly
- * @type {HTMLElement}
- * @description
- * [en]The `<ons-splitter-content>` element.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'content',
- get: function get$$1() {
- return util$1.findChild(this, 'ons-splitter-content');
- }
- }, {
- key: 'topPage',
- get: function get$$1() {
- return this.content._content;
- }
- }, {
- key: 'mask',
- get: function get$$1() {
- return util$1.findChild(this, 'ons-splitter-mask');
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: 'onDeviceBackButton',
- get: function get$$1() {
- return this._backButtonHandler;
- },
- set: function set$$1(callback) {
- if (this._backButtonHandler) {
- this._backButtonHandler.destroy();
- }
-
- this._backButtonHandler = deviceBackButtonDispatcher.createHandler(this, callback);
- }
- }]);
-
- function SplitterElement() {
- classCallCheck(this, SplitterElement);
-
- var _this = possibleConstructorReturn(this, (SplitterElement.__proto__ || Object.getPrototypeOf(SplitterElement)).call(this));
-
- _this._onModeChange = _this._onModeChange.bind(_this);
-
- contentReady(_this, function () {
- !_this.mask && _this.appendChild(document.createElement('ons-splitter-mask'));
- _this._layout();
- });
- return _this;
- }
-
- createClass(SplitterElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- this.onDeviceBackButton = this._onDeviceBackButton.bind(this);
- this.addEventListener('modechange', this._onModeChange, false);
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._backButtonHandler.destroy();
- this._backButtonHandler = null;
- this.removeEventListener('modechange', this._onModeChange, false);
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {}
- }, {
- key: '_show',
- value: function _show() {
- util$1.propagateAction(this, '_show');
- }
- }, {
- key: '_hide',
- value: function _hide() {
- util$1.propagateAction(this, '_hide');
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- util$1.propagateAction(this, '_destroy');
- this.remove();
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator instanceof SplitterAnimator)) {
- util$1.throwAnimator('Splitter');
- }
- _animatorDict$7[name] = Animator;
- }
- }, {
- key: 'SplitterAnimator',
- get: function get$$1() {
- return SplitterAnimator;
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$7;
- }
- }]);
- return SplitterElement;
- }(BaseElement);
-
- onsElements.Splitter = SplitterElement;
- customElements.define('ons-splitter', SplitterElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var SPLIT_MODE = 'split';
- var COLLAPSE_MODE = 'collapse';
- var CLOSED_STATE = 'closed';
- var OPEN_STATE = 'open';
- var CHANGING_STATE = 'changing';
-
- var rewritables$2 = {
- /**
- * @param {Element} splitterSideElement
- * @param {Function} callback
- */
- ready: function ready(splitterSideElement, callback) {
- setImmediate(callback);
- }
- };
-
- var CollapseDetection = function () {
- function CollapseDetection(element, target) {
- classCallCheck(this, CollapseDetection);
-
- this._element = element;
- this._onChange = this._onChange.bind(this);
- target && this.changeTarget(target);
- }
-
- createClass(CollapseDetection, [{
- key: 'changeTarget',
- value: function changeTarget(target) {
- this.disable();
- this._target = target;
- if (target) {
- this._orientation = ['portrait', 'landscape'].indexOf(target) !== -1;
- this.activate();
- }
- }
- }, {
- key: '_match',
- value: function _match(value) {
- if (this._orientation) {
- return this._target === (value.isPortrait ? 'portrait' : 'landscape');
- }
- return value.matches;
- }
- }, {
- key: '_onChange',
- value: function _onChange(value) {
- this._element._updateMode(this._match(value) ? COLLAPSE_MODE : SPLIT_MODE);
- }
- }, {
- key: 'activate',
- value: function activate() {
- if (this._orientation) {
- orientation.on('change', this._onChange);
- this._onChange({ isPortrait: orientation.isPortrait() });
- } else {
- this._queryResult = window.matchMedia(this._target);
- this._queryResult.addListener(this._onChange);
- this._onChange(this._queryResult);
- }
- }
- }, {
- key: 'disable',
- value: function disable() {
- if (this._orientation) {
- orientation.off('change', this._onChange);
- } else if (this._queryResult) {
- this._queryResult.removeListener(this._onChange);
- this._queryResult = null;
- }
- }
- }]);
- return CollapseDetection;
- }();
-
- /**
- * @element ons-splitter-side
- * @category menu
- * @description
- * [en]
- * The `<ons-splitter-side>` element is used as a child element of `<ons-splitter>`.
- *
- * It will be displayed on either the left or right side of the `<ons-splitter-content>` element.
- *
- * It supports two modes: collapsed and split. When it's in collapsed mode it will be hidden from view and can be displayed when the user swipes the screen or taps a button. In split mode the element is always shown. It can be configured to automatically switch between the two modes depending on the screen size.
- * [/en]
- * [ja]ons-splitter-side要素は、ons-splitter要素の子要素として利用します。[/ja]
- * @codepen rOQOML
- * @tutorial vanilla/Reference/splitter
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages.[/en]
- * [ja]複数のページを管理する[/ja]
- * @seealso ons-splitter
- * [en]The `<ons-splitter>` is the parent component.[/en]
- * [ja]ons-splitterコンポーネント[/ja]
- * @seealso ons-splitter-content
- * [en]The `<ons-splitter-content>` component contains the main content of the page.[/en]
- * [ja]ons-splitter-contentコンポーネント[/ja]
- * @example
- * <ons-splitter>
- * <ons-splitter-content>
- * ...
- * </ons-splitter-content>
- *
- * <ons-splitter-side side="left" width="80%" collapse>
- * ...
- * </ons-splitter-side>
- * </ons-splitter>
- */
-
- var SplitterSideElement = function (_BaseElement) {
- inherits(SplitterSideElement, _BaseElement);
-
- /**
- * @event modechange
- * @description
- * [en]Fired just after the component's mode changes.[/en]
- * [ja]この要素のモードが変化した際に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.side
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {String} event.mode
- * [en]Returns the current mode. Can be either `"collapse"` or `"split"`.[/en]
- * [ja]現在のモードを返します。[/ja]
- */
-
- /**
- * @event preopen
- * @description
- * [en]Fired just before the sliding menu is opened.[/en]
- * [ja]スライディングメニューが開く前に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Function} event.cancel
- * [en]Call to cancel opening sliding menu.[/en]
- * [ja]スライディングメニューが開くのをキャンセルします。[/ja]
- * @param {Object} event.side
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @event postopen
- * @description
- * [en]Fired just after the sliding menu is opened.[/en]
- * [ja]スライディングメニューが開いた後に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.side
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @event preclose
- * @description
- * [en]Fired just before the sliding menu is closed.[/en]
- * [ja]スライディングメニューが閉じる前に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.side
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Call to cancel opening sliding-menu.[/en]
- * [ja]スライディングメニューが閉じるのをキャンセルします。[/ja]
- */
-
- /**
- * @event postclose
- * @description
- * [en]Fired just after the sliding menu is closed.[/en]
- * [ja]スライディングメニューが閉じた後に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクトです。[/ja]
- * @param {Object} event.side
- * [en]Component object.[/en]
- * [ja]コンポーネントのオブジェクト。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]Specify the animation. Use one of `overlay`, `push`, `reveal` or `default`.[/en]
- * [ja]アニメーションを指定します。"overlay", "push", "reveal", "default"のいずれかを指定できます。[/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
- */
-
- /**
- * @attribute open-threshold
- * @type {Number}
- * @default 0.3
- * @description
- * [en]Specify how much the menu needs to be swiped before opening. A value between `0` and `1`.[/en]
- * [ja]どのくらいスワイプすればスライディングメニューを開くかどうかの割合を指定します。0から1の間の数値を指定します。スワイプの距離がここで指定した数値掛けるこの要素の幅よりも大きければ、スワイプが終わった時にこの要素を開きます。デフォルトは0.3です。[/ja]
- */
-
- /**
- * @attribute collapse
- * @type {String}
- * @description
- * [en]
- * Specify the collapse behavior. Valid values are `"portrait"`, `"landscape"` or a media query.
- * The strings `"portrait"` and `"landscape"` means the view will collapse when device is in landscape or portrait orientation.
- * If the value is a media query, the view will collapse when the media query resolves to `true`.
- * If the value is not defined, the view always be in `"collapse"` mode.
- * [/en]
- * [ja]
- * 左側のページを非表示にする条件を指定します。portrait, landscape、width #pxもしくはメディアクエリの指定が可能です。
- * portraitもしくはlandscapeを指定すると、デバイスの画面が縦向きもしくは横向きになった時に適用されます。
- * メディアクエリを指定すると、指定したクエリに適合している場合に適用されます。
- * 値に何も指定しない場合には、常にcollapseモードになります。
- * [/ja]
- */
-
- /**
- * @attribute swipe-target-width
- * @type {String}
- * @description
- * [en]The width of swipeable area calculated from the edge (in pixels). Use this to enable swipe only when the finger touch on the screen edge.[/en]
- * [ja]スワイプの判定領域をピクセル単位で指定します。画面の端から指定した距離に達するとページが表示されます。[/ja]
- */
-
- /**
- * @attribute width
- * @type {String}
- * @description
- * [en]Can be specified in either pixels or as a percentage, e.g. `90%` or `200px`.[/en]
- * [ja]この要素の横幅を指定します。pxと%での指定が可能です。eg. 90%, 200px[/ja]
- */
-
- /**
- * @attribute side
- * @type {String}
- * @default left
- * @description
- * [en]Specify which side of the screen the `<ons-splitter-side>` element is located. Possible values are `"left"` and `"right"`.[/en]
- * [ja]この要素が左か右かを指定します。指定できる値は"left"か"right"のみです。[/ja]
- */
-
- /**
- * @attribute mode
- * @type {String}
- * @description
- * [en]Current mode. Possible values are `"collapse"` or `"split"`. This attribute is read only.[/en]
- * [ja]現在のモードが設定されます。"collapse"もしくは"split"が指定されます。この属性は読み込み専用です。[/ja]
- */
-
- /**
- * @attribute page
- * @initonly
- * @type {String}
- * @description
- * [en]The URL of the menu page.[/en]
- * [ja]ons-splitter-side要素に表示するページのURLを指定します。[/ja]
- */
-
- /**
- * @attribute swipeable
- * @type {Boolean}
- * @description
- * [en]Whether to enable swipe interaction on collapse mode.[/en]
- * [ja]collapseモード時にスワイプ操作を有効にする場合に指定します。[/ja]
- */
-
- function SplitterSideElement() {
- classCallCheck(this, SplitterSideElement);
-
- var _this = possibleConstructorReturn(this, (SplitterSideElement.__proto__ || Object.getPrototypeOf(SplitterSideElement)).call(this));
-
- _this._page = null;
- _this._state = CLOSED_STATE;
- _this._lock = new DoorLock();
- _this._pageLoader = defaultPageLoader;
- _this._collapseDetection = new CollapseDetection(_this);
-
- _this._animatorFactory = new AnimatorFactory({
- animators: SplitterElement.animators,
- baseClass: SplitterAnimator$1,
- baseClassName: 'SplitterAnimator',
- defaultAnimation: _this.getAttribute('animation')
- });
-
- contentReady(_this, function () {
- // These attributes are used early by the parent element
- _this.attributeChangedCallback('width');
- if (!_this.hasAttribute('side')) {
- _this.setAttribute('side', 'left');
- }
-
- rewritables$2.ready(_this, function () {
- var page = _this._page || _this.getAttribute('page');
- page && _this.load(page);
- });
- });
- return _this;
- }
-
- createClass(SplitterSideElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- if (!util$1.match(this.parentNode, 'ons-splitter')) {
- util$1.throw('Parent must be an ons-splitter element');
- }
-
- this._swipe = new SwipeReveal({
- element: this,
- elementHandler: this.parentElement,
- swipeMax: function swipeMax() {
- _this2._onSwipe && _this2._onSwipe(1, _this2._animationOpt);
- _this2.open();
- },
- swipeMid: function swipeMid(distance, width) {
- _this2._onSwipe && _this2._onSwipe(distance / width);
- _this2._animator.translate(distance);
- },
- swipeMin: function swipeMin() {
- _this2._onSwipe && _this2._onSwipe(0, _this2._animationOpt);
- _this2.close();
- },
- getThreshold: function getThreshold() {
- return Math.max(0, Math.min(1, parseFloat(_this2.getAttribute('open-threshold')) || 0.3));
- },
- getSide: function getSide() {
- return _this2.side;
- },
- isInitialState: function isInitialState() {
- var closed = _this2._state === CLOSED_STATE;
- _this2._state = CHANGING_STATE;
- return closed;
- },
- ignoreSwipe: function ignoreSwipe(event, distance) {
- var isOpen = _this2.isOpen;
- var validDrag = function validDrag(d) {
- return _this2.side === 'left' ? d === 'left' && isOpen || d === 'right' && !isOpen : d === 'left' && !isOpen || d === 'right' && isOpen;
- };
-
- var area = Math.max(0, parseInt(_this2.getAttribute('swipe-target-width'), 10) || 0);
-
- return _this2._mode === SPLIT_MODE || _this2._lock.isLocked() || _this2._isOtherSideOpen() || !validDrag(event.gesture.direction) || !isOpen && area !== 0 && distance > area;
- }
- });
-
- this.attributeChangedCallback('swipeable');
-
- contentReady(this, function () {
- _this2.constructor.observedAttributes.forEach(function (attr) {
- return _this2.attributeChangedCallback(attr, null, _this2.getAttribute(attr));
- });
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this._swipe && this._swipe.dispose();
- this._animator = this._animationOpt = this._swipe = null;
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- switch (name) {
- case 'swipeable':
- this._swipe && this._swipe.update();
- break;
- case 'width':
- current = this.getAttribute('width'); // Sometimes undefined. CE bug?
- this.style.width = /^\d+(px|%)$/.test(current) ? current : '80%';
- break;
- default:
- this[util$1.camelize('_update-' + name)](current);
- }
- }
- }, {
- key: '_emitEvent',
- value: function _emitEvent(name) {
- if (name.slice(0, 3) !== 'pre') {
- return util$1.triggerElementEvent(this, name, { side: this });
- }
- var isCanceled = false;
-
- util$1.triggerElementEvent(this, name, {
- side: this,
- cancel: function cancel() {
- return isCanceled = true;
- }
- });
-
- return isCanceled;
- }
- }, {
- key: '_isOtherSideOpen',
- value: function _isOtherSideOpen() {
- var _this3 = this;
-
- return !!util$1.findChild(this.parentElement, function (el) {
- return el instanceof _this3.constructor && el !== _this3 && el._mode === COLLAPSE_MODE && el.isOpen;
- });
- }
- }, {
- key: '_updateCollapse',
- value: function _updateCollapse() {
- var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('collapse');
-
- if (value === null || value === 'split') {
- this._collapseDetection.disable();
- return this._updateMode(SPLIT_MODE);
- }
- if (value === '' || value === 'collapse') {
- this._collapseDetection.disable();
- return this._updateMode(COLLAPSE_MODE);
- }
-
- this._collapseDetection.changeTarget(value);
- }
- }, {
- key: '_updateMode',
- value: function _updateMode(mode) {
- if (mode !== this._mode) {
- this._mode = mode;
- this.setAttribute('mode', mode); // readonly attribute for the users
-
- if (mode === SPLIT_MODE) {
- this._animator && this._animator.deactivate();
- this._state = CLOSED_STATE;
- } else {
- this._animator && this._animator.activate(this);
- this._state === OPEN_STATE && this._animator.open();
- }
-
- util$1.triggerElementEvent(this, 'modechange', { side: this, mode: mode });
- }
- }
- }, {
- key: '_updateAnimation',
- value: function _updateAnimation() {
- var animation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('animation');
-
- if (this.parentNode) {
- this._animator && this._animator.deactivate();
- this._animator = this._animatorFactory.newAnimator({ animation: animation });
- this._animator.activate(this);
- this._animationOpt = {
- timing: this._animator.duration,
- duration: this._animator.duration
- };
- }
- }
- }, {
- key: '_updateAnimationOptions',
- value: function _updateAnimationOptions() {
- var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('animation-options');
-
- this._animator.updateOptions(AnimatorFactory.parseAnimationOptionsString(value));
- }
-
- /**
- * @property page
- * @type {*}
- * @description
- * [en]Page location to load in the splitter side.[/en]
- * [ja]この要素内に表示するページを指定します。[/ja]
- */
-
- }, {
- key: 'open',
-
-
- /**
- * @method open
- * @signature open([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {Function} [options.callback]
- * [en]This function will be called after the menu has been opened.[/en]
- * [ja]メニューが開いた後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Open menu in collapse mode.[/en]
- * [ja]collapseモードになっているons-splitter-side要素を開きます。[/ja]
- * @return {Promise}
- * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
- * [ja][/ja]
- */
- value: function open(options) {
- return this.toggle(options, true);
- }
-
- /**
- * @method close
- * @signature close([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {Function} [options.callback]
- * [en]This function will be called after the menu has been closed.[/en]
- * [ja]メニューが閉じた後に呼び出される関数オブジェクトを指定します。[/ja]
- * @description
- * [en]Close menu in collapse mode.[/en]
- * [ja]collapseモードになっているons-splitter-side要素を閉じます。[/ja]
- * @return {Promise}
- * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'close',
- value: function close(options) {
- return this.toggle(options, false);
- }
-
- /**
- * @method toggle
- * @signature toggle([options])
- * @param {Object} [options]
- * @description
- * [en]Opens if it's closed. Closes if it's open.[/en]
- * [ja]開けている場合は要素を閉じますそして開けている場合は要素を開きます。[/ja]
- * @return {Promise}
- * [en]Resolves to the splitter side element or false if not in collapse mode[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'toggle',
- value: function toggle() {
- var _this4 = this;
-
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var force = arguments[1];
-
- var shouldOpen = typeof force === 'boolean' ? force : !this.isOpen;
- var action = shouldOpen ? 'open' : 'close';
- var FINAL_STATE = shouldOpen ? OPEN_STATE : CLOSED_STATE;
-
- if (this._mode === SPLIT_MODE) {
- return Promise.resolve(false);
- }
- if (this._state === FINAL_STATE) {
- return Promise.resolve(this);
- }
- if (this._lock.isLocked()) {
- return Promise.reject('Another splitter-side action is already running.');
- }
- if (shouldOpen && this._isOtherSideOpen()) {
- return Promise.reject('Another menu is already open.');
- }
- if (this._emitEvent('pre' + action)) {
- return Promise.reject('Canceled in pre' + action + ' event.');
- }
-
- var unlock = this._lock.lock();
- this._state = CHANGING_STATE;
-
- if (options.animation) {
- this._updateAnimation(options.animation);
- }
-
- return new Promise(function (resolve) {
- _this4._animator[action](function () {
- util$1.iosPageScrollFix(shouldOpen);
- _this4._state = FINAL_STATE;
- unlock();
- _this4._emitEvent('post' + action);
- options.callback instanceof Function && options.callback(_this4);
- resolve(_this4);
- });
- });
- }
-
- /**
- * @method load
- * @signature load(page, [options])
- * @param {String} page
- * [en]Page URL. Can be either an HTML document or a `<template>`.[/en]
- * [ja]pageのURLか、`<template>`で宣言したテンプレートのid属性の値を指定します。[/ja]
- * @param {Object} [options]
- * @param {Function} [options.callback]
- * @description
- * [en]Show the page specified in pageUrl in the right section[/en]
- * [ja]指定したURLをメインページを読み込みます。[/ja]
- * @return {Promise}
- * [en]Resolves to the new page element[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'load',
- value: function load(page) {
- var _this5 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- this._page = page;
- var callback = options.callback || function () {};
-
- return new Promise(function (resolve) {
- var oldContent = _this5._content || null;
-
- _this5._pageLoader.load({ page: page, parent: _this5 }, function (pageElement) {
- if (oldContent) {
- _this5._pageLoader.unload(oldContent);
- oldContent = null;
- }
-
- setImmediate(function () {
- return _this5._show();
- });
-
- callback(pageElement);
- resolve(pageElement);
- });
- });
- }
- }, {
- key: '_show',
- value: function _show() {
- if (this._content) {
- this._content._show();
- }
- }
- }, {
- key: '_hide',
- value: function _hide() {
- if (this._content) {
- this._content._hide();
- }
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- if (this._content) {
- this._pageLoader.unload(this._content);
- }
- this.remove();
- }
- }, {
- key: 'side',
- get: function get$$1() {
- return this.getAttribute('side') === 'right' ? 'right' : 'left';
- }
- }, {
- key: 'page',
- get: function get$$1() {
- return this._page;
- }
-
- /**
- * @param {*} page
- */
- ,
- set: function set$$1(page) {
- this._page = page;
- }
- }, {
- key: '_content',
- get: function get$$1() {
- return this.children[0];
- }
-
- /**
- * @property pageLoader
- * @description
- * [en][/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'pageLoader',
- get: function get$$1() {
- return this._pageLoader;
- },
- set: function set$$1(loader) {
- if (!(loader instanceof PageLoader)) {
- util$1.throwPageLoader();
- }
- this._pageLoader = loader;
- }
-
- /**
- * @property mode
- * @readonly
- * @type {String}
- * @description
- * [en]Current mode. Possible values are "split", "collapse", "closed", "open" or "changing".[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'mode',
- get: function get$$1() {
- return this._mode;
- }
-
- /**
- * @property onSwipe
- * @type {Function}
- * @description
- * [en]Hook called whenever the user slides the splitter. It gets a decimal ratio (0-1) and an animationOptions object as arguments.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onSwipe',
- get: function get$$1() {
- return this._onSwipe;
- },
- set: function set$$1(value) {
- if (value && !(value instanceof Function)) {
- util$1.throw('"onSwipe" must be a function');
- }
- this._onSwipe = value;
- }
-
- /**
- * @property isOpen
- * @type {Boolean}
- * @readonly
- * @description
- * [en]This value is `true` when the menu is open.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'isOpen',
- get: function get$$1() {
- return this._mode === COLLAPSE_MODE && this._state !== CLOSED_STATE;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['animation', 'width', 'collapse', 'swipeable', 'animation-options'];
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['preopen', 'postopen', 'preclose', 'postclose', 'modechange'];
- }
- }, {
- key: 'rewritables',
- get: function get$$1() {
- return rewritables$2;
- }
- }]);
- return SplitterSideElement;
- }(BaseElement);
-
- onsElements.SplitterSide = SplitterSideElement;
- customElements.define('ons-splitter-side', SplitterSideElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$28 = {
- '': 'switch--*',
- '.switch__input': 'switch--*__input',
- '.switch__handle': 'switch--*__handle',
- '.switch__toggle': 'switch--*__toggle'
- };
-
- var locations = {
- ios: [1, 21],
- material: [0, 16]
- };
-
- /**
- * @element ons-switch
- * @category form
- * @description
- * [en]
- * Switch component. The switch can be toggled both by dragging and tapping.
- *
- * Will automatically displays a Material Design switch on Android devices.
- * [/en]
- * [ja]スイッチを表示するコンポーネントです。[/ja]
- * @modifier material
- * [en]Material Design switch[/en]
- * [ja][/ja]
- * @codepen LpXZQQ
- * @tutorial vanilla/Reference/switch
- * @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
- * @example
- * <ons-switch checked></ons-switch>
- * <ons-switch disabled></ons-switch>
- * <ons-switch modifier="material"></ons-switch>
- */
-
- var SwitchElement = function (_BaseCheckboxElement) {
- inherits(SwitchElement, _BaseCheckboxElement);
-
- function SwitchElement() {
- classCallCheck(this, SwitchElement);
-
- var _this = possibleConstructorReturn(this, (SwitchElement.__proto__ || Object.getPrototypeOf(SwitchElement)).call(this));
-
- contentReady(_this, function () {
- _this.attributeChangedCallback('modifier', null, _this.getAttribute('modifier'));
- });
-
- _this._onChange = _this._onChange.bind(_this);
- _this._onRelease = _this._onRelease.bind(_this);
- _this._lastTimeStamp = 0;
- return _this;
- }
-
- createClass(SwitchElement, [{
- key: '_getPosition',
-
-
- /* Own props */
-
- value: function _getPosition(e) {
- var l = this._locations;
- return Math.min(l[1], Math.max(l[0], this._startX + e.gesture.deltaX));
- }
- }, {
- key: '_emitChangeEvent',
- value: function _emitChangeEvent() {
- util$1.triggerElementEvent(this, 'change', {
- value: this.checked,
- switch: this,
- isInteractive: true
- });
- }
- }, {
- key: '_onChange',
- value: function _onChange(event) {
- if (event && event.stopPropagation) {
- event.stopPropagation();
- }
-
- this._emitChangeEvent();
- }
- }, {
- key: '_onClick',
- value: function _onClick(ev) {
- if (ev.target.classList.contains(this.defaultElementClass + '__touch') || ev.timeStamp - this._lastTimeStamp < 50 // Prevent second click triggered by <label>
- ) {
- ev.preventDefault();
- }
- this._lastTimeStamp = ev.timeStamp;
- }
- }, {
- key: '_onHold',
- value: function _onHold(e) {
- if (!this.disabled) {
- ModifierUtil.addModifier(this, 'active');
- document.addEventListener('release', this._onRelease);
- }
- }
- }, {
- key: '_onDragStart',
- value: function _onDragStart(e) {
- if (this.disabled || ['left', 'right'].indexOf(e.gesture.direction) === -1) {
- ModifierUtil.removeModifier(this, 'active');
- return;
- }
-
- e.consumed = true;
-
- ModifierUtil.addModifier(this, 'active');
- this._startX = this._locations[this.checked ? 1 : 0]; // - e.gesture.deltaX;
-
- this.addEventListener('drag', this._onDrag);
- document.addEventListener('release', this._onRelease);
- }
- }, {
- key: '_onDrag',
- value: function _onDrag(e) {
- e.stopPropagation();
- this._handle.style.left = this._getPosition(e) + 'px';
- }
- }, {
- key: '_onRelease',
- value: function _onRelease(e) {
- var l = this._locations;
- var position = this._getPosition(e);
- var previousValue = this.checked;
-
- this.checked = position >= (l[0] + l[1]) / 2;
-
- if (this.checked !== previousValue) {
- this._emitChangeEvent();
- }
-
- this.removeEventListener('drag', this._onDrag);
- document.removeEventListener('release', this._onRelease);
-
- this._handle.style.left = '';
- ModifierUtil.removeModifier(this, 'active');
- }
- }, {
- key: 'click',
- value: function click() {
- var ev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
-
- if (!this.disabled) {
- this.checked = !this.checked;
- this._emitChangeEvent();
- this._lastTimeStamp = ev.timeStamp || 0;
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- contentReady(this, function () {
- _this2._input.addEventListener('change', _this2._onChange);
- });
-
- this.addEventListener('dragstart', this._onDragStart);
- this.addEventListener('hold', this._onHold);
- this.addEventListener('tap', this.click);
- this.addEventListener('click', this._onClick);
- this._gestureDetector = new GestureDetector(this, { dragMinDistance: 1, holdTimeout: 251, passive: true });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- var _this3 = this;
-
- contentReady(this, function () {
- _this3._input.removeEventListener('change', _this3._onChange);
- });
-
- this.removeEventListener('dragstart', this._onDragStart);
- this.removeEventListener('hold', this._onHold);
- this.removeEventListener('tap', this.click);
- this.removeEventListener('click', this._onClick);
- if (this._gestureDetector) {
- this._gestureDetector.dispose();
- }
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'modifier') {
- var md = (current || '').indexOf('material') !== -1;
- this._locations = locations[md ? 'material' : 'ios'];
- }
-
- get(SwitchElement.prototype.__proto__ || Object.getPrototypeOf(SwitchElement.prototype), 'attributeChangedCallback', this).call(this, name, last, current);
- }
-
- /**
- * @event change
- * @description
- * [en]Fired when the switch is toggled.[/en]
- * [ja]ON/OFFが変わった時に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクト。[/ja]
- * @param {Object} event.switch
- * [en]Switch object.[/en]
- * [ja]イベントが発火したSwitchオブジェクトを返します。[/ja]
- * @param {Boolean} event.value
- * [en]Current value.[/en]
- * [ja]現在の値を返します。[/ja]
- * @param {Boolean} event.isInteractive
- * [en]True if the change was triggered by the user clicking on the switch.[/en]
- * [ja]タップやクリックなどのユーザの操作によって変わった場合にはtrueを返します。[/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the switch.[/en]
- * [ja]スイッチの表現を指定します。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Whether the switch is be disabled.[/en]
- * [ja]スイッチを無効の状態にする場合に指定します。[/ja]
- */
-
- /**
- * @attribute checked
- * @description
- * [en]Whether the switch is checked.[/en]
- * [ja]スイッチがONの状態にするときに指定します。[/ja]
- */
-
- /**
- * @attribute input-id
- * @type {String}
- * @description
- * [en]Specify the `id` attribute of the inner `<input>` element. This is useful when using `<label for="...">` elements.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property checked
- * @type {Boolean}
- * @description
- * [en]This value is `true` if the switch is checked.[/en]
- * [ja]スイッチがONの場合に`true`。[/ja]
- */
-
- /**
- * @property value
- * @type {String}
- * @description
- * [en]The current value of the input.[/en]
- * [ja][/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- /**
- * @property checkbox
- * @readonly
- * @type {HTMLElement}
- * @description
- * [en]The underlying checkbox element.[/en]
- * [ja]コンポーネント内部のcheckbox要素になります。[/ja]
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$28;
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'switch';
- }
- }, {
- key: '_template',
- get: function get$$1() {
- return '\n <input type="' + this.type + '" class="' + this._defaultClassName + '__input">\n <div class="' + this._defaultClassName + '__toggle">\n <div class="' + this._defaultClassName + '__handle">\n <div class="' + this._defaultClassName + '__touch"></div>\n </div>\n </div>\n ';
- }
- }, {
- key: 'type',
- get: function get$$1() {
- return 'checkbox';
- }
- }, {
- key: '_handle',
- get: function get$$1() {
- return this.querySelector('.' + this._defaultClassName + '__handle');
- }
- }, {
- key: 'checkbox',
- get: function get$$1() {
- return this._input;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return [].concat(toConsumableArray(get(SwitchElement.__proto__ || Object.getPrototypeOf(SwitchElement), 'observedAttributes', this)), ['modifier']);
- }
- }]);
- return SwitchElement;
- }(BaseCheckboxElement);
-
- onsElements.Switch = SwitchElement;
- customElements.define('ons-switch', SwitchElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$30 = {
- '.tabbar__content': 'tabbar--*__content',
- '.tabbar__border': 'tabbar--*__border',
- '.tabbar': 'tabbar--*'
- };
-
- var rewritables$3 = {
- /**
- * @param {Element} tabbarElement
- * @param {Function} callback
- */
- ready: function ready(tabbarElement, callback) {
- callback();
- }
- };
-
- var lerp = function lerp(x0, x1, t) {
- return (1 - t) * x0 + t * x1;
- };
-
- /**
- * @element ons-tabbar
- * @category tabbar
- * @description
- * [en]A component to display a tab bar on the bottom of a page. Used with `<ons-tab>` to manage pages using tabs.[/en]
- * [ja]タブバーをページ下部に表示するためのコンポーネントです。ons-tabと組み合わせて使うことで、ページを管理できます。[/ja]
- * @codepen pGuDL
- * @tutorial vanilla/Reference/tabbar
- * @modifier material
- * [en]A tabbar in Material Design.[/en]
- * [ja][/ja]
- * @modifier autogrow
- * [en]Tabs automatically grow depending on their content instead of having a fixed width.[/en]
- * [ja][/ja]
- * @modifier top-border
- * [en]Shows a static border-bottom in tabs for iOS top tabbars.[/en]
- * [ja][/ja]
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages.[/en]
- * [ja]複数のページを管理する[/ja]
- * @seealso ons-tab
- * [en]The `<ons-tab>` component.[/en]
- * [ja]ons-tabコンポーネント[/ja]
- * @seealso ons-page
- * [en]The `<ons-page>` component.[/en]
- * [ja]ons-pageコンポーネント[/ja]
- * @example
- * <ons-tabbar>
- * <ons-tab
- * page="home.html"
- * label="Home"
- * active>
- * </ons-tab>
- * <ons-tab
- * page="settings.html"
- * label="Settings"
- * active>
- * </ons-tab>
- * </ons-tabbar>
- *
- * <template id="home.html">
- * ...
- * </template>
- *
- * <template id="settings.html">
- * ...
- * </template>
- */
-
- var TabbarElement = function (_BaseElement) {
- inherits(TabbarElement, _BaseElement);
-
- /**
- * @event prechange
- * @description
- * [en]Fires just before the tab is changed.[/en]
- * [ja]アクティブなタブが変わる前に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクト。[/ja]
- * @param {Number} event.index
- * [en]Current index.[/en]
- * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
- * @param {Object} event.tabItem
- * [en]Tab item object.[/en]
- * [ja]tabItemオブジェクト。[/ja]
- * @param {Function} event.cancel
- * [en]Call this function to cancel the change event.[/en]
- * [ja]この関数を呼び出すと、アクティブなタブの変更がキャンセルされます。[/ja]
- */
-
- /**
- * @event postchange
- * @description
- * [en]Fires just after the tab is changed.[/en]
- * [ja]アクティブなタブが変わった後に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクト。[/ja]
- * @param {Number} event.index
- * [en]Current index.[/en]
- * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
- * @param {Object} event.tabItem
- * [en]Tab item object.[/en]
- * [ja]tabItemオブジェクト。[/ja]
- */
-
- /**
- * @event reactive
- * @description
- * [en]Fires if the already open tab is tapped again.[/en]
- * [ja]すでにアクティブになっているタブがもう一度タップやクリックされた場合に発火します。[/ja]
- * @param {Object} event
- * [en]Event object.[/en]
- * [ja]イベントオブジェクト。[/ja]
- * @param {Number} event.index
- * [en]Current index.[/en]
- * [ja]現在アクティブになっているons-tabのインデックスを返します。[/ja]
- * @param {Object} event.tabItem
- * [en]Tab item object.[/en]
- * [ja]tabItemオブジェクト。[/ja]
- */
-
- /**
- * @attribute animation
- * @type {String}
- * @default none
- * @description
- * [en]If this attribute is set to `"none"` the transitions will not be animated.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. {duration: 0.2, delay: 1, timing: 'ease-in'}[/ja]
- */
-
- /**
- * @attribute position
- * @initonly
- * @type {String}
- * @default bottom
- * @description
- * [en]Tabbar's position. Available values are `"bottom"` and `"top"`. Use `"auto"` to choose position depending on platform (bottom for iOS flat design, top for Material Design).[/en]
- * [ja]タブバーの位置を指定します。"bottom"もしくは"top"を選択できます。デフォルトは"bottom"です。[/ja]
- */
-
- /**
- * @attribute swipeable
- * @description
- * [en]If this attribute is set the tab bar can be scrolled by drag or swipe.[/en]
- * [ja]この属性がある時、タブバーをスワイプやドラッグで移動できるようになります。[/ja]
- */
-
- /**
- * @attribute ignore-edge-width
- * @type {Number}
- * @default 20
- * @description
- * [en]Distance in pixels from both edges. Swiping on these areas will prioritize parent components such as `ons-splitter` or `ons-navigator`.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute hide-tabs
- * @description
- * [en]Whether to hide the tabs.[/en]
- * [ja]タブを非表示にする場合に指定します。[/ja]
- */
-
- /**
- * @attribute tab-border
- * @description
- * [en]If this attribute is set the tabs show a dynamic bottom border. Only works for iOS flat design since the border is always visible in Material Design.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the tabbar.[/en]
- * [ja]タブバーの表現を指定します。[/ja]
- */
-
- function TabbarElement() {
- classCallCheck(this, TabbarElement);
-
- var _this = possibleConstructorReturn(this, (TabbarElement.__proto__ || Object.getPrototypeOf(TabbarElement)).call(this));
-
- _this._loadInactive = util$1.defer(); // Improves #2324
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(TabbarElement, [{
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this2 = this;
-
- if (!this._swiper) {
- this._swiper = new Swiper({
- getElement: function getElement() {
- return _this2._contentElement;
- },
- getInitialIndex: function getInitialIndex() {
- return _this2.getAttribute('activeIndex') || _this2.getAttribute('active-index');
- },
- getAutoScrollRatio: this._getAutoScrollRatio.bind(this),
- getBubbleWidth: function getBubbleWidth() {
- return parseInt(_this2.getAttribute('ignore-edge-width') || 25, 10);
- },
- isAutoScrollable: function isAutoScrollable() {
- return true;
- },
- preChangeHook: this._onPreChange.bind(this),
- postChangeHook: this._onPostChange.bind(this),
- refreshHook: this._onRefresh.bind(this),
- scrollHook: this._onScroll.bind(this)
- });
-
- contentReady(this, function () {
- _this2._tabbarBorder = util$1.findChild(_this2._tabbarElement, '.tabbar__border');
- _this2._swiper.init({ swipeable: _this2.hasAttribute('swipeable') });
- });
- }
-
- contentReady(this, function () {
- _this2._updatePosition();
-
- if (!util$1.findParent(_this2, 'ons-page', function (p) {
- return p === document.body;
- })) {
- _this2._show(); // This tabbar is the top component
- }
- });
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- if (this._swiper && this._swiper.initialized) {
- this._swiper.dispose();
- this._swiper = null;
- this._tabbarBorder = null;
- this._tabsRect = null;
- }
- }
- }, {
- key: '_normalizeEvent',
- value: function _normalizeEvent(event) {
- return _extends({}, event, { index: event.activeIndex, tabItem: this.tabs[event.activeIndex] });
- }
- }, {
- key: '_onPostChange',
- value: function _onPostChange(event) {
- event = this._normalizeEvent(event);
- util$1.triggerElementEvent(this, 'postchange', event);
- var page = event.tabItem.pageElement;
- page && page._show();
- }
- }, {
- key: '_onPreChange',
- value: function _onPreChange(event) {
- event = this._normalizeEvent(event);
- event.cancel = function () {
- return event.canceled = true;
- };
-
- util$1.triggerElementEvent(this, 'prechange', event);
-
- if (!event.canceled) {
- var _event = event,
- activeIndex = _event.activeIndex,
- lastActiveIndex = _event.lastActiveIndex;
-
- var tabs = this.tabs;
-
- tabs[activeIndex].setActive(true);
- if (lastActiveIndex >= 0) {
- var prevTab = tabs[lastActiveIndex];
- prevTab.setActive(false);
- prevTab.pageElement && prevTab.pageElement._hide();
- }
- }
-
- return event.canceled;
- }
- }, {
- key: '_onScroll',
- value: function _onScroll(index) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- if (this._tabbarBorder) {
- this._tabbarBorder.style.transition = 'all ' + (options.duration || 0) + 's ' + (options.timing || '');
-
- if (this._autogrow && this._tabsRect.length > 0) {
- var a = Math.floor(index),
- b = Math.ceil(index),
- r = index % 1;
- this._tabbarBorder.style.width = lerp(this._tabsRect[a].width, this._tabsRect[b].width, r) + 'px';
- this._tabbarBorder.style.transform = 'translate3d(' + lerp(this._tabsRect[a].left, this._tabsRect[b].left, r) + 'px, 0, 0)';
- } else {
- this._tabbarBorder.style.transform = 'translate3d(' + index * 100 + '%, 0, 0)';
- }
- }
-
- this._onSwipe && this._onSwipe(index, options);
- }
- }, {
- key: '_onRefresh',
- value: function _onRefresh() {
- this._autogrow = util$1.hasModifier(this, 'autogrow');
- this._tabsRect = this.tabs.map(function (tab) {
- return tab.getBoundingClientRect();
- });
- if (this._tabbarBorder) {
- this._tabbarBorder.style.display = this.hasAttribute('tab-border') || util$1.hasModifier(this, 'material') ? 'block' : 'none';
- var index = this.getActiveTabIndex();
- if (this._tabsRect.length > 0 && index >= 0) {
- this._tabbarBorder.style.width = this._tabsRect[index].width + 'px';
- }
- }
- }
- }, {
- key: '_getAutoScrollRatio',
- value: function _getAutoScrollRatio(matches, velocity, size) {
- var ratio = .6; // Base ratio
- var modifier = size / 300 * (matches ? -1 : 1); // Based on screen size
- return Math.min(1, Math.max(0, ratio + velocity * modifier));
- }
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- var content = this._contentElement || util$1.create('.tabbar__content');
- content.classList.add('ons-tabbar__content');
- var tabbar = this._tabbarElement || util$1.create('.tabbar');
- tabbar.classList.add('ons-tabbar__footer');
-
- if (!tabbar.parentNode) {
- while (this.firstChild) {
- tabbar.appendChild(this.firstChild);
- }
- }
-
- var activeIndex = Number(this.getAttribute('activeIndex')); // 0 by default
- if (tabbar.children.length > activeIndex && !util$1.findChild(tabbar, '[active]')) {
- tabbar.children[activeIndex].setAttribute('active', '');
- }
-
- this._tabbarBorder = util$1.findChild(tabbar, '.tabbar__border') || util$1.create('.tabbar__border');
- tabbar.appendChild(this._tabbarBorder);
- tabbar.classList.add('ons-swiper-tabbar'); // Hides material border
-
- !content.children[0] && content.appendChild(document.createElement('div'));
- !content.children[1] && content.appendChild(document.createElement('div'));
- content.appendChild = content.appendChild.bind(content.children[0]);
- content.insertBefore = content.insertBefore.bind(content.children[0]);
-
- this.appendChild(content);
- this.appendChild(tabbar); // Triggers ons-tab connectedCallback
-
- ModifierUtil.initModifier(this, scheme$30);
- }
- }, {
- key: '_updatePosition',
- value: function _updatePosition() {
- var _this3 = this;
-
- var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getAttribute('position');
-
- var top = this._top = position === 'top' || position === 'auto' && util$1.hasModifier(this, 'material');
- var action = top ? util$1.addModifier : util$1.removeModifier;
-
- action(this, 'top');
-
- var page = util$1.findParent(this, 'ons-page');
- if (page) {
- contentReady(page, function () {
- var p = 0;
- if (page.children[0] && util$1.match(page.children[0], 'ons-toolbar')) {
- action(page.children[0], 'noshadow');
- p = 1; // Visual fix for some devices
- }
-
- var content = page._getContentElement();
- var cs = window.getComputedStyle(page._getContentElement(), null);
-
- _this3.style.top = top ? parseInt(cs.getPropertyValue('padding-top'), 10) - p + 'px' : '';
-
- // Refresh content top - Fix for iOS 8
- content.style.top = cs.top;
- content.style.top = '';
- });
- }
-
- internal$1.autoStatusBarFill(function () {
- var filled = util$1.findParent(_this3, function (e) {
- return e.hasAttribute('status-bar-fill');
- });
- util$1.toggleAttribute(_this3, 'status-bar-fill', top && !filled);
- });
- }
- }, {
- key: 'setActiveTab',
-
-
- /**
- * @method setActiveTab
- * @signature setActiveTab(index, [options])
- * @param {Number} index
- * [en]Tab index.[/en]
- * [ja]タブのインデックスを指定します。[/ja]
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {Function} [options.callback]
- * [en]Function that runs when the new page has loaded.[/en]
- * [ja][/ja]
- * @param {String} [options.animation]
- * [en]If this option is "none", the transition won't slide.[/en]
- * [ja][/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @description
- * [en]Show specified tab page. Animations and their options can be specified by the second parameter.[/en]
- * [ja]指定したインデックスのタブを表示します。アニメーションなどのオプションを指定できます。[/ja]
- * @return {Promise}
- * [en]A promise that resolves to the new page element.[/en]
- * [ja][/ja]
- */
- value: function setActiveTab(nextIndex) {
- var _this4 = this;
-
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
-
- var prevIndex = this.getActiveTabIndex();
- var prevTab = this.tabs[prevIndex],
- nextTab = this.tabs[nextIndex];
-
- if (!nextTab) {
- return Promise.reject('Specified index does not match any tab.');
- }
-
- if (nextIndex === prevIndex) {
- util$1.triggerElementEvent(this, 'reactive', { index: nextIndex, activeIndex: nextIndex, tabItem: nextTab });
- return Promise.resolve(nextTab.pageElement);
- }
-
- // FIXME: nextTab.loaded is broken in Zone.js promises (Angular2)
- var nextPage = nextTab.pageElement;
- return (nextPage ? Promise.resolve(nextPage) : nextTab.loaded).then(function (nextPage) {
- return _this4._swiper.setActiveIndex(nextIndex, _extends({
- reject: true
- }, options, {
- animation: prevTab && nextPage ? options.animation || _this4.getAttribute('animation') : 'none',
- animationOptions: util$1.extend({ duration: .3, timing: 'cubic-bezier(.4, .7, .5, 1)' }, _this4.hasAttribute('animation-options') ? util$1.animationOptionsParse(_this4.getAttribute('animation-options')) : {}, options.animationOptions || {})
- })).then(function () {
- options.callback instanceof Function && options.callback(nextPage);
- return nextPage;
- });
- });
- }
-
- /**
- * @method setTabbarVisibility
- * @signature setTabbarVisibility(visible)
- * @param {Boolean} visible
- * @description
- * [en]Used to hide or show the tab bar.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'setTabbarVisibility',
- value: function setTabbarVisibility(visible) {
- var _this5 = this;
-
- contentReady(this, function () {
- _this5._contentElement.style[_this5._top ? 'top' : 'bottom'] = visible ? '' : '0px';
- _this5._tabbarElement.style.display = visible ? '' : 'none';
- visible && _this5._onRefresh();
- });
- }
- }, {
- key: 'show',
- value: function show() {
- this.setTabbarVisibility(true);
- }
- }, {
- key: 'hide',
- value: function hide() {
- this.setTabbarVisibility(false);
- }
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the tabbar is visible or not.[/en]
- * [ja]タブバーが見える場合に`true`。[/ja]
- */
-
- }, {
- key: 'getActiveTabIndex',
-
-
- /**
- * @method getActiveTabIndex
- * @signature getActiveTabIndex()
- * @return {Number}
- * [en]The index of the currently active tab.[/en]
- * [ja]現在アクティブになっているタブのインデックスを返します。[/ja]
- * @description
- * [en]Returns tab index on current active tab. If active tab is not found, returns -1.[/en]
- * [ja]現在アクティブになっているタブのインデックスを返します。現在アクティブなタブがない場合には-1を返します。[/ja]
- */
- value: function getActiveTabIndex() {
- var tabs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.tabs;
-
- for (var i = 0; i < tabs.length; i++) {
- if (tabs[i] && tabs[i].tagName === 'ONS-TAB' && tabs[i].isActive()) {
- return i;
- }
- }
- return -1;
- }
- }, {
- key: '_show',
- value: function _show() {
- var _this6 = this;
-
- this._swiper.show();
-
- setImmediate(function () {
- var tabs = _this6.tabs;
- var activeIndex = _this6.getActiveTabIndex(tabs);
- _this6._loadInactive.resolve();
- if (tabs.length > 0 && activeIndex >= 0) {
- tabs[activeIndex].loaded.then(function (el) {
- return el && setImmediate(function () {
- return el._show();
- });
- });
- }
- });
- }
- }, {
- key: '_hide',
- value: function _hide() {
- this._swiper.hide();
- var topPage = this.topPage;
- topPage && topPage._hide();
- }
- }, {
- key: '_destroy',
- value: function _destroy() {
- this.tabs.forEach(function (tab) {
- return tab.remove();
- });
- this.remove();
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- if (name === 'modifier') {
- ModifierUtil.onModifierChanged(last, current, this, scheme$30);
- var isTop = function isTop(m) {
- return (/(^|\s+)top($|\s+)/i.test(m)
- );
- };
- isTop(last) !== isTop(current) && this._updatePosition();
- } else if (name === 'position') {
- util$1.isAttached(this) && this._updatePosition();
- } else if (name === 'swipeable') {
- this._swiper && this._swiper.updateSwipeable(this.hasAttribute('swipeable'));
- } else if (name === 'hide-tabs') {
- this.setTabbarVisibility(!this.hasAttribute('hide-tabs') || current === 'false');
- }
- }
- }, {
- key: '_tabbarElement',
- get: function get$$1() {
- return util$1.findChild(this, '.tabbar');
- }
- }, {
- key: '_contentElement',
- get: function get$$1() {
- return util$1.findChild(this, '.tabbar__content');
- }
- }, {
- key: '_targetElement',
- get: function get$$1() {
- var content = this._contentElement;
- return content && content.children[0] || null;
- }
- }, {
- key: 'topPage',
- get: function get$$1() {
- var tabs = this.tabs,
- index = this.getActiveTabIndex();
- return tabs[index] ? tabs[index].pageElement || this.pages[0] || null : null;
- }
- }, {
- key: 'pages',
- get: function get$$1() {
- return util$1.arrayFrom(this._targetElement.children);
- }
- }, {
- key: 'tabs',
- get: function get$$1() {
- return Array.prototype.filter.call(this._tabbarElement.children, function (e) {
- return e.tagName === 'ONS-TAB';
- });
- }
- }, {
- key: 'visible',
- get: function get$$1() {
- return this._tabbarElement.style.display !== 'none';
- }
-
- /**
- * @property swipeable
- * @type {Boolean}
- * @description
- * [en]Enable swipe interaction.[/en]
- * [ja]swipeableであればtrueを返します。[/ja]
- */
-
- }, {
- key: 'swipeable',
- get: function get$$1() {
- return this.hasAttribute('swipeable');
- },
- set: function set$$1(value) {
- return util$1.toggleAttribute(this, 'swipeable', value);
- }
-
- /**
- * @property onSwipe
- * @type {Function}
- * @description
- * [en]Hook called whenever the user slides the tabbar. It gets a decimal index and an animationOptions object as arguments.[/en]
- * [ja][/ja]
- */
-
- }, {
- key: 'onSwipe',
- get: function get$$1() {
- return this._onSwipe;
- },
- set: function set$$1(value) {
- if (value && !(value instanceof Function)) {
- util$1.throw('"onSwipe" must be a function');
- }
- this._onSwipe = value;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'position', 'swipeable', 'tab-border', 'hide-tabs'];
- }
- }, {
- key: 'rewritables',
- get: function get$$1() {
- return rewritables$3;
- }
- }, {
- key: 'events',
- get: function get$$1() {
- return ['prechange', 'postchange', 'reactive'];
- }
- }]);
- return TabbarElement;
- }(BaseElement);
-
- onsElements.Tabbar = TabbarElement;
- customElements.define('ons-tabbar', TabbarElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var defaultClassName$16 = 'tabbar__item';
-
- var scheme$29 = {
- '': 'tabbar--*__item',
- '.tabbar__button': 'tabbar--*__button'
- };
-
- /**
- * @element ons-tab
- * @category tabbar
- * @description
- * [en]Represents a tab inside tab bar. Each `<ons-tab>` represents a page.[/en]
- * [ja]
- * タブバーに配置される各アイテムのコンポーネントです。それぞれのons-tabはページを表します。
- * ons-tab要素の中には、タブに表示されるコンテンツを直接記述することが出来ます。
- * [/ja]
- * @codepen pGuDL
- * @tutorial vanilla/Reference/tabbar
- * @guide fundamentals.html#managing-pages
- * [en]Managing multiple pages.[/en]
- * [ja]複数のページを管理する[/ja]]
- * @guide appsize.html#removing-icon-packs [en]Removing icon packs.[/en][ja][/ja]
- * @guide faq.html#how-can-i-use-custom-icon-packs [en]Adding custom icon packs.[/en][ja][/ja]
- * @seealso ons-tabbar
- * [en]ons-tabbar component[/en]
- * [ja]ons-tabbarコンポーネント[/ja]
- * @seealso ons-page
- * [en]ons-page component[/en]
- * [ja]ons-pageコンポーネント[/ja]
- * @seealso ons-icon
- * [en]ons-icon component[/en]
- * [ja]ons-iconコンポーネント[/ja]
- * @example
- * <ons-tabbar>
- * <ons-tab
- * page="home.html"
- * label="Home"
- * active>
- * </ons-tab>
- * <ons-tab
- * page="settings.html"
- * label="Settings"
- * active>
- * </ons-tab>
- * </ons-tabbar>
- *
- * <template id="home.html">
- * ...
- * </template>
- *
- * <template id="settings.html">
- * ...
- * </template>
-
- */
-
- var TabElement = function (_BaseElement) {
- inherits(TabElement, _BaseElement);
-
- /**
- * @attribute page
- * @initonly
- * @type {String}
- * @description
- * [en]The page that is displayed when the tab is tapped.[/en]
- * [ja]ons-tabが参照するページへのURLを指定します。[/ja]
- */
-
- /**
- * @attribute icon
- * @type {String}
- * @description
- * [en]
- * The icon name for the tab. Can specify the same icon name as `<ons-icon>`. Check [See also](#seealso) section for more information.
- * [/en]
- * [ja]
- * アイコン名を指定します。ons-iconと同じアイコン名を指定できます。
- * 個別にアイコンをカスタマイズする場合は、background-imageなどのCSSスタイルを用いて指定できます。
- * [/ja]
- */
-
- /**
- * @attribute active-icon
- * @type {String}
- * @description
- * [en]The name of the icon when the tab is active.[/en]
- * [ja]アクティブの際のアイコン名を指定します。[/ja]
- */
-
- /**
- * @attribute label
- * @type {String}
- * @description
- * [en]The label of the tab item.[/en]
- * [ja]アイコン下に表示されるラベルを指定します。[/ja]
- */
-
- /**
- * @attribute badge
- * @type {String}
- * @description
- * [en]Display a notification badge on top of the tab.[/en]
- * [ja]バッジに表示する内容を指定します。[/ja]
- */
-
- /**
- * @attribute active
- * @description
- * [en]This attribute should be set to the tab that is active by default.[/en]
- * [ja][/ja]
- */
-
- function TabElement() {
- classCallCheck(this, TabElement);
-
- var _this = possibleConstructorReturn(this, (TabElement.__proto__ || Object.getPrototypeOf(TabElement)).call(this));
-
- if (['label', 'icon', 'badge'].some(_this.hasAttribute.bind(_this))) {
- _this._compile();
- } else {
- contentReady(_this, function () {
- return _this._compile();
- });
- }
-
- _this._pageLoader = defaultPageLoader;
- _this._onClick = _this._onClick.bind(_this);
- return _this;
- }
-
- createClass(TabElement, [{
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
- this.classList.add(defaultClassName$16);
-
- if (this._button) {
- return;
- }
-
- var button = util$1.create('button.tabbar__button');
- while (this.childNodes[0]) {
- button.appendChild(this.childNodes[0]);
- }
-
- var input = util$1.create('input', { display: 'none' });
- input.type = 'radio';
-
- this.appendChild(input);
- this.appendChild(button);
-
- this._updateButtonContent();
- ModifierUtil.initModifier(this, scheme$29);
- this._updateRipple();
- }
- }, {
- key: '_updateRipple',
- value: function _updateRipple() {
- this._button && util$1.updateRipple(this._button, this.hasAttribute('ripple'));
- }
- }, {
- key: '_updateButtonContent',
- value: function _updateButtonContent() {
- var _this2 = this;
-
- var button = this._button;
-
- var iconWrapper = this._icon;
- if (this.hasAttribute('icon')) {
- iconWrapper = iconWrapper || util$1.createElement('<div class="tabbar__icon"><ons-icon></ons-icon></div>');
- var icon = iconWrapper.children[0];
- var fix = function (last) {
- return function () {
- return icon.attributeChangedCallback('icon', last, _this2.getAttribute('icon'));
- };
- }(icon.getAttribute('icon'));
- icon.setAttribute('icon', this.getAttribute('icon'));
- iconWrapper.parentElement !== button && button.insertBefore(iconWrapper, button.firstChild);
-
- // dirty fix for https://github.com/OnsenUI/OnsenUI/issues/1654
- icon.attributeChangedCallback instanceof Function ? fix() : setImmediate(function () {
- return icon.attributeChangedCallback instanceof Function && fix();
- });
- } else {
- iconWrapper && iconWrapper.remove();
- }
-
- ['label', 'badge'].forEach(function (attr, index) {
- var prop = _this2.querySelector('.tabbar__' + attr);
- if (_this2.hasAttribute(attr)) {
- prop = prop || util$1.create('.tabbar__' + attr + (attr === 'badge' ? ' notification' : ''));
- prop.textContent = _this2.getAttribute(attr);
- prop.parentElement !== button && button.appendChild(prop);
- } else {
- prop && prop.remove();
- }
- });
- }
- }, {
- key: '_onClick',
- value: function _onClick() {
- if (this.onClick instanceof Function) {
- this.onClick();
- } else {
- this._tabbar.setActiveTab(this.index, { reject: false });
- }
- }
- }, {
- key: 'setActive',
- value: function setActive() {
- var active = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
-
- this._input.checked = active;
- this.classList.toggle('active', active);
- util$1.toggleAttribute(this, 'active', active);
-
- if (this.hasAttribute('icon') && this.hasAttribute('active-icon')) {
- this._icon.children[0].setAttribute('icon', this.getAttribute(active ? 'active-icon' : 'icon'));
- }
- }
- }, {
- key: '_loadPageElement',
- value: function _loadPageElement(parent, page) {
- var _this3 = this;
-
- this._hasLoaded = true;
-
- return new Promise(function (resolve) {
- _this3._pageLoader.load({ parent: parent, page: page }, function (pageElement) {
- parent.replaceChild(pageElement, parent.children[_this3.index]); // Ensure position
- _this3._loadedPage = pageElement;
- resolve(pageElement);
- });
- });
- }
- }, {
- key: 'isActive',
-
-
- /**
- * @return {Boolean}
- */
- value: function isActive() {
- return this.classList.contains('active');
- }
- }, {
- key: 'disconnectedCallback',
- value: function disconnectedCallback() {
- this.removeEventListener('click', this._onClick, false);
- if (this._loadedPage) {
- this._hasLoaded = false;
- this.loaded = null;
- }
- }
- }, {
- key: 'connectedCallback',
- value: function connectedCallback() {
- var _this4 = this;
-
- this.addEventListener('click', this._onClick, false);
-
- if (!util$1.isAttached(this) || this.loaded) {
- return; // ons-tabbar compilation may trigger this
- }
-
- var deferred = util$1.defer();
- this.loaded = deferred.promise;
-
- contentReady(this, function () {
- var index = _this4.index;
- var tabbar = _this4._tabbar;
- if (!tabbar) {
- util$1.throw('Tab elements must be children of Tabbar');
- }
-
- if (tabbar.hasAttribute('modifier')) {
- util$1.addModifier(_this4, tabbar.getAttribute('modifier'));
- }
-
- if (!_this4._hasLoaded) {
- if (_this4.hasAttribute('active')) {
- _this4.setActive(true);
- tabbar.setAttribute('activeIndex', index);
- }
-
- if (index === tabbar.tabs.length - 1) {
- tabbar._onRefresh();
- setImmediate(function () {
- return tabbar._onRefresh();
- });
- }
-
- TabbarElement.rewritables.ready(tabbar, function () {
- var pageTarget = _this4.page || _this4.getAttribute('page');
- if (!_this4.pageElement && pageTarget) {
- var parentTarget = tabbar._targetElement;
- var dummyPage = util$1.create('div', { height: '100%', width: '100%', visibility: 'hidden' });
- parentTarget.insertBefore(dummyPage, parentTarget.children[index]); // Ensure position
-
- var load = function load() {
- return _this4._loadPageElement(parentTarget, pageTarget).then(deferred.resolve);
- };
- return _this4.isActive() ? load() : tabbar._loadInactive.promise.then(load);
- }
-
- return deferred.resolve(_this4.pageElement);
- });
- }
- });
- }
- }, {
- key: 'attributeChangedCallback',
- value: function attributeChangedCallback(name, last, current) {
- var _this5 = this;
-
- switch (name) {
- case 'class':
- util$1.restoreClass(this, defaultClassName$16, scheme$29);
- break;
- case 'modifier':
- contentReady(this, function () {
- return ModifierUtil.onModifierChanged(last, current, _this5, scheme$29);
- });
- break;
- case 'ripple':
- contentReady(this, function () {
- return _this5._updateRipple();
- });
- break;
- case 'icon':
- case 'label':
- case 'badge':
- contentReady(this, function () {
- return _this5._updateButtonContent();
- });
- break;
- case 'page':
- this.page = current || '';
- break;
- }
- }
- }, {
- key: 'pageLoader',
- set: function set$$1(loader) {
- if (!(loader instanceof PageLoader)) {
- util$1.throwPageLoader();
- }
- this._pageLoader = loader;
- },
- get: function get$$1() {
- return this._pageLoader;
- }
- }, {
- key: '_input',
- get: function get$$1() {
- return util$1.findChild(this, 'input');
- }
- }, {
- key: '_button',
- get: function get$$1() {
- return util$1.findChild(this, '.tabbar__button');
- }
- }, {
- key: '_icon',
- get: function get$$1() {
- return this.querySelector('.tabbar__icon');
- }
- }, {
- key: '_tabbar',
- get: function get$$1() {
- return util$1.findParent(this, 'ons-tabbar');
- }
- }, {
- key: 'index',
- get: function get$$1() {
- return Array.prototype.indexOf.call(this.parentElement.children, this);
- }
- }, {
- key: 'pageElement',
- get: function get$$1() {
- // It has been loaded by ons-tab
- if (this._loadedPage) {
- return this._loadedPage;
- }
- // Manually attached to DOM, 1 per tab
- var tabbar = this._tabbar;
- if (tabbar.pages.length === tabbar.tabs.length) {
- return tabbar.pages[this.index];
- }
- // Loaded in another way
- return null;
- }
- }], [{
- key: 'observedAttributes',
- get: function get$$1() {
- return ['modifier', 'ripple', 'icon', 'label', 'page', 'badge', 'class'];
- }
- }]);
- return TabElement;
- }(BaseElement);
-
- onsElements.Tab = TabElement;
- customElements.define('ons-tab', TabElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var ToastAnimator = function (_BaseAnimator) {
- inherits(ToastAnimator, _BaseAnimator);
-
- /**
- * @param {Object} options
- * @param {String} options.timing
- * @param {Number} options.duration
- * @param {Number} options.delay
- */
- function ToastAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.2 : _ref$duration;
-
- classCallCheck(this, ToastAnimator);
- return possibleConstructorReturn(this, (ToastAnimator.__proto__ || Object.getPrototypeOf(ToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
-
- createClass(ToastAnimator, [{
- key: 'show',
- value: function show(modal, callback) {
- callback();
- }
-
- /**
- * @param {HTMLElement} modal
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(modal, callback) {
- callback();
- }
- }]);
- return ToastAnimator;
- }(BaseAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * iOS style animator for dialog.
- */
-
- var FadeToastAnimator = function (_ToastAnimator) {
- inherits(FadeToastAnimator, _ToastAnimator);
-
- function FadeToastAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'linear' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.3 : _ref$duration;
-
- classCallCheck(this, FadeToastAnimator);
- return possibleConstructorReturn(this, (FadeToastAnimator.__proto__ || Object.getPrototypeOf(FadeToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
-
- createClass(FadeToastAnimator, [{
- key: 'show',
- value: function show(toast, callback) {
- callback = callback ? callback : function () {};
-
- Animit(toast, this.def).default({ opacity: 0 }, { opacity: 1 }).queue(function (done) {
- callback();
- done();
- }).play();
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(toast, callback) {
- callback = callback ? callback : function () {};
-
- Animit(toast, this.def).default({ opacity: 1 }, { opacity: 0 }).queue(function (done) {
- callback();
- done();
- }).play();
- }
- }]);
- return FadeToastAnimator;
- }(ToastAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Ascend Toast Animator.
- */
-
- var AscendToastAnimator = function (_ToastAnimator) {
- inherits(AscendToastAnimator, _ToastAnimator);
-
- function AscendToastAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'ease' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.25 : _ref$duration;
-
- classCallCheck(this, AscendToastAnimator);
-
- var _this = possibleConstructorReturn(this, (AscendToastAnimator.__proto__ || Object.getPrototypeOf(AscendToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this.messageDelay = _this.duration * 0.4 + _this.delay; // Delay message opacity change
- if (platform.isAndroid()) {
- _this.ascension = 48; // Toasts are always 1 line
- } else {
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- _this.ascension = 98; // 64 + 34
- } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
- _this.ascension = 85; // 64 + 21
- } else {
- _this.ascension = 64;
- }
- }
- return _this;
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
-
- createClass(AscendToastAnimator, [{
- key: 'show',
- value: function show(toast, callback) {
- toast = toast._toast;
- util$1.globals.fabOffset = this.ascension;
-
- Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, ' + this.ascension + 'px, 0)' }, { transform: 'translate3d(0, 0, 0)' }).queue(function (done) {
- callback && callback();
- done();
- }), Animit(this._getFabs()).wait(this.delay).queue({ transform: 'translate3d(0, -' + this.ascension + 'px, 0) scale(1)' }, this.def), Animit(util$1.arrayFrom(toast.children), this.def).default({ opacity: 0 }, { opacity: 1 }));
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(toast, callback) {
- toast = toast._toast;
- util$1.globals.fabOffset = 0;
-
- Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, 0, 0)' }, { transform: 'translate3d(0, ' + this.ascension + 'px, 0)' }).queue(function (done) {
- callback && callback();
- done();
- }), Animit(this._getFabs(), this.def).wait(this.delay).queue({ transform: 'translate3d(0, 0, 0) scale(1)' }, this.def), Animit(util$1.arrayFrom(toast.children), this.def).default({ opacity: 1 }, { opacity: 0 }));
- }
- }, {
- key: '_getFabs',
- value: function _getFabs() {
- return util$1.arrayFrom(document.querySelectorAll('ons-fab[position~=bottom], ons-speed-dial[position~=bottom]')).filter(function (fab) {
- return fab.visible;
- });
- }
- }]);
- return AscendToastAnimator;
- }(ToastAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Lift-fade Toast Animator
- */
-
- var LiftToastAnimator = function (_ToastAnimator) {
- inherits(LiftToastAnimator, _ToastAnimator);
-
- function LiftToastAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'ease' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.35 : _ref$duration;
-
- classCallCheck(this, LiftToastAnimator);
-
- var _this = possibleConstructorReturn(this, (LiftToastAnimator.__proto__ || Object.getPrototypeOf(LiftToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- _this.bodyHeight = document.body.clientHeight; // avoid Forced Synchronous Layout
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- _this.liftAmount = 'calc(100% + 34px)';
- } else if (iPhoneXPatch.isIPhoneXLandscapePatchActive()) {
- _this.liftAmount = 'calc(100% + 21px)';
- } else {
- _this.liftAmount = '100%';
- }
- return _this;
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
-
- createClass(LiftToastAnimator, [{
- key: 'show',
- value: function show(toast, callback) {
- toast = toast._toast;
-
- Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, ' + this.liftAmount + ', 0)', opacity: 0 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(toast, callback) {
- toast = toast._toast;
-
- Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 1 }, { transform: 'translate3d(0, ' + this.liftAmount + ', 0)', opacity: 0 }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
- }, {
- key: '_updatePosition',
- value: function _updatePosition(toast) {
- if (parseInt(toast.style.top, 10) === 0) {
- toast.style.top = toast.style.bottom = '';
- }
- }
- }]);
- return LiftToastAnimator;
- }(ToastAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * Fall-fade Toast Animator
- */
-
- var FallToastAnimator = function (_ToastAnimator) {
- inherits(FallToastAnimator, _ToastAnimator);
-
- function FallToastAnimator() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- _ref$timing = _ref.timing,
- timing = _ref$timing === undefined ? 'ease' : _ref$timing,
- _ref$delay = _ref.delay,
- delay = _ref$delay === undefined ? 0 : _ref$delay,
- _ref$duration = _ref.duration,
- duration = _ref$duration === undefined ? 0.35 : _ref$duration;
-
- classCallCheck(this, FallToastAnimator);
-
- var _this = possibleConstructorReturn(this, (FallToastAnimator.__proto__ || Object.getPrototypeOf(FallToastAnimator)).call(this, { timing: timing, delay: delay, duration: duration }));
-
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- _this.fallAmount = 'calc(-100% - 44px)';
- } else {
- _this.fallAmount = '-100%';
- }
- return _this;
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
-
- createClass(FallToastAnimator, [{
- key: 'show',
- value: function show(toast, callback) {
- toast = toast._toast;
- this._updatePosition(toast);
-
- Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, ' + this.fallAmount + ', 0)', opacity: 0 }, { transform: 'translate3d(0, 0, 0)', opacity: 1 }).queue(function (done) {
- callback && callback();
- done();
- }));
- }
-
- /**
- * @param {HTMLElement} toast
- * @param {Function} callback
- */
-
- }, {
- key: 'hide',
- value: function hide(toast, callback) {
- var _this2 = this;
-
- toast = toast._toast;
- this._updatePosition(toast);
-
- Animit.runAll(Animit(toast, this.def).default({ transform: 'translate3d(0, 0, 0)', opacity: 1 }, { transform: 'translate3d(0, ' + this.fallAmount + ', 0)', opacity: 0 }).queue(function (done) {
- _this2._updatePosition(toast, true);
- callback && callback();
- done();
- }));
- }
- }, {
- key: '_updatePosition',
- value: function _updatePosition(toast, cleanUp) {
- var correctTop = void 0;
- if (iPhoneXPatch.isIPhoneXPortraitPatchActive()) {
- correctTop = '44px';
- } else {
- correctTop = '0';
- }
-
- if (toast.style.top !== correctTop) {
- toast.style.top = correctTop;
- toast.style.bottom = 'initial';
- }
- }
- }]);
- return FallToastAnimator;
- }(ToastAnimator);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- var scheme$31 = {
- '.toast': 'toast--*',
- '.toast__message': 'toast--*__message',
- '.toast__button': 'toast--*__button'
- };
-
- var defaultClassName$17 = 'toast';
-
- var _animatorDict$8 = {
- 'default': platform.isAndroid() ? AscendToastAnimator : LiftToastAnimator,
- 'fade': FadeToastAnimator,
- 'ascend': AscendToastAnimator,
- 'lift': LiftToastAnimator,
- 'fall': FallToastAnimator,
- 'none': ToastAnimator
- };
-
- /**
- * @element ons-toast
- * @category dialog
- * @description
- * [en]
- * The Toast or Snackbar component is useful for displaying dismissable information or simple actions at (normally) the bottom of the page.
- *
- * This component does not block user input, allowing the app to continue its flow. For simple toasts, consider `ons.notification.toast` instead.
- * [/en]
- * [ja][/ja]
- * @tutorial vanilla/Reference/toast
- * @seealso ons-alert-dialog
- * [en]The `<ons-alert-dialog>` component is preferred for displaying undismissable information.[/en]
- * [ja][/ja]
- */
-
- var ToastElement = function (_BaseDialogElement) {
- inherits(ToastElement, _BaseDialogElement);
-
- /**
- * @attribute animation
- * @type {String}
- * @default default
- * @description
- * [en]The animation used when showing and hiding the toast. Can be either `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
- * [ja][/ja]
- */
-
- /**
- * @attribute animation-options
- * @type {Expression}
- * @description
- * [en]Specify the animation's duration, timing and delay with an object literal. E.g. `{duration: 0.2, delay: 1, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, timing, delayをオブジェクトリテラルで指定します。e.g. <code>{duration: 0.2, delay: 1, timing: 'ease-in'}</code>[/ja]
- */
-
- function ToastElement() {
- classCallCheck(this, ToastElement);
-
- var _this = possibleConstructorReturn(this, (ToastElement.__proto__ || Object.getPrototypeOf(ToastElement)).call(this));
-
- _this._defaultDBB = null;
- contentReady(_this, function () {
- return _this._compile();
- });
- return _this;
- }
-
- createClass(ToastElement, [{
- key: '_updateAnimatorFactory',
- value: function _updateAnimatorFactory() {
- // Reset position style
- this._toast && (this._toast.style.top = this._toast.style.bottom = '');
-
- return new AnimatorFactory({
- animators: _animatorDict$8,
- baseClass: ToastAnimator,
- baseClassName: 'ToastAnimator',
- defaultAnimation: this.getAttribute('animation')
- });
- }
-
- /**
- * @property onDeviceBackButton
- * @type {Object}
- * @description
- * [en]Back-button handler.[/en]
- * [ja]バックボタンハンドラ。[/ja]
- */
-
- }, {
- key: '_compile',
- value: function _compile() {
- autoStyle.prepare(this);
-
- this.style.display = 'none';
- this.style.zIndex = 10000; // Lower than dialogs
-
- var messageClassName = 'toast__message';
- var buttonClassName = 'toast__button';
-
- var toast = util$1.findChild(this, '.' + defaultClassName$17);
- if (!toast) {
- toast = document.createElement('div');
- toast.classList.add(defaultClassName$17);
- while (this.childNodes[0]) {
- toast.appendChild(this.childNodes[0]);
- }
- }
-
- var button = util$1.findChild(toast, '.' + buttonClassName);
- if (!button) {
- button = util$1.findChild(toast, function (e) {
- return util$1.match(e, '.button') || util$1.match(e, 'button');
- });
- if (button) {
- button.classList.remove('button');
- button.classList.add(buttonClassName);
- toast.appendChild(button);
- }
- }
-
- if (!util$1.findChild(toast, '.' + messageClassName)) {
- var message = util$1.findChild(toast, '.message');
- if (!message) {
- message = document.createElement('div');
- for (var i = toast.childNodes.length - 1; i >= 0; i--) {
- if (toast.childNodes[i] !== button) {
- message.insertBefore(toast.childNodes[i], message.firstChild);
- }
- }
- }
- message.classList.add(messageClassName);
-
- toast.insertBefore(message, toast.firstChild);
- }
-
- if (toast.parentNode !== this) {
- this.appendChild(toast);
- }
-
- ModifierUtil.initModifier(this, this._scheme);
- }
-
- /**
- * @property visible
- * @readonly
- * @type {Boolean}
- * @description
- * [en]Whether the element is visible or not.[/en]
- * [ja]要素が見える場合に`true`。[/ja]
- */
-
- /**
- * @method show
- * @signature show([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
- * [ja][/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @description
- * [en]Show the element.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the displayed element[/en]
- * [ja][/ja]
- */
-
- /**
- * @method toggle
- * @signature toggle([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
- * [ja][/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @description
- * [en]Toggle toast visibility.[/en]
- * [ja][/ja]
- */
-
- /**
- * @method hide
- * @signature hide([options])
- * @param {Object} [options]
- * [en]Parameter object.[/en]
- * [ja]オプションを指定するオブジェクト。[/ja]
- * @param {String} [options.animation]
- * [en]Animation name. Available animations are `"default"`, `"ascend"` (Android), `"lift"` (iOS), `"fall"`, `"fade"` or `"none"`.[/en]
- * [ja][/ja]
- * @param {String} [options.animationOptions]
- * [en]Specify the animation's duration, delay and timing. E.g. `{duration: 0.2, delay: 0.4, timing: 'ease-in'}`.[/en]
- * [ja]アニメーション時のduration, delay, timingを指定します。e.g. {duration: 0.2, delay: 0.4, timing: 'ease-in'}[/ja]
- * @description
- * [en]Hide toast.[/en]
- * [ja][/ja]
- * @return {Promise}
- * [en]Resolves to the hidden element[/en]
- * [ja][/ja]
- */
-
- /**
- * @param {String} name
- * @param {Function} Animator
- */
-
- }, {
- key: '_scheme',
- get: function get$$1() {
- return scheme$31;
- }
- }, {
- key: '_toast',
- get: function get$$1() {
- return util$1.findChild(this, '.' + defaultClassName$17);
- }
- }], [{
- key: 'registerAnimator',
- value: function registerAnimator(name, Animator) {
- if (!(Animator.prototype instanceof ToastAnimator)) {
- util$1.throw('"Animator" param must inherit OnsToastElement.ToastAnimator');
- }
- _animatorDict$8[name] = Animator;
- }
- }, {
- key: 'animators',
- get: function get$$1() {
- return _animatorDict$8;
- }
- }, {
- key: 'ToastAnimator',
- get: function get$$1() {
- return ToastAnimator;
- }
- }]);
- return ToastElement;
- }(BaseDialogElement);
-
- onsElements.Toast = ToastElement;
- customElements.define('ons-toast', ToastElement);
-
- /*
- Copyright 2013-2015 ASIAL CORPORATION
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
- /**
- * @element ons-toolbar-button
- * @category page
- * @modifier material
- * [en]Material Design toolbar button.[/en]
- * [ja][/ja]
- * @modifier outline
- * [en]A button with an outline.[/en]
- * [ja]アウトラインをもったボタンを表示します。[/ja]
- * @description
- * [en]Button component for ons-toolbar and ons-bottom-toolbar.[/en]
- * [ja]ons-toolbarあるいはons-bottom-toolbarに設置できるボタン用コンポーネントです。[/ja]
- * @codepen aHmGL
- * @tutorial vanilla/Reference/page
- * @guide compilation.html#toolbar-compilation
- * [en]Adding a toolbar[/en]
- * [ja]ツールバーの追加[/ja]
- * @seealso ons-toolbar
- * [en]The `<ons-toolbar>` component displays a navigation bar at the top of a page.[/en]
- * [ja]ons-toolbarコンポーネント[/ja]
- * @seealso ons-back-button
- * [en]The `<ons-back-button>` displays a back button in the navigation bar.[/en]
- * [ja]ons-back-buttonコンポーネント[/ja]
- * @example
- * <ons-toolbar>
- * <div class="left">
- * <ons-toolbar-button>
- * Button
- * </ons-toolbar-button>
- * </div>
- * <div class="center">
- * Title
- * </div>
- * <div class="right">
- * <ons-toolbar-button>
- * <ons-icon icon="ion-navicon" size="28px"></ons-icon>
- * </ons-toolbar-button>
- * </div>
- * </ons-toolbar>
- */
-
- var ToolbarButtonElement = function (_BaseButtonElement) {
- inherits(ToolbarButtonElement, _BaseButtonElement);
-
- function ToolbarButtonElement() {
- classCallCheck(this, ToolbarButtonElement);
- return possibleConstructorReturn(this, (ToolbarButtonElement.__proto__ || Object.getPrototypeOf(ToolbarButtonElement)).apply(this, arguments));
- }
-
- createClass(ToolbarButtonElement, [{
- key: '_scheme',
-
-
- /**
- * @attribute modifier
- * @type {String}
- * @description
- * [en]The appearance of the button.[/en]
- * [ja]ボタンの表現を指定します。[/ja]
- */
-
- /**
- * @attribute icon
- * @type {String}
- * @description
- * [en]Creates an `ons-icon` component with this string.[/en]
- * [ja]`ons-icon`コンポーネントを悪性します。[/ja]
- */
-
- /**
- * @attribute disabled
- * @description
- * [en]Specify if button should be disabled.[/en]
- * [ja]ボタンを無効化する場合は指定してください。[/ja]
- */
-
- /**
- * @property disabled
- * @type {Boolean}
- * @description
- * [en]Whether the element is disabled or not.[/en]
- * [ja]無効化されている場合に`true`。[/ja]
- */
-
- get: function get$$1() {
- return { '': 'toolbar-button--*' };
- }
- }, {
- key: '_defaultClassName',
- get: function get$$1() {
- return 'toolbar-button';
- }
- }, {
- key: '_rippleOpt',
- get: function get$$1() {
- return [this, undefined, { center: '', 'size': 'contain', 'background': 'transparent' }];
- }
- }]);
- return ToolbarButtonElement;
- }(BaseButtonElement);
-
- onsElements.ToolbarButton = ToolbarButtonElement;
- customElements.define('ons-toolbar-button', ToolbarButtonElement);
-
- // Add and register Custom Elements
- setup$1(ons$1); // Setup initial listeners
- window._superSecretOns = ons$1;
-
- return ons$1;
-
- })));
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25zZW51aS5qcyIsInNvdXJjZXMiOlsiLi4vLi4vY29yZS9zcmMvb25zL2VsZW1lbnRzLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL3N0eWxlci5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9wbGF0Zm9ybS5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9wYWdlLWF0dHJpYnV0ZS1leHByZXNzaW9uLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2ludGVybmFsL2ludGVybmFsLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnkuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYXV0b3N0eWxlLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvZGV2aWNlLWJhY2stYnV0dG9uLWRpc3BhdGNoZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYW5pbWF0aW9uLW9wdGlvbnMtcGFyc2VyLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL3V0aWwuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYW5pbWl0LmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2dlc3R1cmUtZGV0ZWN0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvY29udGVudC1yZWFkeS5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9pbnRlcm5hbC90b2FzdC1xdWV1ZS5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9ub3RpZmljYXRpb24uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvYWN0aW9uLXNoZWV0LmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL21pY3JvZXZlbnQuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvb3JpZW50YXRpb24uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvbW9kaWZpZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvc29mdHdhcmUta2V5Ym9hcmQuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvZG9vcmxvY2suanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvcGFnZS1sb2FkZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW5kZXguanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvZmFzdGNsaWNrL2xpYi9mYXN0Y2xpY2suanMiLCIuLi8uLi9jb3JlL3NyYy9wb2x5ZmlsbHMvcG9seWZpbGwtc3dpdGNoZXMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb3BlcnR5LWRlc2MuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lvYmplY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BkLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNldC1wcm90b3R5cGUtb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9vYmplY3Qvc2V0LXByb3RvdHlwZS1vZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3drcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2xpYnJhcnkuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyYXRvcnMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1sZW5ndGguanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1hYnNvbHV0ZS1pbmRleC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWluY2x1ZGVzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2hhcmVkLWtleS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2h0bWwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNyZWF0ZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLW9iamVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mb3Itb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX21ldGEuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL192YWxpZGF0ZS1jb2xsZWN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi1zdHJvbmcuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRldGVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc2V0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktZnJvbS1pdGVyYWJsZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24tdG8tanNvbi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnNldC50by1qc29uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LWNvbGxlY3Rpb24tb2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQub2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtY29sbGVjdGlvbi1mcm9tLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc2V0LmZyb20uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9zZXQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXAudG8tanNvbi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC5vZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC5mcm9tLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vbWFwLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktc3BlY2llcy1jcmVhdGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1tZXRob2RzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi13ZWFrLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1tYXAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy53ZWFrLW1hcC5vZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LndlYWstbWFwLmZyb20uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi93ZWFrLW1hcC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZyb20uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9hcnJheS9mcm9tLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvVXRpbGl0aWVzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvQ3VzdG9tRWxlbWVudFN0YXRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL0RvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvY3VzdG9tLWVsZW1lbnRzL3NyYy9EZWZlcnJlZC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL0N1c3RvbUVsZW1lbnRSZWdpc3RyeS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL1BhdGNoL05hdGl2ZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL0FscmVhZHlDb25zdHJ1Y3RlZE1hcmtlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL1BhdGNoL0hUTUxFbGVtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvUGF0Y2gvSW50ZXJmYWNlL1BhcmVudE5vZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvY3VzdG9tLWVsZW1lbnRzL3NyYy9QYXRjaC9Eb2N1bWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL1BhdGNoL05vZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQG9uc2VudWkvY3VzdG9tLWVsZW1lbnRzL3NyYy9QYXRjaC9JbnRlcmZhY2UvQ2hpbGROb2RlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0BvbnNlbnVpL2N1c3RvbS1lbGVtZW50cy9zcmMvUGF0Y2gvRWxlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9Ab25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL2N1c3RvbS1lbGVtZW50cy5qcyIsIi4uLy4uL2NvcmUvc3JjL3BvbHlmaWxscy9NdXRhdGlvbk9ic2VydmVyQDAuNy4yMi9NdXRhdGlvbk9ic2VydmVyLmpzIiwiLi4vLi4vY29yZS9zcmMvcG9seWZpbGxzL3NldEltbWVkaWF0ZUAxLjAuMittb2Qvc2V0SW1tZWRpYXRlLmpzIiwiLi4vLi4vY29yZS9zcmMvcG9seWZpbGxzL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvdmVuZG9yL3ZpZXdwb3J0LmpzIiwiLi4vLi4vY29yZS9zcmMvc2V0dXAuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtZWxlbWVudC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10ZW1wbGF0ZS5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1pZi5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9iYXNlLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvb25zL2lwaG9uZXgtcGF0Y2guanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtYWN0aW9uLXNoZWV0L2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvYmFzZS9iYXNlLWRpYWxvZy5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1hY3Rpb24tc2hlZXQvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtYnV0dG9uLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWFjdGlvbi1zaGVldC1idXR0b24uanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtYWxlcnQtZGlhbG9nL2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWFsZXJ0LWRpYWxvZy9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1hbGVydC1kaWFsb2ctYnV0dG9uLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWJhY2stYnV0dG9uLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWJvdHRvbS10b29sYmFyLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWJ1dHRvbi5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1jYXJkLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWNhcm91c2VsLWl0ZW0uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvc3dpcGVyLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWNhcm91c2VsLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWNvbC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1kaWFsb2cvYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtZGlhbG9nL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWZhYi5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1nZXN0dXJlLWRldGVjdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWljb24uanMiLCIuLi8uLi9jb3JlL3NyYy9vbnMvaW50ZXJuYWwvbGF6eS1yZXBlYXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGF6eS1yZXBlYXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGlzdC1oZWFkZXIuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGlzdC10aXRsZS5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1saXN0LWl0ZW0vYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbGlzdC1pdGVtL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLWxpc3QuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtaW5wdXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtaW5wdXQuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9iYXNlL2Jhc2UtY2hlY2tib3guanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtY2hlY2tib3guanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcmFkaW8uanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc2VhcmNoLWlucHV0LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW1vZGFsL2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW1vZGFsL2ZhZGUtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbW9kYWwvbGlmdC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1tb2RhbC9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL29ucy9pbnRlcm5hbC9zd2lwZS1yZXZlYWwuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbmF2aWdhdG9yL2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW5hdmlnYXRvci9pb3Mtc3dpcGUtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbmF2aWdhdG9yL2lvcy1zbGlkZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvaW9zLWxpZnQtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtbmF2aWdhdG9yL2lvcy1mYWRlLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLW5hdmlnYXRvci9tZC1zbGlkZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvbWQtbGlmdC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvbWQtZmFkZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3Ivbm9uZS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1uYXZpZ2F0b3IvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdG9vbGJhci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1wYWdlLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXBvcG92ZXIvYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcG9wb3Zlci9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1wcm9ncmVzcy1iYXIuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcHJvZ3Jlc3MtY2lyY3VsYXIuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcHVsbC1ob29rLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXJhbmdlLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXJpcHBsZS9hbmltYXRvci1jc3MuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtcmlwcGxlL2luZGV4LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXJvdy5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zZWdtZW50LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXNlbGVjdC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGVlZC1kaWFsLWl0ZW0uanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc3BlZWQtZGlhbC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci1jb250ZW50LmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXNwbGl0dGVyLW1hc2suanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc3BsaXR0ZXIvYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtc3BsaXR0ZXIvb3ZlcmxheS1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci9wdXNoLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXNwbGl0dGVyL3JldmVhbC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy1zcGxpdHRlci1zaWRlLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXN3aXRjaC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10YWJiYXIvaW5kZXguanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdGFiLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXRvYXN0L2FuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXRvYXN0L2ZhZGUtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdG9hc3QvYXNjZW5kLWFuaW1hdG9yLmpzIiwiLi4vLi4vY29yZS9zcmMvZWxlbWVudHMvb25zLXRvYXN0L2xpZnQtYW5pbWF0b3IuanMiLCIuLi8uLi9jb3JlL3NyYy9lbGVtZW50cy9vbnMtdG9hc3QvZmFsbC1hbmltYXRvci5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10b2FzdC9pbmRleC5qcyIsIi4uLy4uL2NvcmUvc3JjL2VsZW1lbnRzL29ucy10b29sYmFyLWJ1dHRvbi5qcyIsIi4uLy4uL2NvcmUvc3JjL2luZGV4LnVtZC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCB7IH07XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5cbi8qKlxuICogQWRkIHZlbmRvciBwcmVmaXguXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuY29uc3QgcHJlZml4ID0gKGZ1bmN0aW9uKCkge1xuICBjb25zdCBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICcnKTtcbiAgY29uc3QgcHJlZml4ID0gKEFycmF5LnByb3RvdHlwZS5zbGljZVxuICAgIC5jYWxsKHN0eWxlcylcbiAgICAuam9pbignJylcbiAgICAubWF0Y2goLy0obW96fHdlYmtpdHxtcyktLykgfHwgKHN0eWxlcy5PTGluayA9PT0gJycgJiYgWycnLCAnbyddKVxuICApWzFdO1xuXG4gIHJldHVybiBmdW5jdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuICctJyArIHByZWZpeCArICctJyArIHV0aWwuaHlwaGVuYXRlKG5hbWUpO1xuICB9O1xufSkoKTtcblxuXG4vKipcbiAqIE1pbmltYWwgdXRpbGl0eSBsaWJyYXJ5IGZvciBtYW5pcHVsYXRpbmcgZWxlbWVudCdzIHN0eWxlLlxuICogU2V0IGVsZW1lbnQncyBzdHlsZS5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdHlsZXNcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmNvbnN0IHN0eWxlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIHN0eWxlKSB7XG4gIE9iamVjdC5rZXlzKHN0eWxlKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmIChrZXkgaW4gZWxlbWVudC5zdHlsZSkge1xuICAgICAgZWxlbWVudC5zdHlsZVtrZXldID0gc3R5bGVba2V5XTtcbiAgICB9IGVsc2UgaWYgKHByZWZpeChrZXkpIGluIGVsZW1lbnQuc3R5bGUpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGVbcHJlZml4KGtleSldID0gc3R5bGVba2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXRpbC53YXJuKCdObyBzdWNoIHN0eWxlIHByb3BlcnR5OiAnICsga2V5KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gZWxlbWVudDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N0cmluZ30gc3R5bGVzIFNwYWNlLXNlcGFyYXRlZCBDU1MgcHJvcGVydGllcyB0byByZW1vdmVcbiAqL1xuc3R5bGVyLmNsZWFyID0gZnVuY3Rpb24oZWxlbWVudCwgc3R5bGVzID0gJycpIHtcbiAgY29uc3QgY2xlYXJsaXN0ID0gc3R5bGVzLnNwbGl0KC9cXHMrLykucmVkdWNlKChyLCBzKSA9PiByLmNvbmNhdChbdXRpbC5oeXBoZW5hdGUocyksIHByZWZpeChzKV0pLCBbXSksXG4gICAga2V5cyA9IFtdO1xuXG4gIGZvciAobGV0IGkgPSBlbGVtZW50LnN0eWxlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3Qga2V5ID0gZWxlbWVudC5zdHlsZVtpXTtcbiAgICBpZiAoY2xlYXJsaXN0Lmxlbmd0aCA9PT0gMCB8fCBjbGVhcmxpc3Quc29tZShzID0+IGtleS5pbmRleE9mKHMpID09PSAwKSkge1xuICAgICAga2V5cy5wdXNoKGtleSk7IC8vIFN0b3JlIHRoZSBrZXkgdG8gZml4IFNhZmFyaSBzdHlsZSBpbmRleGVzXG4gICAgfVxuICB9XG5cbiAga2V5cy5mb3JFYWNoKGtleSA9PiBlbGVtZW50LnN0eWxlW2tleV0gPSAnJyk7XG4gIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzdHlsZScpID09PSAnJyAmJiBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHN0eWxlcjtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbi8vIFNhdmUgSFRNTEVsZW1lbnQgb2JqZWN0IGJlZm9yZSBDdXN0b20gRWxlbWVudHMgcG9seWZpbGwgcGF0Y2ggZ2xvYmFsIEhUTUxFbGVtZW50LlxuY29uc3QgTmF0aXZlSFRNTEVsZW1lbnQgPSB3aW5kb3cuSFRNTEVsZW1lbnQ7XG5cbi8qKlxuICogQG9iamVjdCBvbnMucGxhdGZvcm1cbiAqIEBjYXRlZ29yeSB1dGlsXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVV0aWxpdHkgbWV0aG9kcyB0byBkZXRlY3QgY3VycmVudCBwbGF0Zm9ybS5bL2VuXVxuICogICBbamFd54++5Zyo5a6f6KGM44GV44KM44Gm44GE44KL44OX44Op44OD44OI44OV44Kp44O844Og44KS5qSc55+l44GZ44KL44Gf44KB44Gu44Om44O844OG44Kj44Oq44OG44Kj44Oh44K944OD44OJ44KS5Y+O44KB44Gf44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqL1xuY2xhc3MgUGxhdGZvcm0ge1xuXG4gIC8qKlxuICAgKiBBbGwgZWxlbWVudHMgd2lsbCBiZSByZW5kZXJlZCBhcyBpZiB0aGUgYXBwIHdhcyBydW5uaW5nIG9uIHRoaXMgcGxhdGZvcm0uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9zZWxlY3RlZFBsYXRmb3JtID0gbnVsbDtcbiAgICB0aGlzLl9pZ25vcmVQbGF0Zm9ybVNlbGVjdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2VsZWN0XG4gICAqIEBzaWduYXR1cmUgc2VsZWN0KHBsYXRmb3JtKVxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHBsYXRmb3JtIE5hbWUgb2YgdGhlIHBsYXRmb3JtLlxuICAgKiAgIFtlbl1Qb3NzaWJsZSB2YWx1ZXMgYXJlOiBcIm9wZXJhXCIsIFwiZmlyZWZveFwiLCBcInNhZmFyaVwiLCBcImNocm9tZVwiLCBcImllXCIsIFwiYW5kcm9pZFwiLCBcImJsYWNrYmVycnlcIiwgXCJpb3NcIiBvciBcIndwXCIuWy9lbl1cbiAgICogICBbamFdXCJvcGVyYVwiLCBcImZpcmVmb3hcIiwgXCJzYWZhcmlcIiwgXCJjaHJvbWVcIiwgXCJpZVwiLCBcImFuZHJvaWRcIiwgXCJibGFja2JlcnJ5XCIsIFwiaW9zXCIsIFwid3BcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TZXRzIHRoZSBwbGF0Zm9ybSB1c2VkIHRvIHJlbmRlciB0aGUgZWxlbWVudHMuIFVzZWZ1bCBmb3IgdGVzdGluZy5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgpLmj4/nlLvjgZnjgovjgZ/jgoHjgavliKnnlKjjgZnjgovjg5fjg6njg4Pjg4jjg5Xjgqnjg7zjg6DlkI3jgpLoqK3lrprjgZfjgb7jgZnjgILjg4bjgrnjg4jjgavkvr/liKnjgafjgZnjgIJbL2phXVxuICAgKi9cbiAgc2VsZWN0KHBsYXRmb3JtKSB7XG4gICAgaWYgKHR5cGVvZiBwbGF0Zm9ybSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkUGxhdGZvcm0gPSBwbGF0Zm9ybS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gIH1cblxuICBfZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpIHtcbiAgICByZXR1cm4gdGhpcy5faWdub3JlUGxhdGZvcm1TZWxlY3QgPyBudWxsIDogdGhpcy5fc2VsZWN0ZWRQbGF0Zm9ybTtcbiAgfVxuXG4gIF9ydW5PbkFjdHVhbFBsYXRmb3JtKGZuKSB7XG4gICAgdGhpcy5faWdub3JlUGxhdGZvcm1TZWxlY3QgPSB0cnVlO1xuICAgIGNvbnN0IHJlc3VsdCA9IGZuKCk7XG4gICAgdGhpcy5faWdub3JlUGxhdGZvcm1TZWxlY3QgPSBmYWxzZTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gR2VuZXJhbFxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNXZWJWaWV3XG4gICAqIEBzaWduYXR1cmUgaXNXZWJWaWV3KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBDb3Jkb3ZhLlsvZW5dXG4gICAqICAgW2phXUNvcmRvdmHlhoXjgaflrp/ooYzjgZXjgozjgabjgYTjgovjgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNXZWJWaWV3KCkge1xuICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnbG9hZGluZycgfHwgZG9jdW1lbnQucmVhZHlTdGF0ZSA9PSAndW5pbml0aWFsaXplZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaXNXZWJWaWV3KCkgbWV0aG9kIGlzIGF2YWlsYWJsZSBhZnRlciBkb20gY29udGVudHMgbG9hZGVkLicpO1xuICAgIH1cblxuICAgIHJldHVybiAhISh3aW5kb3cuY29yZG92YSB8fCB3aW5kb3cucGhvbmVnYXAgfHwgd2luZG93LlBob25lR2FwKTtcbiAgfVxuXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBpT1MgZGV2aWNlc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNJUGhvbmVcbiAgICogQHNpZ25hdHVyZSBpc0lQaG9uZSgpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGRldmljZSBpcyBpUGhvbmUuWy9lbl1cbiAgICogICBbamFdaVBob25l5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSVBob25lKCkge1xuICAgIHJldHVybiAvaVBob25lL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzSVBob25lWFxuICAgKiBAc2lnbmF0dXJlIGlzSVBob25lWCgpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGRldmljZSBpcyBpUGhvbmUgWCwgWFMsIFhTIE1heCwgb3IgWFIuWy9lbl1cbiAgICogICBbamFdaVBob25lIFgg44KEIFhT44CBWFMgTWF444CB44G+44Gf44GvIFhSIOS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0lQaG9uZVgoKSB7XG4gICAgLy8gaU9TIFdlYlZpZXdzIG9uIHRoZSBzYW1lIGlPUyB2ZXJzaW9uIGhhdmUgdGhlIHNhbWUgdXNlciBhZ2VudC5cbiAgICAvLyBXZSBjYW5ub3QgYXZvaWQgdXNpbmcgd2luZG93LnNjcmVlbi5cbiAgICAvLyBXZSBhbHNvIGNhbm5vdCB1c2UgY29yZG92YS1wbHVnaW4tZGV2aWNlIHNpbmNlIGl0cyBiZWhhdmlvciBpcyBkaWZmZXJlbnQgYmV0d2VlbiBzaW11bGF0b3JzIGFuZCByZWFsIGRldmljZXMuXG4gICAgLy8gVGhpcyB3b3JrcyB3ZWxsIGJvdGggaW4gaU9TIFNhZmFyaSBhbmQgKFVJfFdLKVdlYlZpZXcgb2YgaVBob25lIFguXG4gICAgcmV0dXJuIHRoaXMuaXNJUGhvbmUoKSAmJlxuICAgICAgKHdpbmRvdy5zY3JlZW4ud2lkdGggPT09IDM3NSAmJiB3aW5kb3cuc2NyZWVuLmhlaWdodCA9PT0gODEyIHx8IC8vIFgsIFhTIHBvcnRyYWl0XG4gICAgICAgd2luZG93LnNjcmVlbi53aWR0aCA9PT0gODEyICYmIHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID09PSAzNzUgfHwgLy8gWCwgWFMgbGFuZHNjYXBlXG4gICAgICAgd2luZG93LnNjcmVlbi53aWR0aCA9PT0gNDE0ICYmIHdpbmRvdy5zY3JlZW4uaGVpZ2h0ID09PSA4OTYgfHwgLy8gWFMgTWF4LCBYUiBwb3J0cmFpdFxuICAgICAgIHdpbmRvdy5zY3JlZW4ud2lkdGggPT09IDg5NiAmJiB3aW5kb3cuc2NyZWVuLmhlaWdodCA9PT0gNDE0KTsgLy8gWFMgTWF4LCBYUiBsYW5kc2NhcGVcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzSVBhZFxuICAgKiBAc2lnbmF0dXJlIGlzSVBhZCgpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGRldmljZSBpcyBpUGFkLlsvZW5dXG4gICAqICAgW2phXWlQYWTkuIrjgaflrp/ooYzjgZXjgozjgabjgYTjgovjgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNJUGFkKCkge1xuICAgIHJldHVybiAvaVBhZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSVBvZCgpIHtcbiAgICByZXR1cm4gL2lQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICB9XG5cbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIGlPUyB2ZXJzaW9uc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNJT1NcbiAgICogQHNpZ25hdHVyZSBpc0lPUyhbZm9yY2VBY3R1YWxQbGF0Zm9ybV0pXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2VBY3R1YWxQbGF0Zm9ybVxuICAgKiAgIFtlbl1JZiB0cnVlLCBzZWxlY3RlZCBwbGF0Zm9ybSBpcyBpZ25vcmVkIGFuZCB0aGUgYWN0dWFsIHBsYXRmb3JtIGlzIHJldHVybmVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIE9TIGlzIGlPUy4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdaU9T5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSU9TKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnaW9zJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcgJiYgIS9icm93c2VyL2kudGVzdChkZXZpY2UucGxhdGZvcm0pKSB7XG4gICAgICByZXR1cm4gL2lPUy9pLnRlc3QoZGV2aWNlLnBsYXRmb3JtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIC9pUGhvbmV8aVBhZHxpUG9kL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc0lPUzdhYm92ZVxuICAgKiBAc2lnbmF0dXJlIGlzSU9TN2Fib3ZlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgaU9TIHZlcnNpb24gaXMgNyBvciBhYm92ZS5bL2VuXVxuICAgKiAgIFtqYV1pT1M35Lul5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzSU9TN2Fib3ZlKCkge1xuICAgIGlmICh0eXBlb2YgZGV2aWNlID09PSAnb2JqZWN0JyAmJiAhL2Jyb3dzZXIvaS50ZXN0KGRldmljZS5wbGF0Zm9ybSkpIHtcbiAgICAgIHJldHVybiAoL2lPUy9pLnRlc3QoZGV2aWNlLnBsYXRmb3JtKSAmJiAocGFyc2VJbnQoZGV2aWNlLnZlcnNpb24uc3BsaXQoJy4nKVswXSkgPj0gNykpO1xuICAgIH0gZWxzZSBpZiAoL2lQaG9uZXxpUGFkfGlQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICBjb25zdCB2ZXIgPSAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvXFxiWzAtOV0rX1swLTldKyg/Ol9bMC05XSspP1xcYi8pIHx8IFsnJ10pWzBdLnJlcGxhY2UoL18vZywgJy4nKTtcbiAgICAgIHJldHVybiAocGFyc2VJbnQodmVyLnNwbGl0KCcuJylbMF0pID49IDcpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gaU9TIGJyb3dzZXJzXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogQG1ldGhvZCBpc0lPU1NhZmFyaVxuICAgKiBAc2lnbmF0dXJlIGlzSU9TU2FmYXJpKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBpT1MgU2FmYXJpLlsvZW5dXG4gICAqICAgW2phXWlPUyBTYWZhcmnjgaflrp/ooYzjgZXjgozjgabjgYTjgovjgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNJT1NTYWZhcmkoKSB7XG4gICAgY29uc3QgbmF2aWdhdG9yID0gd2luZG93Lm5hdmlnYXRvcjtcbiAgICBjb25zdCB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG5cbiAgICByZXR1cm4gISEodGhpcy5pc0lPUygpICYmIHVhLmluZGV4T2YoJ1NhZmFyaScpICE9PSAtMSAmJiB1YS5pbmRleE9mKCdWZXJzaW9uJykgIT09IC0xICYmICFuYXZpZ2F0b3Iuc3RhbmRhbG9uZSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc1dLV2ViVmlld1xuICAgKiBAc2lnbmF0dXJlIGlzV0tXZWJWaWV3KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBXS1dlYlZpZXcuWy9lbl1cbiAgICogICBbamFdV0tXZWJWaWV344Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzV0tXZWJWaWV3KCkge1xuICAgIGNvbnN0IGx0ZTkgPSAvY29uc3RydWN0b3IvaS50ZXN0KE5hdGl2ZUhUTUxFbGVtZW50KTtcbiAgICByZXR1cm4gISEodGhpcy5pc0lPUygpICYmIHdpbmRvdy53ZWJraXQgJiYgd2luZG93LndlYmtpdC5tZXNzYWdlSGFuZGxlcnMgJiYgd2luZG93LmluZGV4ZWREQiAmJiAhbHRlOSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc1VJV2ViVmlld1xuICAgKiBAc2lnbmF0dXJlIGlzVUlXZWJWaWV3KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciBhcHAgaXMgcnVubmluZyBpbiBVSVdlYlZpZXcuWy9lbl1cbiAgICogICBbamFdVUlXZWJWaWV344Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzVUlXZWJWaWV3KCkge1xuICAgIHJldHVybiAhISh0aGlzLmlzSU9TKCkgJiYgIXRoaXMuaXNJT1NTYWZhcmkoKSAmJiAhdGhpcy5pc1dLV2ViVmlldygpKTtcbiAgfVxuXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBBbmRyb2lkIGRldmljZXNcbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzQW5kcm9pZFBob25lXG4gICAqIEBzaWduYXR1cmUgaXNBbmRyb2lkUGhvbmUoKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgQW5kcm9pZCBwaG9uZS5bL2VuXVxuICAgKiAgIFtqYV1BbmRyb2lk5pC65biv5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzQW5kcm9pZFBob25lKCkge1xuICAgIHJldHVybiAvQW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgL01vYmlsZS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc0FuZHJvaWRUYWJsZXRcbiAgICogQHNpZ25hdHVyZSBpc0FuZHJvaWRUYWJsZXQoKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgQW5kcm9pZCB0YWJsZXQuWy9lbl1cbiAgICogICBbamFdQW5kcm9pZOOCv+ODluODrOODg+ODiOS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0FuZHJvaWRUYWJsZXQoKSB7XG4gICAgcmV0dXJuIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAhL01vYmlsZS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIH1cblxuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gQW5kcm9pZCB2ZXJzaW9uc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNBbmRyb2lkXG4gICAqIEBzaWduYXR1cmUgaXNBbmRyb2lkKFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgT1MgaXMgQW5kcm9pZC4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdQW5kcm9pZOS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0FuZHJvaWQoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICdhbmRyb2lkJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcgJiYgIS9icm93c2VyL2kudGVzdChkZXZpY2UucGxhdGZvcm0pKSB7XG4gICAgICByZXR1cm4gL0FuZHJvaWQvaS50ZXN0KGRldmljZS5wbGF0Zm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAvQW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gICAgfVxuICB9XG5cbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIE90aGVyIGRldmljZXNcbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzV1BcbiAgICogQHNpZ25hdHVyZSBpc1dQKFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgT1MgaXMgV2luZG93cyBwaG9uZS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzV1AoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICd3cCc7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkZXZpY2UgPT09ICdvYmplY3QnICYmICEvYnJvd3Nlci9pLnRlc3QoZGV2aWNlLnBsYXRmb3JtKSkge1xuICAgICAgcmV0dXJuIC9XaW4zMk5UfFdpbkNFL2kudGVzdChkZXZpY2UucGxhdGZvcm0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gL1dpbmRvd3MgUGhvbmV8SUVNb2JpbGV8V1BEZXNrdG9wL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc0JsYWNrQmVycnlcbiAgICogQHNpZ25hdHVyZSBpc0JsYWNrQmVycnkoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBkZXZpY2UgaXMgQmxhY2tCZXJyeS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdQmxhY2tCZXJyeeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0JsYWNrQmVycnkoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICdibGFja2JlcnJ5JztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcgJiYgIS9icm93c2VyL2kudGVzdChkZXZpY2UucGxhdGZvcm0pKSB7XG4gICAgICByZXR1cm4gL0JsYWNrQmVycnkvaS50ZXN0KGRldmljZS5wbGF0Zm9ybSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAvQmxhY2tCZXJyeXxSSU0gVGFibGV0IE9TfEJCMTAvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBPdGhlciBicm93c2Vyc1xuICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNPcGVyYVxuICAgKiBAc2lnbmF0dXJlIGlzT3BlcmEoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIE9wZXJhLiBCeSBkZWZhdWx0IHdpbGwgcmV0dXJuIG1hbnVhbGx5IHNlbGVjdGVkIHBsYXRmb3JtIGlmIGl0IGlzIHNldC5bL2VuXVxuICAgKiAgIFtqYV1PcGVyYeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc09wZXJhKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnb3BlcmEnO1xuICAgIH1cblxuICAgIHJldHVybiAoISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNGaXJlZm94XG4gICAqIEBzaWduYXR1cmUgaXNGaXJlZm94KFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgYnJvd3NlciBpcyBGaXJlZm94LiBCeSBkZWZhdWx0IHdpbGwgcmV0dXJuIG1hbnVhbGx5IHNlbGVjdGVkIHBsYXRmb3JtIGlmIGl0IGlzIHNldC5bL2VuXVxuICAgKiAgIFtqYV1GaXJlZm945LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzRmlyZWZveChmb3JjZUFjdHVhbFBsYXRmb3JtKSB7XG4gICAgaWYgKCFmb3JjZUFjdHVhbFBsYXRmb3JtICYmIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSA9PT0gJ2ZpcmVmb3gnO1xuICAgIH1cblxuICAgIHJldHVybiAodHlwZW9mIEluc3RhbGxUcmlnZ2VyICE9PSAndW5kZWZpbmVkJyk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBpc1NhZmFyaVxuICAgKiBAc2lnbmF0dXJlIGlzU2FmYXJpKFtmb3JjZUFjdHVhbFBsYXRmb3JtXSlcbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZUFjdHVhbFBsYXRmb3JtXG4gICAqICAgW2VuXUlmIHRydWUsIHNlbGVjdGVkIHBsYXRmb3JtIGlzIGlnbm9yZWQgYW5kIHRoZSBhY3R1YWwgcGxhdGZvcm0gaXMgcmV0dXJuZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJldHVybnMgd2hldGhlciB0aGUgYnJvd3NlciBpcyBTYWZhcmkuIEJ5IGRlZmF1bHQgd2lsbCByZXR1cm4gbWFudWFsbHkgc2VsZWN0ZWQgcGxhdGZvcm0gaWYgaXQgaXMgc2V0LlsvZW5dXG4gICAqICAgW2phXVNhZmFyaeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc1NhZmFyaShmb3JjZUFjdHVhbFBsYXRmb3JtKSB7XG4gICAgaWYgKCFmb3JjZUFjdHVhbFBsYXRmb3JtICYmIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFNlbGVjdGVkUGxhdGZvcm0oKSA9PT0gJ3NhZmFyaSc7XG4gICAgfVxuXG4gICAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LkhUTUxFbGVtZW50KS5pbmRleE9mKCdDb25zdHJ1Y3RvcicpID4gMCkgfHwgKGZ1bmN0aW9uIChwKSB7IHJldHVybiBwLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IFNhZmFyaVJlbW90ZU5vdGlmaWNhdGlvbl0nIH0pKCF3aW5kb3dbJ3NhZmFyaSddIHx8IHNhZmFyaS5wdXNoTm90aWZpY2F0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzQ2hyb21lXG4gICAqIEBzaWduYXR1cmUgaXNDaHJvbWUoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIENocm9tZS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdQ2hyb21l5LiK44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIGlzQ2hyb21lKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnY2hyb21lJztcbiAgICB9XG5cbiAgICByZXR1cm4gKCEhd2luZG93LmNocm9tZSAmJiAhKCEhd2luZG93Lm9wZXJhIHx8IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIE9QUi8nKSA+PSAwKSAmJiAhKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignIEVkZ2UvJykgPj0gMCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaXNJRVxuICAgKiBAc2lnbmF0dXJlIGlzSUUoW2ZvcmNlQWN0dWFsUGxhdGZvcm1dKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlQWN0dWFsUGxhdGZvcm1cbiAgICogICBbZW5dSWYgdHJ1ZSwgc2VsZWN0ZWQgcGxhdGZvcm0gaXMgaWdub3JlZCBhbmQgdGhlIGFjdHVhbCBwbGF0Zm9ybSBpcyByZXR1cm5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBicm93c2VyIGlzIEludGVybmV0IEV4cGxvcmVyLiBCeSBkZWZhdWx0IHdpbGwgcmV0dXJuIG1hbnVhbGx5IHNlbGVjdGVkIHBsYXRmb3JtIGlmIGl0IGlzIHNldC5bL2VuXVxuICAgKiAgIFtqYV1JbnRlcm5ldCBFeHBsb3JlcuS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0lFKGZvcmNlQWN0dWFsUGxhdGZvcm0pIHtcbiAgICBpZiAoIWZvcmNlQWN0dWFsUGxhdGZvcm0gJiYgdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpID09PSAnaWUnO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZSB8fCAhIWRvY3VtZW50LmRvY3VtZW50TW9kZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzRWRnZVxuICAgKiBAc2lnbmF0dXJlIGlzRWRnZShbZm9yY2VBY3R1YWxQbGF0Zm9ybV0pXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2VBY3R1YWxQbGF0Zm9ybVxuICAgKiAgIFtlbl1JZiB0cnVlLCBzZWxlY3RlZCBwbGF0Zm9ybSBpcyBpZ25vcmVkIGFuZCB0aGUgYWN0dWFsIHBsYXRmb3JtIGlzIHJldHVybmVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgRWRnZS4gQnkgZGVmYXVsdCB3aWxsIHJldHVybiBtYW51YWxseSBzZWxlY3RlZCBwbGF0Zm9ybSBpZiBpdCBpcyBzZXQuWy9lbl1cbiAgICogICBbamFdRWRnZeS4iuOBp+Wun+ihjOOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0VkZ2UoZm9yY2VBY3R1YWxQbGF0Zm9ybSkge1xuICAgIGlmICghZm9yY2VBY3R1YWxQbGF0Zm9ybSAmJiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRTZWxlY3RlZFBsYXRmb3JtKCkgPT09ICdlZGdlJztcbiAgICB9XG5cbiAgICByZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgRWRnZS8nKSA+PSAwO1xuICB9XG5cbiAgLy8tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFV0aWxpdHkgZnVuY3Rpb25zXG4gIC8vLS0tLS0tLS0tLS0tLS0tLVxuICAvKipcbiAgICogQHJldHVybiB7U3RyaW5nfVxuICAgKi9cbiAgZ2V0TW9iaWxlT1MoKSB7XG4gICAgaWYgKHRoaXMuaXNBbmRyb2lkKCkpIHtcbiAgICAgIHJldHVybiAnYW5kcm9pZCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuaXNJT1MoKSkge1xuICAgICAgcmV0dXJuICdpb3MnO1xuICAgIH1cbiAgICBlbHNlIGlmICh0aGlzLmlzV1AoKSkge1xuICAgICAgcmV0dXJuICd3cCc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuICdvdGhlcic7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1N0cmluZ31cbiAgICovXG4gIGdldElPU0RldmljZSgpIHtcbiAgICBpZiAodGhpcy5pc0lQaG9uZSgpKSB7XG4gICAgICByZXR1cm4gJ2lwaG9uZSc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuaXNJUGFkKCkpIHtcbiAgICAgIHJldHVybiAnaXBhZCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuaXNJUG9kKCkpIHtcbiAgICAgIHJldHVybiAnaXBvZCc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuICduYSc7XG4gICAgfVxuICB9XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgbmV3IFBsYXRmb3JtKCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi9wbGF0Zm9ybSc7XG5pbXBvcnQgdXRpbCBmcm9tICcuL3V0aWwnO1xuXG5jb25zdCBlcnJvciA9IG1lc3NhZ2UgPT4gdXRpbC50aHJvdyhgSW4gUGFnZUF0dHJpYnV0ZUV4cHJlc3Npb246ICR7bWVzc2FnZX1gKTtcblxuY29uc3QgcGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24gPSB7XG4gIF92YXJpYWJsZXM6IHt9LFxuXG4gIC8qKlxuICAgKiBEZWZpbmUgYSB2YXJpYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgdmFyaWFibGVcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHZhbHVlIFZhbHVlIG9mIHRoZSB2YXJpYWJsZS4gQ2FuIGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb24uIFRoZSBmdW5jdGlvbiBtdXN0IHJldHVybiBhIHN0cmluZy5cbiAgICogQHBhcmFtIHtCb29sZWFufSBvdmVyd3JpdGUgSWYgdGhpcyB2YWx1ZSBpcyBmYWxzZSwgYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24gd2hlbiB0cnlpbmcgdG8gZGVmaW5lIGEgdmFyaWFibGUgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGRlZmluZWQuXG4gICAqL1xuICBkZWZpbmVWYXJpYWJsZTogZnVuY3Rpb24obmFtZSwgdmFsdWUsIG92ZXJ3cml0ZT1mYWxzZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIGVycm9yKCdWYXJpYWJsZSBuYW1lIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCdWYXJpYWJsZSB2YWx1ZSBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb24nKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5fdmFyaWFibGVzLmhhc093blByb3BlcnR5KG5hbWUpICYmICFvdmVyd3JpdGUpIHtcbiAgICAgIGVycm9yKGBcIiR7bmFtZX1cIiBpcyBhbHJlYWR5IGRlZmluZWRgKTtcbiAgICB9XG4gICAgdGhpcy5fdmFyaWFibGVzW25hbWVdID0gdmFsdWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhIHZhcmlhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBOYW1lIG9mIHRoZSB2YXJpYWJsZS5cbiAgICogQHJldHVybiB7U3RyaW5nfEZ1bmN0aW9ufG51bGx9XG4gICAqL1xuICBnZXRWYXJpYWJsZTogZnVuY3Rpb24obmFtZSkge1xuICAgIGlmICghdGhpcy5fdmFyaWFibGVzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fdmFyaWFibGVzW25hbWVdO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYSB2YXJpYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgTmFtZSBvZiB0aGUgdmFyYWlibGUuXG4gICAqL1xuICByZW1vdmVWYXJpYWJsZTogZnVuY3Rpb24obmFtZSkge1xuICAgIGRlbGV0ZSB0aGlzLl92YXJpYWJsZXNbbmFtZV07XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhbGwgdmFyaWFibGVzLlxuICAgKlxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBnZXRBbGxWYXJpYWJsZXM6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl92YXJpYWJsZXM7XG4gIH0sXG4gIF9wYXJzZVBhcnQ6IGZ1bmN0aW9uKHBhcnQpIHtcbiAgICBsZXQgYyxcbiAgICAgIGluSW50ZXJwb2xhdGlvbiA9IGZhbHNlLFxuICAgICAgY3VycmVudEluZGV4ID0gMDtcblxuICAgIGNvbnN0IHRva2VucyA9IFtdO1xuXG4gICAgaWYgKHBhcnQubGVuZ3RoID09PSAwKSB7XG4gICAgICBlcnJvcignVW5hYmxlIHRvIHBhcnNlIGVtcHR5IHN0cmluZycpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydC5sZW5ndGg7IGkrKykge1xuICAgICAgYyA9IHBhcnQuY2hhckF0KGkpO1xuXG4gICAgICBpZiAoYyA9PT0gJyQnICYmIHBhcnQuY2hhckF0KGkgKyAxKSA9PT0gJ3snKSB7XG4gICAgICAgIGlmIChpbkludGVycG9sYXRpb24pIHtcbiAgICAgICAgICBlcnJvcignTmVzdGVkIGludGVycG9sYXRpb24gbm90IHN1cHBvcnRlZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9rZW4gPSBwYXJ0LnN1YnN0cmluZyhjdXJyZW50SW5kZXgsIGkpO1xuICAgICAgICBpZiAodG9rZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHBhcnQuc3Vic3RyaW5nKGN1cnJlbnRJbmRleCwgaSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudEluZGV4ID0gaTtcbiAgICAgICAgaW5JbnRlcnBvbGF0aW9uID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGMgPT09ICd9Jykge1xuICAgICAgICBpZiAoIWluSW50ZXJwb2xhdGlvbikge1xuICAgICAgICAgIGVycm9yKCd9IG11c3QgYmUgcHJlY2VlZGVkIGJ5ICR7Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b2tlbiA9IHBhcnQuc3Vic3RyaW5nKGN1cnJlbnRJbmRleCwgaSArIDEpO1xuICAgICAgICBpZiAodG9rZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRva2Vucy5wdXNoKHBhcnQuc3Vic3RyaW5nKGN1cnJlbnRJbmRleCwgaSArIDEpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGN1cnJlbnRJbmRleCA9IGkgKyAxO1xuICAgICAgICBpbkludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW5JbnRlcnBvbGF0aW9uKSB7XG4gICAgICBlcnJvcignVW50ZXJtaW5hdGVkIGludGVycG9sYXRpb24nKTtcbiAgICB9XG5cbiAgICB0b2tlbnMucHVzaChwYXJ0LnN1YnN0cmluZyhjdXJyZW50SW5kZXgsIHBhcnQubGVuZ3RoKSk7XG5cbiAgICByZXR1cm4gdG9rZW5zO1xuICB9LFxuICBfcmVwbGFjZVRva2VuOiBmdW5jdGlvbih0b2tlbikge1xuICAgIGNvbnN0IHJlID0gL15cXCR7KC4qPyl9JC8sXG4gICAgICBtYXRjaCA9IHRva2VuLm1hdGNoKHJlKTtcblxuICAgIGlmIChtYXRjaCkge1xuICAgICAgY29uc3QgbmFtZSA9IG1hdGNoWzFdLnRyaW0oKTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlID0gdGhpcy5nZXRWYXJpYWJsZShuYW1lKTtcblxuICAgICAgaWYgKHZhcmlhYmxlID09PSBudWxsKSB7XG4gICAgICAgIGVycm9yKGBWYXJpYWJsZSBcIiR7bmFtZX1cIiBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodHlwZW9mIHZhcmlhYmxlID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFyaWFibGU7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgcnYgPSB2YXJpYWJsZSgpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgcnYgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgZXJyb3IoJ011c3QgcmV0dXJuIGEgc3RyaW5nJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcnY7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH1cbiAgfSxcbiAgX3JlcGxhY2VUb2tlbnM6IGZ1bmN0aW9uKHRva2Vucykge1xuICAgIHJldHVybiB0b2tlbnMubWFwKHRoaXMuX3JlcGxhY2VUb2tlbi5iaW5kKHRoaXMpKTtcbiAgfSxcbiAgX3BhcnNlRXhwcmVzc2lvbjogZnVuY3Rpb24oZXhwcmVzc2lvbikge1xuICAgIHJldHVybiBleHByZXNzaW9uLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoXG4gICAgICAgIGZ1bmN0aW9uKHBhcnQpIHtcbiAgICAgICAgICByZXR1cm4gcGFydC50cmltKCk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC5tYXAodGhpcy5fcGFyc2VQYXJ0LmJpbmQodGhpcykpXG4gICAgICAubWFwKHRoaXMuX3JlcGxhY2VUb2tlbnMuYmluZCh0aGlzKSlcbiAgICAgIC5tYXAoKHBhcnQpID0+IHBhcnQuam9pbignJykpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZSBhbiBleHByZXNzaW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwcmVzc2lvbiBBbiBwYWdlIGF0dHJpYnV0ZSBleHByZXNzaW9uLlxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIGV2YWx1YXRlOiBmdW5jdGlvbihleHByZXNzaW9uKSB7XG4gICAgaWYgKCFleHByZXNzaW9uKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3BhcnNlRXhwcmVzc2lvbihleHByZXNzaW9uKTtcbiAgfVxufTtcblxuLy8gRGVmaW5lIGRlZmF1bHQgdmFyaWFibGVzLlxucGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24uZGVmaW5lVmFyaWFibGUoJ21vYmlsZU9TJywgcGxhdGZvcm0uZ2V0TW9iaWxlT1MoKSk7XG5wYWdlQXR0cmlidXRlRXhwcmVzc2lvbi5kZWZpbmVWYXJpYWJsZSgnaU9TRGV2aWNlJywgcGxhdGZvcm0uZ2V0SU9TRGV2aWNlKCkpO1xucGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24uZGVmaW5lVmFyaWFibGUoJ3J1bnRpbWUnLCAoKSA9PiB7XG4gIHJldHVybiBwbGF0Zm9ybS5pc1dlYlZpZXcoKSA/ICdjb3Jkb3ZhJyA6ICdicm93c2VyJztcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBwYWdlQXR0cmlidXRlRXhwcmVzc2lvbjtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL3BsYXRmb3JtJztcbmltcG9ydCBwYWdlQXR0cmlidXRlRXhwcmVzc2lvbiBmcm9tICcuLi9wYWdlLWF0dHJpYnV0ZS1leHByZXNzaW9uJztcblxuY29uc3QgaW50ZXJuYWwgPSB7fTtcblxuaW50ZXJuYWwuY29uZmlnID0ge1xuICBhdXRvU3RhdHVzQmFyRmlsbDogdHJ1ZSxcbiAgYW5pbWF0aW9uc0Rpc2FibGVkOiBmYWxzZSxcbiAgd2FybmluZ3NEaXNhYmxlZDogZmFsc2Vcbn07XG5cbmludGVybmFsLm51bGxFbGVtZW50ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4vKipcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmludGVybmFsLmlzRW5hYmxlZEF1dG9TdGF0dXNCYXJGaWxsID0gKCkgPT4ge1xuICByZXR1cm4gISFpbnRlcm5hbC5jb25maWcuYXV0b1N0YXR1c0JhckZpbGw7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSBodG1sXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cbmludGVybmFsLm5vcm1hbGl6ZVBhZ2VIVE1MID0gaHRtbCA9PiAoJycgKyBodG1sKS50cmltKCk7XG5cbmludGVybmFsLndhaXRET01Db250ZW50TG9hZGVkID0gY2FsbGJhY2sgPT4ge1xuICBpZiAod2luZG93LmRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJyB8fCB3aW5kb3cuZG9jdW1lbnQucmVhZHlTdGF0ZSA9PSAndW5pbml0aWFsaXplZCcpIHtcbiAgICBjb25zdCB3cmFwcGVkQ2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgICAgd2luZG93LmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB3cmFwcGVkQ2FsbGJhY2spO1xuICAgIH07XG4gICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB3cmFwcGVkQ2FsbGJhY2spO1xuICB9IGVsc2Uge1xuICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4gIH1cbn07XG5cbmludGVybmFsLmF1dG9TdGF0dXNCYXJGaWxsID0gYWN0aW9uID0+IHtcbiAgY29uc3Qgb25SZWFkeSA9ICgpID0+IHtcbiAgICBpZiAoaW50ZXJuYWwuc2hvdWxkRmlsbFN0YXR1c0JhcigpKSB7XG4gICAgICBhY3Rpb24oKTtcbiAgICB9XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlcmVhZHknLCBvblJlYWR5KTtcbiAgfTtcblxuICBpZiAodHlwZW9mIGRldmljZSA9PT0gJ29iamVjdCcpIHtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2VyZWFkeScsIG9uUmVhZHkpO1xuICB9IGVsc2UgaWYgKFsnY29tcGxldGUnLCAnaW50ZXJhY3RpdmUnXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID09PSAtMSkge1xuICAgIGludGVybmFsLndhaXRET01Db250ZW50TG9hZGVkKG9uUmVhZHkpO1xuICB9IGVsc2Uge1xuICAgIG9uUmVhZHkoKTtcbiAgfVxufTtcblxuaW50ZXJuYWwuc2hvdWxkRmlsbFN0YXR1c0JhciA9ICgpID0+IGludGVybmFsLmlzRW5hYmxlZEF1dG9TdGF0dXNCYXJGaWxsKCkgJiZcbiAgKHBsYXRmb3JtLmlzV2ViVmlldygpICYmIHBsYXRmb3JtLmlzSU9TN2Fib3ZlKCkgJiYgIXBsYXRmb3JtLmlzSVBob25lWCgpIHx8IGRvY3VtZW50LmJvZHkucXVlcnlTZWxlY3RvcignLm9ucy1zdGF0dXMtYmFyLW1vY2suaW9zJykpO1xuXG5pbnRlcm5hbC50ZW1wbGF0ZVN0b3JlID0ge1xuICBfc3RvcmFnZToge30sXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nL251bGx9IHRlbXBsYXRlXG4gICAqL1xuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIGludGVybmFsLnRlbXBsYXRlU3RvcmUuX3N0b3JhZ2Vba2V5XSB8fCBudWxsO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0ZW1wbGF0ZVxuICAgKi9cbiAgc2V0KGtleSwgdGVtcGxhdGUpIHtcbiAgICBpbnRlcm5hbC50ZW1wbGF0ZVN0b3JlLl9zdG9yYWdlW2tleV0gPSB0ZW1wbGF0ZTtcbiAgfVxufTtcblxud2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ190ZW1wbGF0ZWxvYWRlZCcsIGZ1bmN0aW9uKGUpIHtcbiAgaWYgKGUudGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdvbnMtdGVtcGxhdGUnKSB7XG4gICAgaW50ZXJuYWwudGVtcGxhdGVTdG9yZS5zZXQoZS50ZW1wbGF0ZUlkLCBlLnRlbXBsYXRlKTtcbiAgfVxufSwgZmFsc2UpO1xuXG5pbnRlcm5hbC53YWl0RE9NQ29udGVudExvYWRlZChmdW5jdGlvbigpIHtcbiAgcmVnaXN0ZXIoJ3NjcmlwdFt0eXBlPVwidGV4dC9vbnMtdGVtcGxhdGVcIl0nKTtcbiAgcmVnaXN0ZXIoJ3NjcmlwdFt0eXBlPVwidGV4dC90ZW1wbGF0ZVwiXScpO1xuICByZWdpc3Rlcignc2NyaXB0W3R5cGU9XCJ0ZXh0L25nLXRlbXBsYXRlXCJdJyk7XG4gIHJlZ2lzdGVyKCd0ZW1wbGF0ZScpO1xuXG4gIGZ1bmN0aW9uIHJlZ2lzdGVyKHF1ZXJ5KSB7XG4gICAgY29uc3QgdGVtcGxhdGVzID0gd2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVtcGxhdGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpbnRlcm5hbC50ZW1wbGF0ZVN0b3JlLnNldCh0ZW1wbGF0ZXNbaV0uZ2V0QXR0cmlidXRlKCdpZCcpLCB0ZW1wbGF0ZXNbaV0udGV4dENvbnRlbnQgfHwgdGVtcGxhdGVzW2ldLmNvbnRlbnQpO1xuICAgIH1cbiAgfVxufSk7XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cbmludGVybmFsLmdldFRlbXBsYXRlSFRNTEFzeW5jID0gZnVuY3Rpb24ocGFnZSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGludGVybmFsLndhaXRET01Db250ZW50TG9hZGVkKCgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gaW50ZXJuYWwudGVtcGxhdGVTdG9yZS5nZXQocGFnZSk7XG4gICAgICBpZiAoY2FjaGUpIHtcbiAgICAgICAgaWYgKGNhY2hlIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlKGNhY2hlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGh0bWwgPSB0eXBlb2YgY2FjaGUgPT09ICdzdHJpbmcnID8gY2FjaGUgOiBjYWNoZVsxXTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoaW50ZXJuYWwubm9ybWFsaXplUGFnZUhUTUwoaHRtbCkpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2NhbCA9IHdpbmRvdy5kb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYWdlKTtcbiAgICAgIGlmIChsb2NhbCkge1xuICAgICAgICBjb25zdCBodG1sID0gbG9jYWwudGV4dENvbnRlbnQgfHwgbG9jYWwuY29udGVudDtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoaHRtbCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgeGhyLm9wZW4oJ0dFVCcsIHBhZ2UsIHRydWUpO1xuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCBodG1sID0geGhyLnJlc3BvbnNlVGV4dDtcbiAgICAgICAgaWYgKHhoci5zdGF0dXMgPj0gNDAwICYmIHhoci5zdGF0dXMgPCA2MDApIHtcbiAgICAgICAgICByZWplY3QoaHRtbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVmcmVzaCBzY3JpcHQgdGFnc1xuICAgICAgICAgIGNvbnN0IGZyYWdtZW50ID0gdXRpbC5jcmVhdGVGcmFnbWVudChodG1sKTtcbiAgICAgICAgICB1dGlsLmFycmF5RnJvbShmcmFnbWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzY3JpcHQnKSkuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgICAgIHNjcmlwdC50eXBlID0gZWwudHlwZSB8fCAndGV4dC9qYXZhc2NyaXB0JztcbiAgICAgICAgICAgIHNjcmlwdC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShlbC50ZXh0IHx8IGVsLnRleHRDb250ZW50IHx8IGVsLmlubmVySFRNTCkpO1xuICAgICAgICAgICAgZWwucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoc2NyaXB0LCBlbCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpbnRlcm5hbC50ZW1wbGF0ZVN0b3JlLnNldChwYWdlLCBmcmFnbWVudCk7XG4gICAgICAgICAgcmVzb2x2ZShmcmFnbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB1dGlsLnRocm93KGBQYWdlIHRlbXBsYXRlIG5vdCBmb3VuZDogJHtwYWdlfWApO1xuICAgICAgfTtcbiAgICAgIHhoci5zZW5kKG51bGwpO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cbmludGVybmFsLmdldFBhZ2VIVE1MQXN5bmMgPSBmdW5jdGlvbihwYWdlKSB7XG4gIGNvbnN0IHBhZ2VzID0gcGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24uZXZhbHVhdGUocGFnZSk7XG5cbiAgY29uc3QgZ2V0UGFnZSA9IChwYWdlKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBwYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdNdXN0IHNwZWNpZnkgYSBwYWdlLicpO1xuICAgIH1cblxuICAgIHJldHVybiBpbnRlcm5hbC5nZXRUZW1wbGF0ZUhUTUxBc3luYyhwYWdlKVxuICAgICAgLmNhdGNoKGZ1bmN0aW9uKGVycm9yKSB7XG4gICAgICAgIGlmIChwYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGdldFBhZ2UocGFnZXMuc2hpZnQoKSk7XG4gICAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gZ2V0UGFnZShwYWdlcy5zaGlmdCgpKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGludGVybmFsO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vaW50ZXJuYWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBbmltYXRvckZhY3Rvcnkge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cy5hbmltYXRvcnMgVGhlIGRpY3Rpb25hcnkgZm9yIGFuaW1hdG9yIGNsYXNzZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0cy5iYXNlQ2xhc3MgVGhlIGJhc2UgY2xhc3Mgb2YgYW5pbWF0b3JzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0cy5iYXNlQ2xhc3NOYW1lXSBUaGUgbmFtZSBvZiB0aGUgYmFzZSBjbGFzcyBvZiBhbmltYXRvcnNcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRzLmRlZmF1bHRBbmltYXRpb25dIFRoZSBkZWZhdWx0IGFuaW1hdGlvbiBuYW1lXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5kZWZhdWx0QW5pbWF0aW9uT3B0aW9uc10gVGhlIGRlZmF1bHQgYW5pbWF0aW9uIG9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdHMpIHtcbiAgICB0aGlzLl9hbmltYXRvcnMgPSBvcHRzLmFuaW1hdG9ycztcbiAgICB0aGlzLl9iYXNlQ2xhc3MgPSBvcHRzLmJhc2VDbGFzcztcbiAgICB0aGlzLl9iYXNlQ2xhc3NOYW1lID0gb3B0cy5iYXNlQ2xhc3NOYW1lIHx8IG9wdHMuYmFzZUNsYXNzLm5hbWU7XG4gICAgdGhpcy5fYW5pbWF0aW9uID0gb3B0cy5kZWZhdWx0QW5pbWF0aW9uIHx8ICdkZWZhdWx0JztcbiAgICB0aGlzLl9hbmltYXRpb25PcHRpb25zID0gb3B0cy5kZWZhdWx0QW5pbWF0aW9uT3B0aW9ucyB8fCB7fTtcblxuICAgIGlmICghdGhpcy5fYW5pbWF0b3JzW3RoaXMuX2FuaW1hdGlvbl0pIHtcbiAgICAgIHV0aWwudGhyb3coJ05vIHN1Y2ggYW5pbWF0aW9uOiAnICsgdGhpcy5fYW5pbWF0aW9uKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IGpzb25TdHJpbmdcbiAgICogQHJldHVybiB7T2JqZWN0L251bGx9XG4gICAqL1xuICBzdGF0aWMgcGFyc2VBbmltYXRpb25PcHRpb25zU3RyaW5nKGpzb25TdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHR5cGVvZiBqc29uU3RyaW5nID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB1dGlsLmFuaW1hdGlvbk9wdGlvbnNQYXJzZShqc29uU3RyaW5nKTtcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmIHJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignXCJhbmltYXRpb24tb3B0aW9uc1wiIGF0dHJpYnV0ZSBtdXN0IGJlIGEgSlNPTiBvYmplY3Qgc3RyaW5nOiAnICsganNvblN0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7fTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdcImFuaW1hdGlvbi1vcHRpb25zXCIgYXR0cmlidXRlIG11c3QgYmUgYSBKU09OIG9iamVjdCBzdHJpbmc6ICcgKyBqc29uU3RyaW5nKTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICovXG4gIHNldEFuaW1hdGlvbk9wdGlvbnMob3B0aW9ucykge1xuICAgIHRoaXMuX2FuaW1hdGlvbk9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dIFRoZSBhbmltYXRpb24gbmFtZVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc10gVGhlIGFuaW1hdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkZWZhdWx0QW5pbWF0b3IgVGhlIGRlZmF1bHQgYW5pbWF0b3IgaW5zdGFuY2VcbiAgICogQHJldHVybiB7T2JqZWN0fSBBbiBhbmltYXRvciBpbnN0YW5jZVxuICAgKi9cbiAgbmV3QW5pbWF0b3Iob3B0aW9ucyA9IHt9LCBkZWZhdWx0QW5pbWF0b3IpIHtcblxuICAgIGxldCBhbmltYXRvciA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy5hbmltYXRpb24gaW5zdGFuY2VvZiB0aGlzLl9iYXNlQ2xhc3MpIHtcbiAgICAgIHJldHVybiBvcHRpb25zLmFuaW1hdGlvbjtcbiAgICB9XG5cbiAgICBsZXQgQW5pbWF0b3IgPSBudWxsO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLmFuaW1hdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIEFuaW1hdG9yID0gdGhpcy5fYW5pbWF0b3JzW29wdGlvbnMuYW5pbWF0aW9uXTtcbiAgICB9XG5cbiAgICBpZiAoIUFuaW1hdG9yICYmIGRlZmF1bHRBbmltYXRvcikge1xuICAgICAgYW5pbWF0b3IgPSBkZWZhdWx0QW5pbWF0b3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIEFuaW1hdG9yID0gQW5pbWF0b3IgfHwgdGhpcy5fYW5pbWF0b3JzW3RoaXMuX2FuaW1hdGlvbl07XG5cbiAgICAgIGNvbnN0IGFuaW1hdGlvbk9wdHMgPSB1dGlsLmV4dGVuZChcbiAgICAgICAge30sXG4gICAgICAgIHRoaXMuX2FuaW1hdGlvbk9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnMuYW5pbWF0aW9uT3B0aW9ucyB8fCB7fSxcbiAgICAgICAgaW50ZXJuYWwuY29uZmlnLmFuaW1hdGlvbnNEaXNhYmxlZCA/IHtkdXJhdGlvbjogMCwgZGVsYXk6IDB9IDoge31cbiAgICAgICk7XG5cbiAgICAgIGFuaW1hdG9yID0gbmV3IEFuaW1hdG9yKGFuaW1hdGlvbk9wdHMpO1xuXG4gICAgICBpZiAodHlwZW9mIGFuaW1hdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGFuaW1hdG9yID0gbmV3IGFuaW1hdG9yKGFuaW1hdGlvbk9wdHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5ldy1jYXBcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIShhbmltYXRvciBpbnN0YW5jZW9mIHRoaXMuX2Jhc2VDbGFzcykpIHtcbiAgICAgIHV0aWwudGhyb3coYFwiYW5pbWF0b3JcIiBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgJHt0aGlzLl9iYXNlQ2xhc3NOYW1lfWApO1xuICAgIH1cblxuICAgIHJldHVybiBhbmltYXRvcjtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc1BsYXRmb3JtIGZyb20gJy4vcGxhdGZvcm0nO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcblxubGV0IGF1dG9TdHlsZUVuYWJsZWQgPSB0cnVlO1xuXG4vLyBNb2RpZmllcnNcbmNvbnN0IG1vZGlmaWVyc01hcCA9IHtcbiAgJ3F1aWV0JzogJ21hdGVyaWFsLS1mbGF0JyxcbiAgJ2xpZ2h0JzogJ21hdGVyaWFsLS1mbGF0JyxcbiAgJ291dGxpbmUnOiAnbWF0ZXJpYWwtLWZsYXQnLFxuICAnY3RhJzogJycsXG4gICdsYXJnZS0tcXVpZXQnOiAnbWF0ZXJpYWwtLWZsYXQgbGFyZ2UnLFxuICAnbGFyZ2UtLWN0YSc6ICdsYXJnZScsXG4gICdub2JvcmRlcic6ICcnLFxuICAndGFwcGFibGUnOiAnJ1xufTtcblxuY29uc3QgcGxhdGZvcm1zID0ge307XG5cbnBsYXRmb3Jtcy5hbmRyb2lkID0gZWxlbWVudCA9PiB7XG5cbiAgY29uc3QgZWxlbWVudE5hbWUgPSBlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKTtcblxuICBpZiAoIXV0aWwuaGFzTW9kaWZpZXIoZWxlbWVudCwgJ21hdGVyaWFsJykpIHtcbiAgICBjb25zdCBvbGRNb2RpZmllciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdtb2RpZmllcicpIHx8ICcnO1xuXG4gICAgY29uc3QgbmV3TW9kaWZpZXIgPSBvbGRNb2RpZmllci50cmltKCkuc3BsaXQoL1xccysvKS5tYXAoZSA9PiBtb2RpZmllcnNNYXAuaGFzT3duUHJvcGVydHkoZSkgPyBtb2RpZmllcnNNYXBbZV0gOiBlKTtcbiAgICBuZXdNb2RpZmllci51bnNoaWZ0KCdtYXRlcmlhbCcpO1xuXG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJywgbmV3TW9kaWZpZXIuam9pbignICcpLnRyaW0oKSk7XG4gIH1cblxuICBjb25zdCBlbGVtZW50cyA9IFtcbiAgICAnb25zLWFsZXJ0LWRpYWxvZy1idXR0b24nLFxuICAgICdvbnMtdG9vbGJhci1idXR0b24nLFxuICAgICdvbnMtYmFjay1idXR0b24nLFxuICAgICdvbnMtYnV0dG9uJyxcbiAgICAnb25zLWxpc3QtaXRlbScsXG4gICAgJ29ucy1mYWInLFxuICAgICdvbnMtc3BlZWQtZGlhbCcsXG4gICAgJ29ucy1zcGVlZC1kaWFsLWl0ZW0nLFxuICAgICdvbnMtdGFiJ1xuICBdO1xuXG5cbiAgLy8gRWZmZWN0c1xuICBpZiAoZWxlbWVudHMuaW5kZXhPZihlbGVtZW50TmFtZSkgIT09IC0xXG4gICAgJiYgIWVsZW1lbnQuaGFzQXR0cmlidXRlKCdyaXBwbGUnKVxuICAgICYmICFlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ29ucy1yaXBwbGUnKSkge1xuXG4gICAgaWYgKGVsZW1lbnROYW1lID09PSAnb25zLWxpc3QtaXRlbScpIHtcbiAgICAgIGlmIChlbGVtZW50Lmhhc0F0dHJpYnV0ZSgndGFwcGFibGUnKSkge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgncmlwcGxlJywgJycpO1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgndGFwcGFibGUnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3JpcHBsZScsICcnKTtcbiAgICB9XG4gIH1cbn07XG5cbnBsYXRmb3Jtcy5pb3MgPSBlbGVtZW50ID0+IHtcblxuIC8vIE1vZGlmaWVyc1xuIGlmICh1dGlsLnJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsICdtYXRlcmlhbCcpKSB7XG4gICBpZiAodXRpbC5yZW1vdmVNb2RpZmllcihlbGVtZW50LCAnbWF0ZXJpYWwtLWZsYXQnKSkge1xuICAgICB1dGlsLmFkZE1vZGlmaWVyKGVsZW1lbnQsICh1dGlsLnJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsICdsYXJnZScpKSA/ICdsYXJnZS0tcXVpZXQnIDogJ3F1aWV0Jyk7XG4gICB9XG5cbiAgIGlmICghZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykpIHtcbiAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ21vZGlmaWVyJyk7XG4gICB9XG4gfVxuXG4gLy8gRWZmZWN0c1xuIGlmIChlbGVtZW50Lmhhc0F0dHJpYnV0ZSgncmlwcGxlJykpIHtcbiAgIGlmIChlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29ucy1saXN0LWl0ZW0nKSB7XG4gICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCd0YXBwYWJsZScsICcnKTtcbiAgIH1cblxuICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3JpcHBsZScpO1xuIH1cbn07XG5cbmNvbnN0IHVubG9ja2VkID0ge1xuICBhbmRyb2lkOiB0cnVlXG59O1xuXG5jb25zdCBnZXRQbGF0Zm9ybSA9IChlbGVtZW50LCBmb3JjZSkgPT4ge1xuICBpZiAoYXV0b1N0eWxlRW5hYmxlZCAmJiAhZWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGUtYXV0by1zdHlsaW5nJykpIHtcbiAgICBjb25zdCBtb2JpbGVPUyA9IG9uc1BsYXRmb3JtLmdldE1vYmlsZU9TKCk7XG4gICAgaWYgKHBsYXRmb3Jtcy5oYXNPd25Qcm9wZXJ0eShtb2JpbGVPUykgJiYgKHVubG9ja2VkLmhhc093blByb3BlcnR5KG1vYmlsZU9TKSB8fCBmb3JjZSkpIHtcbiAgICAgIHJldHVybiBtb2JpbGVPUztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5jb25zdCBwcmVwYXJlID0gKGVsZW1lbnQsIGZvcmNlKSA9PiB7XG4gIGNvbnN0IHAgPSBnZXRQbGF0Zm9ybShlbGVtZW50LCBmb3JjZSk7XG4gIHAgJiYgcGxhdGZvcm1zW3BdKGVsZW1lbnQpO1xufTtcblxuY29uc3QgbWFwTW9kaWZpZXIgPSAobW9kaWZpZXIsIGVsZW1lbnQsIGZvcmNlKSA9PiB7XG4gIGlmIChnZXRQbGF0Zm9ybShlbGVtZW50LCBmb3JjZSkpIHtcbiAgICByZXR1cm4gbW9kaWZpZXIuc3BsaXQoL1xccysvKS5tYXAobSA9PiBtb2RpZmllcnNNYXAuaGFzT3duUHJvcGVydHkobSkgPyBtb2RpZmllcnNNYXBbbV0gOiBtKS5qb2luKCcgJyk7XG4gIH1cbiAgcmV0dXJuIG1vZGlmaWVyO1xufTtcblxuY29uc3QgcmVzdG9yZU1vZGlmaWVyID0gZWxlbWVudCA9PiB7XG4gIGlmIChnZXRQbGF0Zm9ybShlbGVtZW50KSA9PT0gJ2FuZHJvaWQnKSB7XG4gICAgY29uc3QgbW9kaWZpZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSB8fCAnJztcbiAgICBsZXQgbmV3TW9kaWZpZXIgPSBtYXBNb2RpZmllcihtb2RpZmllciwgZWxlbWVudCk7XG5cbiAgICBpZiAoIS8oXnxcXHMrKW1hdGVyaWFsKCR8XFxzKykvaS50ZXN0KG1vZGlmaWVyKSkge1xuICAgICAgbmV3TW9kaWZpZXIgPSAnbWF0ZXJpYWwgJyArIG5ld01vZGlmaWVyO1xuICAgIH1cblxuICAgIGlmIChuZXdNb2RpZmllciAhPT0gbW9kaWZpZXIpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdtb2RpZmllcicsIG5ld01vZGlmaWVyLnRyaW0oKSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBpc0VuYWJsZWQ6ICgpID0+IGF1dG9TdHlsZUVuYWJsZWQsXG4gIGVuYWJsZTogKCkgPT4gYXV0b1N0eWxlRW5hYmxlZCA9IHRydWUsXG4gIGRpc2FibGU6ICgpID0+IGF1dG9TdHlsZUVuYWJsZWQgPSBmYWxzZSxcbiAgcHJlcGFyZSxcbiAgbWFwTW9kaWZpZXIsXG4gIGdldFBsYXRmb3JtLFxuICByZXN0b3JlTW9kaWZpZXJcbn07XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vYXV0b3N0eWxlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTW9kaWZpZXJVdGlsIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBsYXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjdXJyZW50XG4gICAqL1xuICBzdGF0aWMgZGlmZihsYXN0LCBjdXJyZW50KSB7XG4gICAgbGFzdCA9IG1ha2VEaWN0KCgnJyArIGxhc3QpLnRyaW0oKSk7XG4gICAgY3VycmVudCA9IG1ha2VEaWN0KCgnJyArIGN1cnJlbnQpLnRyaW0oKSk7XG5cbiAgICBjb25zdCByZW1vdmVkID0gT2JqZWN0LmtleXMobGFzdCkucmVkdWNlKChyZXN1bHQsIHRva2VuKSA9PiB7XG4gICAgICBpZiAoIWN1cnJlbnRbdG9rZW5dKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRva2VuKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgYWRkZWQgPSBPYmplY3Qua2V5cyhjdXJyZW50KS5yZWR1Y2UoKHJlc3VsdCwgdG9rZW4pID0+IHtcbiAgICAgIGlmICghbGFzdFt0b2tlbl0pIHtcbiAgICAgICAgcmVzdWx0LnB1c2godG9rZW4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LCBbXSk7XG5cbiAgICByZXR1cm4ge2FkZGVkLCByZW1vdmVkfTtcblxuICAgIGZ1bmN0aW9uIG1ha2VEaWN0KG1vZGlmaWVyKSB7XG4gICAgICBjb25zdCBkaWN0ID0ge307XG4gICAgICBNb2RpZmllclV0aWwuc3BsaXQobW9kaWZpZXIpLmZvckVhY2godG9rZW4gPT4gZGljdFt0b2tlbl0gPSB0b2tlbik7XG4gICAgICByZXR1cm4gZGljdDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpZmZcbiAgICogQHBhcmFtIHtBcnJheX0gZGlmZi5yZW1vdmVkXG4gICAqIEBwYXJhbSB7QXJyYXl9IGRpZmYuYWRkZWRcbiAgICogQHBhcmFtIHtPYmplY3R9IGNsYXNzTGlzdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdGVtcGxhdGVcbiAgICovXG4gIHN0YXRpYyBhcHBseURpZmZUb0NsYXNzTGlzdChkaWZmLCBjbGFzc0xpc3QsIHRlbXBsYXRlKSB7XG4gICAgZGlmZi5hZGRlZFxuICAgICAgLm1hcChtb2RpZmllciA9PiB0ZW1wbGF0ZS5yZXBsYWNlKC9cXCovZywgbW9kaWZpZXIpKVxuICAgICAgLmZvckVhY2goa2xhc3MgPT4ga2xhc3Muc3BsaXQoL1xccysvKS5mb3JFYWNoKGsgPT4gY2xhc3NMaXN0LmFkZChrKSkpO1xuXG4gICAgZGlmZi5yZW1vdmVkXG4gICAgICAubWFwKG1vZGlmaWVyID0+IHRlbXBsYXRlLnJlcGxhY2UoL1xcKi9nLCBtb2RpZmllcikpXG4gICAgICAuZm9yRWFjaChrbGFzcyA9PiBrbGFzcy5zcGxpdCgvXFxzKy8pLmZvckVhY2goayA9PiBjbGFzc0xpc3QucmVtb3ZlKGspKSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpZmZcbiAgICogQHBhcmFtIHtBcnJheX0gZGlmZi5yZW1vdmVkXG4gICAqIEBwYXJhbSB7QXJyYXl9IGRpZmYuYWRkZWRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gc2NoZW1lXG4gICAqL1xuICBzdGF0aWMgYXBwbHlEaWZmVG9FbGVtZW50KGRpZmYsIGVsZW1lbnQsIHNjaGVtZSkge1xuICAgIE9iamVjdC5rZXlzKHNjaGVtZSkuZm9yRWFjaChzZWxlY3RvciA9PiB7XG4gICAgICBjb25zdCB0YXJnZXRFbGVtZW50cyA9ICFzZWxlY3RvciB8fCB1dGlsLm1hdGNoKGVsZW1lbnQsIHNlbGVjdG9yKVxuICAgICAgICA/IFtlbGVtZW50XVxuICAgICAgICA6IEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbChcbiAgICAgICAgICAgIGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciksXG4gICAgICAgICAgICB0YXJnZXRFbGVtZW50ID0+ICF1dGlsLmZpbmRQYXJlbnQodGFyZ2V0RWxlbWVudCwgZWxlbWVudC50YWdOYW1lLCBwYXJlbnQgPT4gcGFyZW50ID09PSBlbGVtZW50KVxuICAgICAgICAgICk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0RWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvQ2xhc3NMaXN0KGRpZmYsIHRhcmdldEVsZW1lbnRzW2ldLmNsYXNzTGlzdCwgc2NoZW1lW3NlbGVjdG9yXSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IGxhc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IGN1cnJlbnRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gc2NoZW1lXG4gICAqL1xuICBzdGF0aWMgb25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgZWxlbWVudCwgc2NoZW1lKSB7XG4gICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvRWxlbWVudChNb2RpZmllclV0aWwuZGlmZihsYXN0LCBjdXJyZW50KSwgZWxlbWVudCwgc2NoZW1lKTtcbiAgICBhdXRvU3R5bGUucmVzdG9yZU1vZGlmaWVyKGVsZW1lbnQpO1xuICB9XG5cbiAgc3RhdGljIHJlZnJlc2goZWxlbWVudCwgc2NoZW1lKSB7XG4gICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvRWxlbWVudChNb2RpZmllclV0aWwuZGlmZignJywgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykgfHwgJycpLCBlbGVtZW50LCBzY2hlbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IHNjaGVtZVxuICAgKi9cbiAgc3RhdGljIGluaXRNb2RpZmllcihlbGVtZW50LCBzY2hlbWUpIHtcbiAgICBjb25zdCBtb2RpZmllciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdtb2RpZmllcicpO1xuICAgIGlmICh0eXBlb2YgbW9kaWZpZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgTW9kaWZpZXJVdGlsLmFwcGx5RGlmZlRvRWxlbWVudCh7XG4gICAgICByZW1vdmVkOiBbXSxcbiAgICAgIGFkZGVkOiBNb2RpZmllclV0aWwuc3BsaXQobW9kaWZpZXIpXG4gICAgfSwgZWxlbWVudCwgc2NoZW1lKTtcbiAgfVxuXG4gIHN0YXRpYyBzcGxpdChtb2RpZmllcikge1xuICAgIGlmICh0eXBlb2YgbW9kaWZpZXIgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGlmaWVyLnRyaW0oKS5zcGxpdCgvICsvKS5maWx0ZXIodG9rZW4gPT4gdG9rZW4gIT09ICcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgbW9kaWZpZXIgdG9rZW4gdG8gYW4gZWxlbWVudC5cbiAgICovXG4gIHN0YXRpYyBhZGRNb2RpZmllcihlbGVtZW50LCBtb2RpZmllclRva2VuKSB7XG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnbW9kaWZpZXInKSkge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJywgbW9kaWZpZXJUb2tlbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRva2VucyA9IE1vZGlmaWVyVXRpbC5zcGxpdChlbGVtZW50LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSk7XG4gICAgICBpZiAodG9rZW5zLmluZGV4T2YobW9kaWZpZXJUb2tlbikgPT0gLTEpIHtcbiAgICAgICAgdG9rZW5zLnB1c2gobW9kaWZpZXJUb2tlbik7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdtb2RpZmllcicsIHRva2Vucy5qb2luKCcgJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgbW9kaWZpZXIgdG9rZW4gZnJvbSBhbiBlbGVtZW50LlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsIG1vZGlmaWVyVG9rZW4pIHtcbiAgICBpZiAoZWxlbWVudC5oYXNBdHRyaWJ1dGUoJ21vZGlmaWVyJykpIHtcbiAgICAgIGNvbnN0IHRva2VucyA9IE1vZGlmaWVyVXRpbC5zcGxpdChlbGVtZW50LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSk7XG4gICAgICBjb25zdCBpbmRleCA9IHRva2Vucy5pbmRleE9mKG1vZGlmaWVyVG9rZW4pO1xuICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICB0b2tlbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJywgdG9rZW5zLmpvaW4oJyAnKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vcGxhdGZvcm0nO1xuXG5jb25zdCB1dGlsID0ge1xuICBfcmVhZHk6IGZhbHNlLFxuXG4gIF9kb21Db250ZW50TG9hZGVkOiBmYWxzZSxcblxuICBfb25ET01Db250ZW50TG9hZGVkOiAoKSA9PiB7XG4gICAgdXRpbC5fZG9tQ29udGVudExvYWRlZCA9IHRydWU7XG5cbiAgICBpZiAocGxhdGZvcm0uaXNXZWJWaWV3KCkpIHtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2VyZWFkeScsICgpID0+IHtcbiAgICAgICAgdXRpbC5fcmVhZHkgPSB0cnVlO1xuICAgICAgfSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB1dGlsLl9yZWFkeSA9IHRydWU7XG4gICAgfVxuICB9LFxuXG4gIGFkZEJhY2tCdXR0b25MaXN0ZW5lcjogZnVuY3Rpb24oZm4pIHtcbiAgICBpZiAoIXRoaXMuX2RvbUNvbnRlbnRMb2FkZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhpcyBtZXRob2QgaXMgYXZhaWxhYmxlIGFmdGVyIERPTUNvbnRlbnRMb2FkZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcmVhZHkpIHtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdiYWNrYnV0dG9uJywgZm4sIGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZXJlYWR5JywgZnVuY3Rpb24oKSB7XG4gICAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdiYWNrYnV0dG9uJywgZm4sIGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcblxuICByZW1vdmVCYWNrQnV0dG9uTGlzdGVuZXI6IGZ1bmN0aW9uKGZuKSB7XG4gICAgaWYgKCF0aGlzLl9kb21Db250ZW50TG9hZGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoaXMgbWV0aG9kIGlzIGF2YWlsYWJsZSBhZnRlciBET01Db250ZW50TG9hZGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlYWR5KSB7XG4gICAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmFja2J1dHRvbicsIGZuLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdkZXZpY2VyZWFkeScsIGZ1bmN0aW9uKCkge1xuICAgICAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignYmFja2J1dHRvbicsIGZuLCBmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsICgpID0+IHV0aWwuX29uRE9NQ29udGVudExvYWRlZCgpLCBmYWxzZSk7XG5cbmNvbnN0IEhhbmRsZXJSZXBvc2l0b3J5ID0ge1xuICBfc3RvcmU6IHt9LFxuXG4gIF9nZW5JZDogKCgpID0+IHtcbiAgICBsZXQgaSA9IDA7XG4gICAgcmV0dXJuICgpID0+IGkrKztcbiAgfSkoKSxcblxuICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGhhbmRsZXIpIHtcbiAgICBpZiAoZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQpIHtcbiAgICAgIHRoaXMucmVtb3ZlKGVsZW1lbnQpO1xuICAgIH1cbiAgICBjb25zdCBpZCA9IGVsZW1lbnQuZGF0YXNldC5kZXZpY2VCYWNrQnV0dG9uSGFuZGxlcklkID0gSGFuZGxlclJlcG9zaXRvcnkuX2dlbklkKCk7XG4gICAgdGhpcy5fc3RvcmVbaWRdID0gaGFuZGxlcjtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLl9zdG9yZVtlbGVtZW50LmRhdGFzZXQuZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZF07XG4gICAgICBkZWxldGUgZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQ7XG4gICAgfVxuICB9LFxuXG4gIGdldDogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5kYXRhc2V0LmRldmljZUJhY2tCdXR0b25IYW5kbGVySWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgaWQgPSBlbGVtZW50LmRhdGFzZXQuZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZDtcblxuICAgIGlmICghdGhpcy5fc3RvcmVbaWRdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc3RvcmVbaWRdO1xuICB9LFxuXG4gIGhhczogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5kYXRhc2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgaWQgPSBlbGVtZW50LmRhdGFzZXQuZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZDtcblxuICAgIHJldHVybiAhIXRoaXMuX3N0b3JlW2lkXTtcbiAgfVxufTtcblxuY2xhc3MgRGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9ib3VuZENhbGxiYWNrID0gdGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEVuYWJsZSB0byBoYW5kbGUgJ2JhY2tidXR0b24nIGV2ZW50cy5cbiAgICovXG4gIGVuYWJsZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzRW5hYmxlZCkge1xuICAgICAgdXRpbC5hZGRCYWNrQnV0dG9uTGlzdGVuZXIodGhpcy5fYm91bmRDYWxsYmFjayk7XG4gICAgICB0aGlzLl9pc0VuYWJsZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNhYmxlIHRvIGhhbmRsZSAnYmFja2J1dHRvbicgZXZlbnRzLlxuICAgKi9cbiAgZGlzYWJsZSgpIHtcbiAgICBpZiAodGhpcy5faXNFbmFibGVkKSB7XG4gICAgICB1dGlsLnJlbW92ZUJhY2tCdXR0b25MaXN0ZW5lcih0aGlzLl9ib3VuZENhbGxiYWNrKTtcbiAgICAgIHRoaXMuX2lzRW5hYmxlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaXJlIGEgJ2JhY2tidXR0b24nIGV2ZW50IG1hbnVhbGx5LlxuICAgKi9cbiAgZmlyZURldmljZUJhY2tCdXR0b25FdmVudCgpIHtcbiAgICBjb25zdCBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgIGV2ZW50LmluaXRFdmVudCgnYmFja2J1dHRvbicsIHRydWUsIHRydWUpO1xuICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICB9XG5cbiAgX2NhbGxiYWNrKCkge1xuICAgIHRoaXMuX2Rpc3BhdGNoRGV2aWNlQmFja0J1dHRvbkV2ZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgY3JlYXRlSGFuZGxlcihlbGVtZW50LCBjYWxsYmFjaykge1xuICAgIGlmICghKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZWxlbWVudCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEhUTUxFbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgaWYgKCEoY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2FsbGJhY2sgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBGdW5jdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZXIgPSB7XG4gICAgICBfY2FsbGJhY2s6IGNhbGxiYWNrLFxuICAgICAgX2VsZW1lbnQ6IGVsZW1lbnQsXG5cbiAgICAgIGRpc2FibGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICBIYW5kbGVyUmVwb3NpdG9yeS5yZW1vdmUoZWxlbWVudCk7XG4gICAgICB9LFxuXG4gICAgICBzZXRMaXN0ZW5lcjogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAgIH0sXG5cbiAgICAgIGVuYWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIEhhbmRsZXJSZXBvc2l0b3J5LnNldChlbGVtZW50LCB0aGlzKTtcbiAgICAgIH0sXG5cbiAgICAgIGlzRW5hYmxlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBIYW5kbGVyUmVwb3NpdG9yeS5nZXQoZWxlbWVudCkgPT09IHRoaXM7XG4gICAgICB9LFxuXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbigpIHtcbiAgICAgICAgSGFuZGxlclJlcG9zaXRvcnkucmVtb3ZlKGVsZW1lbnQpO1xuICAgICAgICB0aGlzLl9jYWxsYmFjayA9IHRoaXMuX2VsZW1lbnQgPSBudWxsO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBoYW5kbGVyLmVuYWJsZSgpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXI7XG4gIH1cblxuICBfZGlzcGF0Y2hEZXZpY2VCYWNrQnV0dG9uRXZlbnQoKSB7XG4gICAgY29uc3QgdHJlZSA9IHRoaXMuX2NhcHR1cmVUcmVlKCk7XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZmluZEhhbmRsZXJMZWFmRWxlbWVudCh0cmVlKTtcblxuICAgIGxldCBoYW5kbGVyID0gSGFuZGxlclJlcG9zaXRvcnkuZ2V0KGVsZW1lbnQpO1xuICAgIGhhbmRsZXIuX2NhbGxiYWNrKGNyZWF0ZUV2ZW50KGVsZW1lbnQpKTtcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUV2ZW50KGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9lbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBjYWxsUGFyZW50SGFuZGxlcjogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgbGV0IHBhcmVudCA9IHRoaXMuX2VsZW1lbnQucGFyZW50Tm9kZTtcblxuICAgICAgICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBIYW5kbGVyUmVwb3NpdG9yeS5nZXQocGFyZW50KTtcbiAgICAgICAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGVyLl9jYWxsYmFjayhjcmVhdGVFdmVudChwYXJlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgX2NhcHR1cmVUcmVlKCkge1xuICAgIHJldHVybiBjcmVhdGVUcmVlKGRvY3VtZW50LmJvZHkpO1xuXG4gICAgZnVuY3Rpb24gY3JlYXRlVHJlZShlbGVtZW50KSB7XG4gICAgICBjb25zdCB0cmVlID0ge1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBjaGlsZHJlbjogQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgYXJyYXlPZihlbGVtZW50LmNoaWxkcmVuKS5tYXAoZnVuY3Rpb24oY2hpbGRFbGVtZW50KSB7XG5cbiAgICAgICAgICBpZiAoY2hpbGRFbGVtZW50LnN0eWxlLmRpc3BsYXkgPT09ICdub25lJyB8fCBjaGlsZEVsZW1lbnQuX2lzU2hvd24gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGNoaWxkRWxlbWVudC5jaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgIUhhbmRsZXJSZXBvc2l0b3J5LmhhcyhjaGlsZEVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gY3JlYXRlVHJlZShjaGlsZEVsZW1lbnQpO1xuXG4gICAgICAgICAgaWYgKHJlc3VsdC5jaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgIUhhbmRsZXJSZXBvc2l0b3J5LmhhcyhyZXN1bHQuZWxlbWVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gW3Jlc3VsdF07XG4gICAgICAgIH0pKVxuICAgICAgfTtcblxuICAgICAgaWYgKCFIYW5kbGVyUmVwb3NpdG9yeS5oYXModHJlZS5lbGVtZW50KSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRyZWUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspe1xuICAgICAgICAgIGNvbnN0IHN1YlRyZWUgPSB0cmVlLmNoaWxkcmVuW2ldO1xuICAgICAgICAgIGlmIChIYW5kbGVyUmVwb3NpdG9yeS5oYXMoc3ViVHJlZS5lbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIHN1YlRyZWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cmVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFycmF5T2YodGFyZ2V0KSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRhcmdldFtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gdHJlZVxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIF9maW5kSGFuZGxlckxlYWZFbGVtZW50KHRyZWUpIHtcbiAgICByZXR1cm4gZmluZCh0cmVlKTtcblxuICAgIGZ1bmN0aW9uIGZpbmQobm9kZSkge1xuICAgICAgaWYgKG5vZGUuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBub2RlLmVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gZmluZChub2RlLmNoaWxkcmVuWzBdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5vZGUuY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGNoaWxkTm9kZSkge1xuICAgICAgICByZXR1cm4gY2hpbGROb2RlLmVsZW1lbnQ7XG4gICAgICB9KS5yZWR1Y2UoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgICAgaWYgKCFsZWZ0KSB7XG4gICAgICAgICAgcmV0dXJuIHJpZ2h0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGVmdFogPSBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShsZWZ0LCAnJykuekluZGV4LCAxMCk7XG4gICAgICAgIGNvbnN0IHJpZ2h0WiA9IHBhcnNlSW50KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHJpZ2h0LCAnJykuekluZGV4LCAxMCk7XG5cbiAgICAgICAgaWYgKCFpc05hTihsZWZ0WikgJiYgIWlzTmFOKHJpZ2h0WikpIHtcbiAgICAgICAgICByZXR1cm4gbGVmdFogPiByaWdodFogPyBsZWZ0IDogcmlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhcHR1cmluZyBiYWNrYnV0dG9uLWhhbmRsZXIgaXMgZmFpbHVyZS4nKTtcbiAgICAgIH0sIG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgRGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIoKTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi9pbnRlcm5hbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4vYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4vbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIgZnJvbSAnLi9kZXZpY2UtYmFjay1idXR0b24tZGlzcGF0Y2hlcic7XG5cbmludGVybmFsLkFuaW1hdG9yRmFjdG9yeSA9IEFuaW1hdG9yRmFjdG9yeTtcbmludGVybmFsLk1vZGlmaWVyVXRpbCA9IE1vZGlmaWVyVXRpbDtcbmludGVybmFsLmRiYkRpc3BhdGNoZXIgPSBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlcjtcblxuZXhwb3J0IGRlZmF1bHQgaW50ZXJuYWw7XG5cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbid1c2Ugc3RyaWN0JztcblxuY29uc3Qgc3RhcnRzV2l0aCA9IChzLCBjKSA9PiBzLnN1YnN0cigwLCBjLmxlbmd0aCkgPT09IGM7XG5jb25zdCBlbmRzV2l0aCA9IChzLCBjKSA9PiBzLnN1YnN0cihzLmxlbmd0aCAtIGMubGVuZ3RoLCBjLmxlbmd0aCkgPT09IGM7XG5jb25zdCB1bndyYXAgPSBzID0+IHMuc2xpY2UoMSwgLTEpO1xuY29uc3QgaXNPYmplY3RTdHJpbmcgPSBzID0+IHN0YXJ0c1dpdGgocywgJ3snKSAmJiBlbmRzV2l0aChzLCAnfScpO1xuY29uc3QgaXNBcnJheVN0cmluZyA9IHMgPT4gc3RhcnRzV2l0aChzLCAnWycpICYmIGVuZHNXaXRoKHMsICddJyk7XG5jb25zdCBpc1F1b3RlZFN0cmluZyA9IHMgPT4gKHN0YXJ0c1dpdGgocywgJ1xcJycpICYmIGVuZHNXaXRoKHMsICdcXCcnKSkgfHwgKHN0YXJ0c1dpdGgocywgJ1wiJykgJiYgZW5kc1dpdGgocywgJ1wiJykpO1xuXG5jb25zdCBlcnJvciA9ICh0b2tlbiwgc3RyaW5nLCBvcmlnaW5hbFN0cmluZykgPT4ge1xuICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdG9rZW4gXFwnJyArIHRva2VuICsgJ1xcJyBhdCBwb3NpdGlvbiAnICsgKG9yaWdpbmFsU3RyaW5nLmxlbmd0aCAtIHN0cmluZy5sZW5ndGggLSAxKSArICcgaW4gc3RyaW5nOiBcXCcnICsgb3JpZ2luYWxTdHJpbmcgKyAnXFwnJyk7XG59O1xuXG5jb25zdCBwcm9jZXNzVG9rZW4gPSAodG9rZW4sIHN0cmluZywgb3JpZ2luYWxTdHJpbmcpID0+IHtcbiAgaWYgKHRva2VuID09PSAndHJ1ZScgfHwgdG9rZW4gPT09ICdmYWxzZScpIHtcbiAgICByZXR1cm4gdG9rZW4gPT09ICd0cnVlJztcbiAgfSBlbHNlIGlmIChpc1F1b3RlZFN0cmluZyh0b2tlbikpIHtcbiAgICByZXR1cm4gdW53cmFwKHRva2VuKTtcbiAgfSBlbHNlIGlmICghaXNOYU4odG9rZW4pKSB7XG4gICAgcmV0dXJuICsodG9rZW4pO1xuICB9IGVsc2UgaWYgKGlzT2JqZWN0U3RyaW5nKHRva2VuKSkge1xuICAgIHJldHVybiBwYXJzZU9iamVjdCh1bndyYXAodG9rZW4pKTtcbiAgfSBlbHNlIGlmIChpc0FycmF5U3RyaW5nKHRva2VuKSkge1xuICAgIHJldHVybiBwYXJzZUFycmF5KHVud3JhcCh0b2tlbikpO1xuICB9IGVsc2Uge1xuICAgIGVycm9yKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgfVxufTtcblxuY29uc3QgbmV4dFRva2VuID0gKHN0cmluZykgPT4ge1xuICBzdHJpbmcgPSBzdHJpbmcudHJpbSgpO1xuICBsZXQgbGltaXQgPSBzdHJpbmcubGVuZ3RoO1xuXG4gIGlmIChzdHJpbmdbMF0gPT09ICc6JyB8fCBzdHJpbmdbMF0gPT09ICcsJykge1xuXG4gICAgbGltaXQgPSAxO1xuXG4gIH0gZWxzZSBpZiAoc3RyaW5nWzBdID09PSAneycgfHwgc3RyaW5nWzBdID09PSAnWycpIHtcblxuICAgIGNvbnN0IGMgPSBzdHJpbmcuY2hhckNvZGVBdCgwKTtcbiAgICBsZXQgbmVzdGVkT2JqZWN0ID0gMTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHN0cmluZy5jaGFyQ29kZUF0KGkpID09PSBjKSB7XG4gICAgICAgIG5lc3RlZE9iamVjdCsrO1xuICAgICAgfSBlbHNlIGlmIChzdHJpbmcuY2hhckNvZGVBdChpKSA9PT0gYyArIDIpIHtcbiAgICAgICAgbmVzdGVkT2JqZWN0LS07XG4gICAgICAgIGlmIChuZXN0ZWRPYmplY3QgPT09IDApIHtcbiAgICAgICAgICBsaW1pdCA9IGkgKyAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gIH0gZWxzZSBpZiAoc3RyaW5nWzBdID09PSAnXFwnJyB8fCBzdHJpbmdbMF0gPT09ICdcIicpIHtcblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoc3RyaW5nW2ldID09PSBzdHJpbmdbMF0pIHtcbiAgICAgICAgbGltaXQgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gIH0gZWxzZSB7XG5cbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKFsnICcsICcsJywgJzonXS5pbmRleE9mKHN0cmluZ1tpXSkgIT09IC0xKSB7XG4gICAgICAgIGxpbWl0ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gIH1cblxuICByZXR1cm4gc3RyaW5nLnNsaWNlKDAsIGxpbWl0KTtcbn07XG5cbmNvbnN0IHBhcnNlT2JqZWN0ID0gKHN0cmluZykgPT4ge1xuICBjb25zdCBpc1ZhbGlkS2V5ID0ga2V5ID0+IC9eW0EtWl8kXVtBLVowLTlfJF0qJC9pLnRlc3Qoa2V5KTtcblxuICBzdHJpbmcgPSBzdHJpbmcudHJpbSgpO1xuICBjb25zdCBvcmlnaW5hbFN0cmluZyA9IHN0cmluZztcbiAgY29uc3Qgb2JqZWN0ID0ge307XG4gIGxldCByZWFkaW5nS2V5ID0gdHJ1ZSwga2V5LCBwcmV2aW91c1Rva2VuLCB0b2tlbjtcblxuICB3aGlsZSAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICBwcmV2aW91c1Rva2VuID0gdG9rZW47XG4gICAgdG9rZW4gPSBuZXh0VG9rZW4oc3RyaW5nKTtcbiAgICBzdHJpbmcgPSBzdHJpbmcuc2xpY2UodG9rZW4ubGVuZ3RoLCBzdHJpbmcubGVuZ3RoKS50cmltKCk7XG5cbiAgICBpZiAoKHRva2VuID09PSAnOicgJiYgKCFyZWFkaW5nS2V5IHx8ICFwcmV2aW91c1Rva2VuIHx8IHByZXZpb3VzVG9rZW4gPT09ICcsJykpXG4gICAgICAgfHwgKHRva2VuID09PSAnLCcgJiYgcmVhZGluZ0tleSlcbiAgICAgICB8fCAodG9rZW4gIT09ICc6JyAmJiB0b2tlbiAhPT0gJywnICYmIChwcmV2aW91c1Rva2VuICYmIHByZXZpb3VzVG9rZW4gIT09ICcsJyAmJiBwcmV2aW91c1Rva2VuICE9PSAnOicpKSkge1xuICAgICAgZXJyb3IodG9rZW4sIHN0cmluZywgb3JpZ2luYWxTdHJpbmcpO1xuICAgIH0gZWxzZSBpZiAodG9rZW4gPT09ICc6JyAmJiByZWFkaW5nS2V5ICYmIHByZXZpb3VzVG9rZW4pIHtcbiAgICAgIHByZXZpb3VzVG9rZW4gPSBpc1F1b3RlZFN0cmluZyhwcmV2aW91c1Rva2VuKSA/IHVud3JhcChwcmV2aW91c1Rva2VuKSA6IHByZXZpb3VzVG9rZW47XG4gICAgICBpZiAoaXNWYWxpZEtleShwcmV2aW91c1Rva2VuKSkge1xuICAgICAgICBrZXkgPSBwcmV2aW91c1Rva2VuO1xuICAgICAgICByZWFkaW5nS2V5ID0gZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IHRva2VuIFxcJycgKyBwcmV2aW91c1Rva2VuICsgJ1xcJyBhdCBwb3NpdGlvbiAwIGluIHN0cmluZzogXFwnJyArIG9yaWdpbmFsU3RyaW5nICsgJ1xcJycpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodG9rZW4gPT09ICcsJyAmJiAhcmVhZGluZ0tleSAmJiBwcmV2aW91c1Rva2VuKSB7XG4gICAgICBvYmplY3Rba2V5XSA9IHByb2Nlc3NUb2tlbihwcmV2aW91c1Rva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgICAgIHJlYWRpbmdLZXkgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0b2tlbikge1xuICAgIG9iamVjdFtrZXldID0gcHJvY2Vzc1Rva2VuKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgfVxuXG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCBwYXJzZUFycmF5ID0gKHN0cmluZykgPT4ge1xuICBzdHJpbmcgPSBzdHJpbmcudHJpbSgpO1xuICBjb25zdCBvcmlnaW5hbFN0cmluZyA9IHN0cmluZztcbiAgY29uc3QgYXJyYXkgPSBbXTtcbiAgbGV0IHByZXZpb3VzVG9rZW4sIHRva2VuO1xuXG4gIHdoaWxlIChzdHJpbmcubGVuZ3RoID4gMCkge1xuICAgIHByZXZpb3VzVG9rZW4gPSB0b2tlbjtcbiAgICB0b2tlbiA9IG5leHRUb2tlbihzdHJpbmcpO1xuICAgIHN0cmluZyA9IHN0cmluZy5zbGljZSh0b2tlbi5sZW5ndGgsIHN0cmluZy5sZW5ndGgpLnRyaW0oKTtcblxuICAgIGlmICh0b2tlbiA9PT0gJywnICYmICghcHJldmlvdXNUb2tlbiB8fCBwcmV2aW91c1Rva2VuID09PSAnLCcpKSB7XG4gICAgICBlcnJvcih0b2tlbiwgc3RyaW5nLCBvcmlnaW5hbFN0cmluZyk7XG4gICAgfSBlbHNlIGlmICh0b2tlbiA9PT0gJywnKSB7XG4gICAgICBhcnJheS5wdXNoKHByb2Nlc3NUb2tlbihwcmV2aW91c1Rva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRva2VuKSB7XG4gICAgaWYgKHRva2VuICE9PSAnLCcpIHtcbiAgICAgIGFycmF5LnB1c2gocHJvY2Vzc1Rva2VuKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yKHRva2VuLCBzdHJpbmcsIG9yaWdpbmFsU3RyaW5nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXJyYXk7XG59O1xuXG5jb25zdCBwYXJzZSA9IChzdHJpbmcpID0+IHtcbiAgc3RyaW5nID0gc3RyaW5nLnRyaW0oKTtcblxuICBpZiAoaXNPYmplY3RTdHJpbmcoc3RyaW5nKSkge1xuICAgIHJldHVybiBwYXJzZU9iamVjdCh1bndyYXAoc3RyaW5nKSk7XG4gIH0gZWxzZSBpZiAoaXNBcnJheVN0cmluZyhzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHBhcnNlQXJyYXkodW53cmFwKHN0cmluZykpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignUHJvdmlkZWQgc3RyaW5nIG11c3QgYmUgb2JqZWN0IG9yIGFycmF5IGxpa2U6ICcgKyBzdHJpbmcpO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBwYXJzZTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuL2VsZW1lbnRzJztcbmltcG9ydCBzdHlsZXIgZnJvbSAnLi9zdHlsZXInO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4vaW50ZXJuYWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4vaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgYW5pbWF0aW9uT3B0aW9uc1BhcnNlIGZyb20gJy4vYW5pbWF0aW9uLW9wdGlvbnMtcGFyc2VyJztcbmltcG9ydCBwbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtJztcblxuY29uc3QgdXRpbCA9IHt9O1xuY29uc3QgZXJyb3JQcmVmaXggPSAnW09uc2VuIFVJXSc7XG5cbnV0aWwuZ2xvYmFscyA9IHtcbiAgZmFiT2Zmc2V0OiAwLFxuICBlcnJvclByZWZpeCxcbiAgc3VwcG9ydHNQYXNzaXZlOiBmYWxzZVxufTtcblxucGxhdGZvcm0uX3J1bk9uQWN0dWFsUGxhdGZvcm0oKCkgPT4ge1xuICB1dGlsLmdsb2JhbHMuYWN0dWFsTW9iaWxlT1MgPSBwbGF0Zm9ybS5nZXRNb2JpbGVPUygpO1xuICB1dGlsLmdsb2JhbHMuaXNVSVdlYlZpZXcgPSBwbGF0Zm9ybS5pc1VJV2ViVmlldygpO1xuICB1dGlsLmdsb2JhbHMuaXNXS1dlYlZpZXcgPSBwbGF0Zm9ybS5pc1dLV2ViVmlldygpO1xufSk7XG5cbnRyeSB7XG4gIGNvbnN0IG9wdHMgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xuICAgIGdldCgpIHsgdXRpbC5nbG9iYWxzLnN1cHBvcnRzUGFzc2l2ZSA9IHRydWU7IH1cbiAgfSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0ZXN0UGFzc2l2ZScsIG51bGwsIG9wdHMpO1xuICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigndGVzdFBhc3NpdmUnLCBudWxsLCBvcHRzKTtcbn0gY2F0Y2ggKGUpIHsgbnVsbDsgfVxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWwgVGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBFdmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIEV2ZW50IGhhbmRsZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0XSBFdmVudCBvcHRpb25zIChwYXNzaXZlLCBjYXB0dXJlLi4uKVxuICogQHBhcmFtIHtCb29sZWFufSBbaXNHRF0gSWYgY29tZXMgZnJvbSBHZXN0dXJlRGV0ZWN0b3IuIEp1c3QgZm9yIHRlc3RpbmcuXG4gKi9cbnV0aWwuYWRkRXZlbnRMaXN0ZW5lciA9IChlbCwgbmFtZSwgaGFuZGxlciwgb3B0LCBpc0dEKSA9PiB7XG4gIGVsLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlciwgdXRpbC5nbG9iYWxzLnN1cHBvcnRzUGFzc2l2ZSA/IG9wdCA6IChvcHQgfHwge30pLmNhcHR1cmUpO1xufTtcbnV0aWwucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IChlbCwgbmFtZSwgaGFuZGxlciwgb3B0LCBpc0dEKSA9PiB7XG4gIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlciwgdXRpbC5nbG9iYWxzLnN1cHBvcnRzUGFzc2l2ZSA/IG9wdCA6IChvcHQgfHwge30pLmNhcHR1cmUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZy9GdW5jdGlvbn0gcXVlcnkgZG90IGNsYXNzIG5hbWUgb3Igbm9kZSBuYW1lIG9yIG1hdGNoZXIgZnVuY3Rpb24uXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xudXRpbC5wcmVwYXJlUXVlcnkgPSAocXVlcnkpID0+IHtcbiAgcmV0dXJuIHF1ZXJ5IGluc3RhbmNlb2YgRnVuY3Rpb24gPyBxdWVyeSA6IChlbGVtZW50KSA9PiB1dGlsLm1hdGNoKGVsZW1lbnQsIHF1ZXJ5KTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlXG4gKiBAcGFyYW0ge1N0cmluZy9GdW5jdGlvbn0gcyBDU1MgU2VsZWN0b3IuXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG51dGlsLm1hdGNoID0gKGUsIHMpID0+IChlLm1hdGNoZXMgfHwgZS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHwgZS5tb3pNYXRjaGVzU2VsZWN0b3IgfHwgZS5tc01hdGNoZXNTZWxlY3RvcikuY2FsbChlLCBzKTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nL0Z1bmN0aW9ufSBxdWVyeSBkb3QgY2xhc3MgbmFtZSBvciBub2RlIG5hbWUgb3IgbWF0Y2hlciBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50L251bGx9XG4gKi9cbnV0aWwuZmluZENoaWxkID0gKGVsZW1lbnQsIHF1ZXJ5KSA9PiB7XG4gIGNvbnN0IG1hdGNoID0gdXRpbC5wcmVwYXJlUXVlcnkocXVlcnkpO1xuXG4gIC8vIENhdXRpb246IGBlbGVtZW50LmNoaWxkcmVuYCBpcyBgdW5kZWZpbmVkYCBpbiBzb21lIGVudmlyb25tZW50cyBpZiBgZWxlbWVudGAgaXMgYHN2Z2BcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBub2RlID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuICAgIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkgeyAvLyBwcm9jZXNzIG9ubHkgZWxlbWVudCBub2Rlc1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChtYXRjaChub2RlKSkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nL0Z1bmN0aW9ufSBxdWVyeSBkb3QgY2xhc3MgbmFtZSBvciBub2RlIG5hbWUgb3IgbWF0Y2hlciBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50L251bGx9XG4gKi9cbnV0aWwuZmluZFBhcmVudCA9IChlbGVtZW50LCBxdWVyeSwgdW50aWwpID0+IHtcbiAgY29uc3QgbWF0Y2ggPSB1dGlsLnByZXBhcmVRdWVyeShxdWVyeSk7XG5cbiAgbGV0IHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgZm9yICg7Oykge1xuICAgIGlmICghcGFyZW50IHx8IHBhcmVudCA9PT0gZG9jdW1lbnQgfHwgcGFyZW50IGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCB8fCAodW50aWwgJiYgdW50aWwocGFyZW50KSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAobWF0Y2gocGFyZW50KSkge1xuICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICB9XG4gICAgcGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG51dGlsLmlzQXR0YWNoZWQgPSBlbGVtZW50ID0+IGRvY3VtZW50LmJvZHkuY29udGFpbnMoZWxlbWVudCk7XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG51dGlsLmhhc0FueUNvbXBvbmVudEFzUGFyZW50ID0gKGVsZW1lbnQpID0+IHtcbiAgd2hpbGUgKGVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICE9PSBlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgICBpZiAoZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkubWF0Y2goLyhvbnMtbmF2aWdhdG9yfG9ucy10YWJiYXJ8b25zLW1vZGFsKS8pKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbnV0aWwuZ2V0QWxsQ2hpbGROb2RlcyA9IChlbGVtZW50KSA9PiB7XG4gIHJldHVybiBbZWxlbWVudF0uY29uY2F0KFxuICAgIC4uLkFycmF5LmZyb20oZWxlbWVudC5jaGlsZHJlbikubWFwKGNoaWxkRWwgPT4ge1xuICAgICAgcmV0dXJuIHV0aWwuZ2V0QWxsQ2hpbGROb2RlcyhjaGlsZEVsKTtcbiAgICB9KVxuICApO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xudXRpbC5pc1BhZ2VDb250cm9sID0gZWxlbWVudCA9PiBlbGVtZW50Lm5vZGVOYW1lLm1hdGNoKC9eb25zLShuYXZpZ2F0b3J8c3BsaXR0ZXJ8dGFiYmFyfHBhZ2UpJC9pKTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBhY3Rpb24gdG8gcHJvcGFnYXRlXG4gKi9cbnV0aWwucHJvcGFnYXRlQWN0aW9uID0gKGVsZW1lbnQsIGFjdGlvbikgPT4ge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkID0gZWxlbWVudC5jaGlsZE5vZGVzW2ldO1xuICAgIGlmIChjaGlsZFthY3Rpb25dIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIGNoaWxkW2FjdGlvbl0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24oY2hpbGQsIGFjdGlvbik7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgLSBzdHJpbmcgdG8gYmUgY2FtZWxpemVkXG4gKiBAcmV0dXJuIHtTdHJpbmd9IENhbWVsaXplZCBzdHJpbmdcbiAqL1xudXRpbC5jYW1lbGl6ZSA9IHN0cmluZyA9PiBzdHJpbmcudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8tKFthLXpdKS9nLCAobSwgbCkgPT4gbC50b1VwcGVyQ2FzZSgpKTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIC0gc3RyaW5nIHRvIGJlIGh5cGhlbmF0ZWRcbiAqIEByZXR1cm4ge1N0cmluZ30gSHlwaGVuYXRlZCBzdHJpbmdcbiAqL1xudXRpbC5oeXBoZW5hdGUgPSBzdHJpbmcgPT4gc3RyaW5nLnJlcGxhY2UoLyhbYS16QS1aXSkoW0EtWl0pL2csICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGVjdG9yIC0gdGFnIGFuZCBjbGFzcyBvbmx5XG4gKiBAcGFyYW0ge09iamVjdH0gc3R5bGVcbiAqIEBwYXJhbSB7RWxlbWVudH1cbiAqL1xudXRpbC5jcmVhdGUgPSAoc2VsZWN0b3IgPSAnJywgc3R5bGUgPSB7fSkgPT4ge1xuICBjb25zdCBjbGFzc0xpc3QgPSBzZWxlY3Rvci5zcGxpdCgnLicpO1xuICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChjbGFzc0xpc3Quc2hpZnQoKSB8fCAnZGl2Jyk7XG5cbiAgaWYgKGNsYXNzTGlzdC5sZW5ndGgpIHtcbiAgICBlbGVtZW50LmNsYXNzTmFtZSA9IGNsYXNzTGlzdC5qb2luKCcgJyk7XG4gIH1cblxuICBzdHlsZXIoZWxlbWVudCwgc3R5bGUpO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZ30gaHRtbFxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xudXRpbC5jcmVhdGVFbGVtZW50ID0gKGh0bWwpID0+IHtcbiAgY29uc3Qgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gIGlmIChodG1sIGluc3RhbmNlb2YgRG9jdW1lbnRGcmFnbWVudCkge1xuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuaW1wb3J0Tm9kZShodG1sLCB0cnVlKSk7XG4gIH0gZWxzZSB7XG4gICAgd3JhcHBlci5pbm5lckhUTUwgPSBodG1sLnRyaW0oKTtcbiAgfVxuXG4gIGlmICh3cmFwcGVyLmNoaWxkcmVuLmxlbmd0aCA+IDEpIHtcbiAgICB1dGlsLnRocm93KCdIVE1MIHRlbXBsYXRlIG11c3QgY29udGFpbiBhIHNpbmdsZSByb290IGVsZW1lbnQnKVxuICB9XG5cbiAgY29uc3QgZWxlbWVudCA9IHdyYXBwZXIuY2hpbGRyZW5bMF07XG4gIHdyYXBwZXIuY2hpbGRyZW5bMF0ucmVtb3ZlKCk7XG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge1N0cmluZ30gaHRtbFxuICogQHJldHVybiB7SFRNTEZyYWdtZW50fVxuICovXG51dGlsLmNyZWF0ZUZyYWdtZW50ID0gKGh0bWwpID0+IHtcbiAgY29uc3QgdGVtcGxhdGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xuICB0ZW1wbGF0ZS5pbm5lckhUTUwgPSBodG1sO1xuICByZXR1cm4gZG9jdW1lbnQuaW1wb3J0Tm9kZSh0ZW1wbGF0ZS5jb250ZW50LCB0cnVlKTtcbn07XG5cbi8qXG4gKiBAcGFyYW0ge09iamVjdH0gZHN0IERlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzcmMgU291cmNlIG9iamVjdChzKS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJlZmVyZW5jZSB0byBgZHN0YC5cbiAqL1xudXRpbC5leHRlbmQgPSAoZHN0LCAuLi5hcmdzKSA9PiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChhcmdzW2ldKSB7XG4gICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYXJnc1tpXSk7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgY29uc3Qga2V5ID0ga2V5c1tqXTtcbiAgICAgICAgZHN0W2tleV0gPSBhcmdzW2ldW2tleV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRzdDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3R9IGFycmF5TGlrZVxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbnV0aWwuYXJyYXlGcm9tID0gKGFycmF5TGlrZSkgPT4ge1xuICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFycmF5TGlrZSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfSBqc29uU3RyaW5nXG4gKiBAcGFyYW0ge09iamVjdH0gW2ZhaWxTYWZlXVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG51dGlsLnBhcnNlSlNPTk9iamVjdFNhZmVseSA9IChqc29uU3RyaW5nLCBmYWlsU2FmZSA9IHt9KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gSlNPTi5wYXJzZSgnJyArIGpzb25TdHJpbmcpO1xuICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0JyAmJiByZXN1bHQgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhaWxTYWZlO1xuICB9XG4gIHJldHVybiBmYWlsU2FmZTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGggLSBwYXRoIHN1Y2ggYXMgJ215QXBwLmNvbnRyb2xsZXJzLmRhdGEubG9hZERhdGEnXG4gKiBAcmV0dXJuIHtBbnl9IC0gd2hhdGV2ZXIgaXMgbG9jYXRlZCBhdCB0aGF0IHBhdGhcbiAqL1xudXRpbC5maW5kRnJvbVBhdGggPSAocGF0aCkgPT4ge1xuICBwYXRoID0gcGF0aC5zcGxpdCgnLicpO1xuICB2YXIgZWwgPSB3aW5kb3csIGtleTtcbiAgd2hpbGUgKGtleSA9IHBhdGguc2hpZnQoKSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWNvbmQtYXNzaWduXG4gICAgZWwgPSBlbFtrZXldO1xuICB9XG4gIHJldHVybiBlbDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY29udGFpbmVyIC0gUGFnZSBvciBwYWdlLWNvbnRhaW5lciB0aGF0IGltcGxlbWVudHMgJ3RvcFBhZ2UnXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudHxudWxsfSAtIFZpc2libGUgcGFnZSBlbGVtZW50IG9yIG51bGwgaWYgbm90IGZvdW5kLlxuICovXG51dGlsLmdldFRvcFBhZ2UgPSBjb250YWluZXIgPT4gY29udGFpbmVyICYmIChjb250YWluZXIudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnb25zLXBhZ2UnID8gY29udGFpbmVyIDogY29udGFpbmVyLnRvcFBhZ2UpIHx8IG51bGw7XG5cbi8qKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY29udGFpbmVyIC0gRWxlbWVudCB3aGVyZSB0aGUgc2VhcmNoIGJlZ2luc1xuICogQHJldHVybiB7SFRNTEVsZW1lbnR8bnVsbH0gLSBQYWdlIGVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgdmlzaWJsZSB0b29sYmFyIG9yIG51bGwuXG4gKi9cbnV0aWwuZmluZFRvb2xiYXJQYWdlID0gY29udGFpbmVyID0+IHtcbiAgY29uc3QgcGFnZSA9IHV0aWwuZ2V0VG9wUGFnZShjb250YWluZXIpO1xuXG4gIGlmIChwYWdlKSB7XG4gICAgaWYgKHBhZ2UuX2NhbkFuaW1hdGVUb29sYmFyKCkpIHtcbiAgICAgIHJldHVybiBwYWdlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFnZS5fY29udGVudEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5leHRQYWdlID0gdXRpbC5nZXRUb3BQYWdlKHBhZ2UuX2NvbnRlbnRFbGVtZW50LmNoaWxkcmVuW2ldKTtcbiAgICAgIGlmIChuZXh0UGFnZSAmJiAhL29ucy10YWJiYXIvaS50ZXN0KHBhZ2UuX2NvbnRlbnRFbGVtZW50LmNoaWxkcmVuW2ldLnRhZ05hbWUpKSB7XG4gICAgICAgIHJldHVybiB1dGlsLmZpbmRUb29sYmFyUGFnZShuZXh0UGFnZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtPYmplY3R9IFtkZXRhaWxdXG4gKiBAcmV0dXJuIHtDdXN0b21FdmVudH1cbiAqL1xudXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50ID0gKHRhcmdldCwgZXZlbnROYW1lLCBkZXRhaWwgPSB7fSkgPT4ge1xuXG4gIGNvbnN0IGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge1xuICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICBkZXRhaWw6IGRldGFpbFxuICB9KTtcblxuICBPYmplY3Qua2V5cyhkZXRhaWwpLmZvckVhY2goa2V5ID0+IHtcbiAgICBldmVudFtrZXldID0gZGV0YWlsW2tleV07XG4gIH0pO1xuXG4gIHRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcblxuICByZXR1cm4gZXZlbnQ7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gbW9kaWZpZXJOYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG51dGlsLmhhc01vZGlmaWVyID0gKHRhcmdldCwgbW9kaWZpZXJOYW1lKSA9PiB7XG4gIGlmICghdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnbW9kaWZpZXInKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBSZWdFeHAoYChefFxcXFxzKykke21vZGlmaWVyTmFtZX0oJHxcXFxccyspYCwgJ2knKS50ZXN0KHRhcmdldC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtTdHJpbmd9IG1vZGlmaWVyTmFtZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuYXV0b1N0eWxlIE1hcHMgdGhlIG1vZGlmaWVyTmFtZSB0byB0aGUgY29ycmVzcG9uZGluZyBzdHlsZWQgbW9kaWZpZXIuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucy5mb3JjZUF1dG9TdHlsZSBJZ25vcmVzIHBsYXRmb3JtIGxpbWl0YXRpb24uXG4gKiBAcmV0dXJuIHtCb29sZWFufSBXaGV0aGVyIGl0IHdhcyBhZGRlZCBvciBub3QuXG4gKi9cbnV0aWwuYWRkTW9kaWZpZXIgPSAodGFyZ2V0LCBtb2RpZmllck5hbWUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICBpZiAob3B0aW9ucy5hdXRvU3R5bGUpIHtcbiAgICBtb2RpZmllck5hbWUgPSBhdXRvU3R5bGUubWFwTW9kaWZpZXIobW9kaWZpZXJOYW1lLCB0YXJnZXQsIG9wdGlvbnMuZm9yY2VBdXRvU3R5bGUpO1xuICB9XG5cbiAgaWYgKHV0aWwuaGFzTW9kaWZpZXIodGFyZ2V0LCBtb2RpZmllck5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdGFyZ2V0LnNldEF0dHJpYnV0ZSgnbW9kaWZpZXInLCAoKHRhcmdldC5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykgfHwgJycpICsgJyAnICsgbW9kaWZpZXJOYW1lKS50cmltKCkpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXRcbiAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllck5hbWVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmF1dG9TdHlsZSBNYXBzIHRoZSBtb2RpZmllck5hbWUgdG8gdGhlIGNvcnJlc3BvbmRpbmcgc3R5bGVkIG1vZGlmaWVyLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuZm9yY2VBdXRvU3R5bGUgSWdub3JlcyBwbGF0Zm9ybSBsaW1pdGF0aW9uLlxuICogQHJldHVybiB7Qm9vbGVhbn0gV2hldGhlciBpdCB3YXMgZm91bmQgb3Igbm90LlxuICovXG51dGlsLnJlbW92ZU1vZGlmaWVyID0gKHRhcmdldCwgbW9kaWZpZXJOYW1lLCBvcHRpb25zID0ge30pID0+IHtcbiAgaWYgKG9wdGlvbnMuYXV0b1N0eWxlKSB7XG4gICAgbW9kaWZpZXJOYW1lID0gYXV0b1N0eWxlLm1hcE1vZGlmaWVyKG1vZGlmaWVyTmFtZSwgdGFyZ2V0LCBvcHRpb25zLmZvcmNlQXV0b1N0eWxlKTtcbiAgfVxuXG4gIGlmICghdGFyZ2V0LmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSB8fCAhdXRpbC5oYXNNb2RpZmllcih0YXJnZXQsIG1vZGlmaWVyTmFtZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBuZXdNb2RpZmllcnMgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdtb2RpZmllcicpLnNwbGl0KC9cXHMrLykuZmlsdGVyKG0gPT4gbSAmJiBtICE9PSBtb2RpZmllck5hbWUpO1xuICBuZXdNb2RpZmllcnMubGVuZ3RoID8gdGFyZ2V0LnNldEF0dHJpYnV0ZSgnbW9kaWZpZXInLCBuZXdNb2RpZmllcnMuam9pbignICcpKSA6IHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoJ21vZGlmaWVyJyk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtTdHJpbmd9IG1vZGlmaWVyTmFtZVxuICogQHBhcmFtIHtCb29sZWFufSBvcHRpb25zLmZvcmNlIEZvcmNlcyBtb2RpZmllciB0byBiZSBhZGRlZCBvciByZW1vdmVkLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuYXV0b1N0eWxlIE1hcHMgdGhlIG1vZGlmaWVyTmFtZSB0byB0aGUgY29ycmVzcG9uZGluZyBzdHlsZWQgbW9kaWZpZXIuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9wdGlvbnMuZm9yY2VBdXRvU3R5bGUgSWdub3JlcyBwbGF0Zm9ybSBsaW1pdGF0aW9uLlxuICogQHJldHVybiB7Qm9vbGVhbn0gV2hldGhlciBpdCB3YXMgZm91bmQgb3Igbm90LlxuICovXG51dGlsLnRvZ2dsZU1vZGlmaWVyID0gKC4uLmFyZ3MpID0+IHtcbiAgY29uc3Qgb3B0aW9ucyA9IGFyZ3MubGVuZ3RoID4gMiA/IGFyZ3NbMl0gOiB7fTtcbiAgY29uc3QgZm9yY2UgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucyA6IG9wdGlvbnMuZm9yY2U7XG5cbiAgY29uc3QgdG9nZ2xlID0gdHlwZW9mIGZvcmNlID09PSAnYm9vbGVhbicgPyBmb3JjZSA6ICF1dGlsLmhhc01vZGlmaWVyKC4uLmFyZ3MpO1xuICB0b2dnbGUgPyB1dGlsLmFkZE1vZGlmaWVyKC4uLmFyZ3MpIDogdXRpbC5yZW1vdmVNb2RpZmllciguLi5hcmdzKVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gZGVmYXVsdENsYXNzXG4gKiBAcGFyYW0ge09iamVjdH0gc2NoZW1lXG4gKi9cbnV0aWwucmVzdG9yZUNsYXNzID0gKGVsLCBkZWZhdWx0Q2xhc3MsIHNjaGVtZSkgPT4ge1xuICBkZWZhdWx0Q2xhc3Muc3BsaXQoL1xccysvKS5mb3JFYWNoKGMgPT4gYyAhPT0gJycgJiYgIWVsLmNsYXNzTGlzdC5jb250YWlucyhjKSAmJiBlbC5jbGFzc0xpc3QuYWRkKGMpKTtcbiAgZWwuaGFzQXR0cmlidXRlKCdtb2RpZmllcicpICYmIE1vZGlmaWVyVXRpbC5yZWZyZXNoKGVsLCBzY2hlbWUpO1xufVxuXG4vLyBUT0RPOiBGSVhcbnV0aWwudXBkYXRlUGFyZW50UG9zaXRpb24gPSAoZWwpID0+IHtcbiAgaWYgKCFlbC5fcGFyZW50VXBkYXRlZCAmJiBlbC5wYXJlbnRFbGVtZW50KSB7XG4gICAgaWYgKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsLnBhcmVudEVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJ3Bvc2l0aW9uJykgPT09ICdzdGF0aWMnKSB7XG4gICAgICBlbC5wYXJlbnRFbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICB9XG4gICAgZWwuX3BhcmVudFVwZGF0ZWQgPSB0cnVlO1xuICB9XG59O1xuXG51dGlsLnRvZ2dsZUF0dHJpYnV0ZSA9IChlbGVtZW50LCBuYW1lLCB2YWx1ZSkgPT4ge1xuICBpZiAodmFsdWUpIHtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyA/ICcnIDogdmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICB9XG59O1xuXG51dGlsLmJpbmRMaXN0ZW5lcnMgPSAoZWxlbWVudCwgbGlzdGVuZXJOYW1lcykgPT4ge1xuICBsaXN0ZW5lck5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgY29uc3QgYm91bmROYW1lID0gbmFtZS5yZXBsYWNlKC9eX1thLXpdLywgJ19ib3VuZCcgKyBuYW1lWzFdLnRvVXBwZXJDYXNlKCkpO1xuICAgIGVsZW1lbnRbYm91bmROYW1lXSA9IGVsZW1lbnRbYm91bmROYW1lXSB8fCBlbGVtZW50W25hbWVdLmJpbmQoZWxlbWVudCk7XG4gIH0pO1xufTtcblxudXRpbC5lYWNoID0gKG9iaiwgZikgPT4gT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGtleSA9PiBmKGtleSwgb2JqW2tleV0pKTtcblxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGhhc1JpcHBsZVxuICogQHBhcmFtIHtPYmplY3R9IGF0dHJzXG4gKi9cbnV0aWwudXBkYXRlUmlwcGxlID0gKHRhcmdldCwgaGFzUmlwcGxlLCBhdHRycyA9IHt9KSA9PiB7XG4gIGlmIChoYXNSaXBwbGUgPT09IHVuZGVmaW5lZCkge1xuICAgIGhhc1JpcHBsZSA9IHRhcmdldC5oYXNBdHRyaWJ1dGUoJ3JpcHBsZScpO1xuICB9XG5cbiAgY29uc3QgcmlwcGxlRWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRhcmdldCwgJ29ucy1yaXBwbGUnKTtcblxuICBpZiAoaGFzUmlwcGxlKSB7XG4gICAgaWYgKCFyaXBwbGVFbGVtZW50KSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb25zLXJpcHBsZScpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goa2V5ID0+IGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgYXR0cnNba2V5XSkpO1xuICAgICAgdGFyZ2V0Lmluc2VydEJlZm9yZShlbGVtZW50LCB0YXJnZXQuZmlyc3RDaGlsZCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHJpcHBsZUVsZW1lbnQpIHtcbiAgICByaXBwbGVFbGVtZW50LnJlbW92ZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7U3RyaW5nfVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG51dGlsLmFuaW1hdGlvbk9wdGlvbnNQYXJzZSA9IGFuaW1hdGlvbk9wdGlvbnNQYXJzZTtcblxuLyoqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cbnV0aWwuaXNJbnRlZ2VyID0gKHZhbHVlKSA9PiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmXG4gICAgaXNGaW5pdGUodmFsdWUpICYmXG4gICAgTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtPYmplY3R9IERlZmVycmVkIHByb21pc2UuXG4gKi9cbnV0aWwuZGVmZXIgPSAoKSA9PiB7XG4gIGNvbnN0IGRlZmVycmVkID0ge307XG4gIGRlZmVycmVkLnByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZGVmZXJyZWQucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gcmVqZWN0O1xuICB9KTtcbiAgcmV0dXJuIGRlZmVycmVkO1xufTtcblxuLyoqXG4gKiBTaG93IHdhcm5pbmdzIHdoZW4gdGhleSBhcmUgZW5hYmxlZC5cbiAqXG4gKiBAcGFyYW0geyp9IGFyZ3VtZW50cyB0byBjb25zb2xlLndhcm5cbiAqL1xudXRpbC53YXJuID0gKC4uLmFyZ3MpID0+IHtcbiAgaWYgKCFpbnRlcm5hbC5jb25maWcud2FybmluZ3NEaXNhYmxlZCkge1xuICAgIGNvbnNvbGUud2FybihlcnJvclByZWZpeCwgLi4uYXJncyk7XG4gIH1cbn07XG5cbnV0aWwudGhyb3cgPSAobWVzc2FnZSkgPT4ge1xuICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JQcmVmaXh9ICR7bWVzc2FnZX1gKTtcbn07XG5cbnV0aWwudGhyb3dBYnN0cmFjdCA9ICgpID0+IHV0aWwudGhyb3coJ0Nhbm5vdCBpbnN0YW50aWF0ZSBhYnN0cmFjdCBjbGFzcycpO1xudXRpbC50aHJvd01lbWJlciA9ICgpID0+IHV0aWwudGhyb3coJ0NsYXNzIG1lbWJlciBtdXN0IGJlIGltcGxlbWVudGVkJyk7XG51dGlsLnRocm93UGFnZUxvYWRlciA9ICgpID0+IHV0aWwudGhyb3coJ0ZpcnN0IHBhcmFtZXRlciBzaG91bGQgYmUgYW4gaW5zdGFuY2Ugb2YgUGFnZUxvYWRlcicpO1xudXRpbC50aHJvd0FuaW1hdG9yID0gKGVsKSA9PiB1dGlsLnRocm93KGBcIkFuaW1hdG9yXCIgcGFyYW0gbXVzdCBpbmhlcml0ICR7ZWx9QW5pbWF0b3JgKTtcblxuXG5jb25zdCBwcmV2ZW50ID0gZSA9PiBlLmNhbmNlbGFibGUgJiYgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4vKipcbiAqIFByZXZlbnQgc2Nyb2xsaW5nIHdoaWxlIGRyYWdpbmcgaG9yaXpvbnRhbGx5IG9uIGlPUy5cbiAqXG4gKiBAcGFyYW0ge2dkfSBHZXN0dXJlRGV0ZWN0b3IgaW5zdGFuY2VcbiAqL1xudXRpbC5pb3NQcmV2ZW50U2Nyb2xsID0gZ2QgPT4ge1xuICBpZiAodXRpbC5nbG9iYWxzLmFjdHVhbE1vYmlsZU9TID09PSAnaW9zJykge1xuICAgIGNvbnN0IGNsZWFuID0gKGUpID0+IHtcbiAgICAgIGdkLm9mZigndG91Y2htb3ZlJywgcHJldmVudCk7XG4gICAgICBnZC5vZmYoJ2RyYWdlbmQnLCBjbGVhbik7XG4gICAgfTtcblxuICAgIGdkLm9uKCd0b3VjaG1vdmUnLCBwcmV2ZW50KTtcbiAgICBnZC5vbignZHJhZ2VuZCcsIGNsZWFuKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQcmV2ZW50cyBzY3JvbGwgaW4gdW5kZXJseWluZyBwYWdlcyBvbiBpT1MuIFNlZSAjMjIyMCAjMjI3NCAjMTk0OVxuICpcbiAqIEBwYXJhbSB7ZWx9IEhUTUxFbGVtZW50IHRoYXQgcHJldmVudHMgdGhlIGV2ZW50c1xuICogQHBhcmFtIHthZGR9IEJvb2xlYW4gQWRkIG9yIHJlbW92ZSBldmVudCBsaXN0ZW5lcnNcbiAqL1xudXRpbC5pb3NQYWdlU2Nyb2xsRml4ID0gKGFkZCkgPT4geyAvLyBGdWxsIGZpeCAtIE1heSBjYXVzZSBpc3N1ZXMgd2l0aCBVSVdlYlZpZXcncyBtb21lbnR1bSBzY3JvbGxcbiAgaWYgKHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ2lvcycpIHtcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC50b2dnbGUoJ29ucy1pb3Mtc2Nyb2xsJywgYWRkKTsgLy8gQWxsb3dzIGN1c3RvbSBhbmQgbG9jYWxpemVkIGZpeGVzICgjMjI3NClcbiAgICBpZiAoIXV0aWwuZ2xvYmFscy5pc1VJV2ViVmlldyB8fCBpbnRlcm5hbC5jb25maWcuZm9yY2VVSVdlYlZpZXdTY3JvbGxGaXgpIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnRvZ2dsZSgnb25zLWlvcy1zY3JvbGwtZml4JywgYWRkKTtcbiAgICB9XG4gIH1cbn07XG51dGlsLmlvc01hc2tTY3JvbGxGaXggPSAoZWwsIGFkZCkgPT4geyAvLyBIYWxmIGZpeCAtIG9ubHkgcHJldmVudHMgc2Nyb2xsIG9uIG1hc2tzXG4gIGlmICh1dGlsLmdsb2JhbHMuaXNVSVdlYlZpZXcpIHtcbiAgICBjb25zdCBhY3Rpb24gPSAoYWRkID8gJ2FkZCcgOiAncmVtb3ZlJykgKyAnRXZlbnRMaXN0ZW5lcic7XG4gICAgZWxbYWN0aW9uXSgndG91Y2htb3ZlJywgcHJldmVudCwgZmFsc2UpO1xuICB9XG59O1xuXG4vKipcbiAqIERpc3RhbmNlIGFuZCBkZWx0YVRpbWUgZmlsdGVyIHNvbWUgd2VpcmQgZHJhZ3N0YXJ0IGV2ZW50cyB0aGF0IGFyZSBub3QgZmlyZWQgaW1tZWRpYXRlbHkuXG4gKlxuICogQHBhcmFtIHtldmVudH1cbiAqL1xudXRpbC5pc1ZhbGlkR2VzdHVyZSA9IGV2ZW50ID0+IGV2ZW50Lmdlc3R1cmUgIT09IHVuZGVmaW5lZCAmJiAoZXZlbnQuZ2VzdHVyZS5kaXN0YW5jZSA8PSAxNSB8fCBldmVudC5nZXN0dXJlLmRlbHRhVGltZSA8PSAxMDApO1xuXG51dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCA9ICguLi5lbGVtZW50TmFtZXMpID0+IHtcbiAgZWxlbWVudE5hbWVzLmZvckVhY2gobmFtZSA9PiB7XG4gICAgaWYgKCFvbnNFbGVtZW50c1tuYW1lXSkge1xuICAgICAgdXRpbC50aHJvdyhgT25zJHtuYW1lfSBpcyByZXF1aXJlZCBidXQgd2FzIG5vdCBpbXBvcnRlZCAoQ3VzdG9tIEVsZW1lbnRzKWApO1xuICAgIH1cbiAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHV0aWw7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5cbi8qKlxuICogTWluaW1hbCBhbmltYXRpb24gbGlicmFyeSBmb3IgbWFuYWdpbmcgY3NzIHRyYW5zaXRpb24gb24gbW9iaWxlIGJyb3dzZXJzLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbnZhciBUSU1FT1VUX1JBVElPID0gMS40O1xuXG52YXIgdXRpbCA9IHtcbn07XG5cbi8vIGNhcGl0YWxpemUgc3RyaW5nXG51dGlsLmNhcGl0YWxpemUgPSBmdW5jdGlvbihzdHIpIHtcbiAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3R9IHBhcmFtc1xuICogQHBhcmFtIHtTdHJpbmd9IHBhcmFtcy5wcm9wZXJ0eVxuICogQHBhcmFtIHtGbG9hdH0gcGFyYW1zLmR1cmF0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1zLnRpbWluZ1xuICovXG51dGlsLmJ1aWxkVHJhbnNpdGlvblZhbHVlID0gZnVuY3Rpb24ocGFyYW1zKSB7XG4gIHBhcmFtcy5wcm9wZXJ0eSA9IHBhcmFtcy5wcm9wZXJ0eSB8fCAnYWxsJztcbiAgcGFyYW1zLmR1cmF0aW9uID0gcGFyYW1zLmR1cmF0aW9uIHx8IDAuNDtcbiAgcGFyYW1zLnRpbWluZyA9IHBhcmFtcy50aW1pbmcgfHwgJ2xpbmVhcic7XG5cbiAgdmFyIHByb3BzID0gcGFyYW1zLnByb3BlcnR5LnNwbGl0KC8gKy8pO1xuXG4gIHJldHVybiBwcm9wcy5tYXAoZnVuY3Rpb24ocHJvcCkge1xuICAgIHJldHVybiBwcm9wICsgJyAnICsgcGFyYW1zLmR1cmF0aW9uICsgJ3MgJyArIHBhcmFtcy50aW1pbmc7XG4gIH0pLmpvaW4oJywgJyk7XG59O1xuXG4vKipcbiAqIEFkZCBhbiBldmVudCBoYW5kbGVyIG9uIFwidHJhbnNpdGlvbmVuZFwiIGV2ZW50LlxuICovXG51dGlsLm9uY2VPblRyYW5zaXRpb25FbmQgPSBmdW5jdGlvbihlbGVtZW50LCBjYWxsYmFjaykge1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7fTtcbiAgfVxuXG4gIHZhciBmbiA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaWYgKGVsZW1lbnQgPT0gZXZlbnQudGFyZ2V0KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHJlbW92ZUxpc3RlbmVycygpO1xuXG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcmVtb3ZlTGlzdGVuZXJzID0gZnVuY3Rpb24oKSB7XG4gICAgdXRpbC5fdHJhbnNpdGlvbkVuZEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50TmFtZSkge1xuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZm4sIGZhbHNlKTtcbiAgICB9KTtcbiAgfTtcblxuICB1dGlsLl90cmFuc2l0aW9uRW5kRXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnROYW1lKSB7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZm4sIGZhbHNlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlbW92ZUxpc3RlbmVycztcbn07XG5cbnV0aWwuX3RyYW5zaXRpb25FbmRFdmVudHMgPSAoZnVuY3Rpb24oKSB7XG5cbiAgaWYgKCdvbnRyYW5zaXRpb25lbmQnIGluIHdpbmRvdykge1xuICAgIHJldHVybiBbJ3RyYW5zaXRpb25lbmQnXTtcbiAgfVxuXG4gIGlmICgnb253ZWJraXR0cmFuc2l0aW9uZW5kJyBpbiB3aW5kb3cpIHtcbiAgICByZXR1cm4gWyd3ZWJraXRUcmFuc2l0aW9uRW5kJ107XG4gIH1cblxuICBpZiAodXRpbC52ZW5kb3JQcmVmaXggPT09ICd3ZWJraXQnIHx8IHV0aWwudmVuZG9yUHJlZml4ID09PSAnbycgfHwgdXRpbC52ZW5kb3JQcmVmaXggPT09ICdtb3onIHx8IHV0aWwudmVuZG9yUHJlZml4ID09PSAnbXMnKSB7XG4gICAgcmV0dXJuIFt1dGlsLnZlbmRvclByZWZpeCArICdUcmFuc2l0aW9uRW5kJywgJ3RyYW5zaXRpb25lbmQnXTtcbiAgfVxuXG4gIHJldHVybiBbXTtcbn0pKCk7XG5cbnV0aWwuX2Nzc1Byb3BlcnR5RGljdCA9IChmdW5jdGlvbigpIHtcbiAgdmFyIHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJycpO1xuICB2YXIgZGljdCA9IHt9O1xuICB2YXIgYSA9ICdBJy5jaGFyQ29kZUF0KDApO1xuICB2YXIgeiA9ICd6Jy5jaGFyQ29kZUF0KDApO1xuXG4gIHZhciB1cHBlciA9IGZ1bmN0aW9uKHMpIHtcbiAgICByZXR1cm4gcy5zdWJzdHIoMSkudG9VcHBlckNhc2UoKTtcbiAgfTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrKykge1xuXG4gICAgdmFyIGtleSA9IHN0eWxlc1tpXVxuICAgIC5yZXBsYWNlKC9eWy1dKy8sICcnKVxuICAgIC5yZXBsYWNlKC9bLV1bYS16XS9nLCB1cHBlcilcbiAgICAucmVwbGFjZSgvXm1vei8sICdNb3onKTtcblxuICAgIGlmIChhIDw9IGtleS5jaGFyQ29kZUF0KDApICYmIHogPj0ga2V5LmNoYXJDb2RlQXQoMCkpIHtcbiAgICAgIGlmIChrZXkgIT09ICdjc3NUZXh0JyAmJiBrZXkgIT09ICdwYXJlbnRUZXh0Jykge1xuICAgICAgICBkaWN0W2tleV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkaWN0O1xufSkoKTtcblxudXRpbC5oYXNDc3NQcm9wZXJ0eSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUgaW4gdXRpbC5fY3NzUHJvcGVydHlEaWN0O1xufTtcblxuLyoqXG4gKiBWZW5kb3IgcHJlZml4IGZvciBjc3MgcHJvcGVydHkuXG4gKi9cbnV0aWwudmVuZG9yUHJlZml4ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgc3R5bGVzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAnJyksXG4gICAgcHJlID0gKEFycmF5LnByb3RvdHlwZS5zbGljZVxuICAgICAgLmNhbGwoc3R5bGVzKVxuICAgICAgLmpvaW4oJycpXG4gICAgICAubWF0Y2goLy0obW96fHdlYmtpdHxtcyktLykgfHwgKHN0eWxlcy5PTGluayA9PT0gJycgJiYgWycnLCAnbyddKVxuICAgIClbMV07XG4gICAgcmV0dXJuIHByZTtcbn0pKCk7XG5cbnV0aWwuZm9yY2VMYXlvdXRBdE9uY2UgPSBmdW5jdGlvbihlbGVtZW50cywgY2FsbGJhY2spIHtcbiAgdGhpcy5iYXRjaEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIC8vIGZvcmNlIGxheW91dFxuICAgICAgZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgfSk7XG4gICAgY2FsbGJhY2soKTtcbiAgfSk7XG59O1xuXG51dGlsLmJhdGNoSW1tZWRpYXRlID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY2FsbGJhY2tzID0gW107XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNvbmNyZWF0ZUNhbGxiYWNrcyA9IGNhbGxiYWNrcy5zbGljZSgwKTtcbiAgICAgICAgY2FsbGJhY2tzID0gW107XG4gICAgICAgIGNvbmNyZWF0ZUNhbGxiYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH07XG59KSgpO1xuXG51dGlsLmJhdGNoQW5pbWF0aW9uRnJhbWUgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBjYWxsYmFja3MgPSBbXTtcblxuICB2YXIgcmFmID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgIHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgd2luZG93Lm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICB3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgIHNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJhZihmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGNvbmNyZWF0ZUNhbGxiYWNrcyA9IGNhbGxiYWNrcy5zbGljZSgwKTtcbiAgICAgICAgY2FsbGJhY2tzID0gW107XG4gICAgICAgIGNvbmNyZWF0ZUNhbGxiYWNrcy5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH07XG59KSgpO1xuXG51dGlsLnRyYW5zaXRpb25Qcm9wZXJ0eU5hbWUgPSAoZnVuY3Rpb24oKSB7XG4gIGlmICh1dGlsLmhhc0Nzc1Byb3BlcnR5KCd0cmFuc2l0aW9uRHVyYXRpb24nKSkge1xuICAgIHJldHVybiAndHJhbnNpdGlvbic7XG4gIH1cblxuICBpZiAodXRpbC5oYXNDc3NQcm9wZXJ0eSh1dGlsLnZlbmRvclByZWZpeCArICdUcmFuc2l0aW9uRHVyYXRpb24nKSkge1xuICAgIHJldHVybiB1dGlsLnZlbmRvclByZWZpeCArICdUcmFuc2l0aW9uJztcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdGF0ZScpO1xufSkoKTtcblxuXG4vKipcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqL1xudmFyIEFuaW1pdCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGRlZmF1bHRzKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBBbmltaXQpKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltaXQoZWxlbWVudCwgZGVmYXVsdHMpO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgIHRoaXMuZWxlbWVudHMgPSBbZWxlbWVudF07XG4gIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGVsZW1lbnQpID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgdGhpcy5lbGVtZW50cyA9IGVsZW1lbnQ7XG5cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYW4gYXJyYXkgb3IgYW4gaW5zdGFuY2Ugb2YgSFRNTEVsZW1lbnQuJyk7XG4gIH1cblxuICB0aGlzLmRlZmF1bHRzID0gZGVmYXVsdHM7XG4gIHRoaXMudHJhbnNpdGlvblF1ZXVlID0gW107XG4gIHRoaXMubGFzdFN0eWxlQXR0cmlidXRlRGljdCA9IFtdO1xufTtcblxuQW5pbWl0LnByb3RvdHlwZSA9IHtcblxuICAvKipcbiAgICogQHByb3BlcnR5IHtBcnJheX1cbiAgICovXG4gIHRyYW5zaXRpb25RdWV1ZTogdW5kZWZpbmVkLFxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkge0FycmF5fVxuICAgKi9cbiAgZWxlbWVudHM6IHVuZGVmaW5lZCxcblxuICAvKipcbiAgICogQHByb3BlcnR5IHtPYmplY3R9XG4gICAqL1xuICBkZWZhdWx0czogdW5kZWZpbmVkLFxuXG4gIC8qKlxuICAgKiBTdGFydCBhbmltYXRpb24gc2VxdWVuY2Ugd2l0aCBwYXNzZWQgYW5pbWF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHBsYXk6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy50cmFuc2l0aW9uUXVldWUucHVzaChmdW5jdGlvbihkb25lKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnRBbmltYXRpb24oKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIC8qKlxuICAgKiBNb3N0IG9mIHRoZSBhbmltYXRpb25zIGZvbGxvdyB0aGlzIGRlZmF1bHQgcHJvY2Vzcy5cbiAgICpcbiAgICogQHBhcmFtIHtmcm9tfSBjc3Mgb3Igb3B0aW9ucyBvYmplY3QgY29udGFpbmluZyBjc3NcbiAgICogQHBhcmFtIHt0b30gY3NzIG9yIG9wdGlvbnMgb2JqZWN0IGNvbnRhaW5pbmcgY3NzXG4gICAqIEBwYXJhbSB7ZGVsYXl9IGRlbGF5IHRvIHdhaXRcbiAgICovXG4gIGRlZmF1bHQ6IGZ1bmN0aW9uKGZyb20sIHRvLCBkZWxheSkge1xuICAgIGZ1bmN0aW9uIHN0ZXAocGFyYW1zLCBkdXJhdGlvbiwgdGltaW5nKSB7XG4gICAgICBpZiAocGFyYW1zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZHVyYXRpb24gPSBwYXJhbXMuZHVyYXRpb247XG4gICAgICB9XG4gICAgICBpZiAocGFyYW1zLnRpbWluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRpbWluZyA9IHBhcmFtcy50aW1pbmc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNzczogcGFyYW1zLmNzcyB8fCBwYXJhbXMsXG4gICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcbiAgICAgICAgdGltaW5nOiB0aW1pbmdcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2F2ZVN0eWxlKClcbiAgICAgIC5xdWV1ZShzdGVwKGZyb20sIDAsIHRoaXMuZGVmYXVsdHMudGltaW5nKSlcbiAgICAgIC53YWl0KGRlbGF5ID09PSB1bmRlZmluZWQgPyB0aGlzLmRlZmF1bHRzLmRlbGF5IDogZGVsYXkpXG4gICAgICAucXVldWUoc3RlcCh0bywgdGhpcy5kZWZhdWx0cy5kdXJhdGlvbiwgdGhpcy5kZWZhdWx0cy50aW1pbmcpKVxuICAgICAgLnJlc3RvcmVTdHlsZSgpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBRdWV1ZSB0cmFuc2l0aW9uIGFuaW1hdGlvbnMgb3Igb3RoZXIgZnVuY3Rpb24uXG4gICAqXG4gICAqIGUuZy4gYW5pbWl0KGVsdCkucXVldWUoe2NvbG9yOiAncmVkJ30pXG4gICAqIGUuZy4gYW5pbWl0KGVsdCkucXVldWUoe2NvbG9yOiAncmVkJ30sIHtkdXJhdGlvbjogMC40fSlcbiAgICogZS5nLiBhbmltaXQoZWx0KS5xdWV1ZSh7Y3NzOiB7Y29sb3I6ICdyZWQnfSwgZHVyYXRpb246IDAuMn0pXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fEFuaW1pdC5UcmFuc2l0aW9ufEZ1bmN0aW9ufSB0cmFuc2l0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICovXG4gIHF1ZXVlOiBmdW5jdGlvbih0cmFuc2l0aW9uLCBvcHRpb25zKSB7XG4gICAgdmFyIHF1ZXVlID0gdGhpcy50cmFuc2l0aW9uUXVldWU7XG5cbiAgICBpZiAodHJhbnNpdGlvbiAmJiBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zLmNzcyA9IHRyYW5zaXRpb247XG4gICAgICB0cmFuc2l0aW9uID0gbmV3IEFuaW1pdC5UcmFuc2l0aW9uKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICghKHRyYW5zaXRpb24gaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCB0cmFuc2l0aW9uIGluc3RhbmNlb2YgQW5pbWl0LlRyYW5zaXRpb24pKSB7XG4gICAgICBpZiAodHJhbnNpdGlvbi5jc3MpIHtcbiAgICAgICAgdHJhbnNpdGlvbiA9IG5ldyBBbmltaXQuVHJhbnNpdGlvbih0cmFuc2l0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYW5zaXRpb24gPSBuZXcgQW5pbWl0LlRyYW5zaXRpb24oe1xuICAgICAgICAgIGNzczogdHJhbnNpdGlvblxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHJhbnNpdGlvbiBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICBxdWV1ZS5wdXNoKHRyYW5zaXRpb24pO1xuICAgIH0gZWxzZSBpZiAodHJhbnNpdGlvbiBpbnN0YW5jZW9mIEFuaW1pdC5UcmFuc2l0aW9uKSB7XG4gICAgICBxdWV1ZS5wdXNoKHRyYW5zaXRpb24uYnVpbGQoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcmd1bWVudHMnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAvKipcbiAgICogUXVldWUgdHJhbnNpdGlvbiBhbmltYXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge0Zsb2F0fSBzZWNvbmRzXG4gICAqL1xuICB3YWl0OiBmdW5jdGlvbihzZWNvbmRzKSB7XG4gICAgaWYgKHNlY29uZHMgPiAwKSB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25RdWV1ZS5wdXNoKGZ1bmN0aW9uKGRvbmUpIHtcbiAgICAgICAgc2V0VGltZW91dChkb25lLCAxMDAwICogc2Vjb25kcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBzYXZlU3R5bGU6IGZ1bmN0aW9uKCkge1xuXG4gICAgdGhpcy50cmFuc2l0aW9uUXVldWUucHVzaChmdW5jdGlvbihkb25lKSB7XG4gICAgICB0aGlzLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGNzcyA9IHRoaXMubGFzdFN0eWxlQXR0cmlidXRlRGljdFtpbmRleF0gPSB7fTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnQuc3R5bGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjc3NbZWxlbWVudC5zdHlsZVtpXV0gPSBlbGVtZW50LnN0eWxlW2VsZW1lbnQuc3R5bGVbaV1dO1xuICAgICAgICB9XG4gICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgZG9uZSgpO1xuICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICAvKipcbiAgICogUmVzdG9yZSBlbGVtZW50J3Mgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtGbG9hdH0gW29wdGlvbnMuZHVyYXRpb25dXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50aW1pbmddXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50cmFuc2l0aW9uXVxuICAgKi9cbiAgcmVzdG9yZVN0eWxlOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKG9wdGlvbnMudHJhbnNpdGlvbiAmJiAhb3B0aW9ucy5kdXJhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcIm9wdGlvbnMuZHVyYXRpb25cIiBpcyByZXF1aXJlZCB3aGVuIFwib3B0aW9ucy50cmFuc2l0aW9uXCIgaXMgZW5hYmxlZC4nKTtcbiAgICB9XG5cbiAgICB2YXIgdHJhbnNpdGlvbk5hbWUgPSB1dGlsLnRyYW5zaXRpb25Qcm9wZXJ0eU5hbWU7XG5cbiAgICBpZiAob3B0aW9ucy50cmFuc2l0aW9uIHx8IChvcHRpb25zLmR1cmF0aW9uICYmIG9wdGlvbnMuZHVyYXRpb24gPiAwKSkge1xuICAgICAgdmFyIHRyYW5zaXRpb25WYWx1ZSA9IG9wdGlvbnMudHJhbnNpdGlvbiB8fCAoJ2FsbCAnICsgb3B0aW9ucy5kdXJhdGlvbiArICdzICcgKyAob3B0aW9ucy50aW1pbmcgfHwgJ2xpbmVhcicpKTtcblxuICAgICAgdGhpcy50cmFuc2l0aW9uUXVldWUucHVzaChmdW5jdGlvbihkb25lKSB7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMuZWxlbWVudHM7XG4gICAgICAgIHZhciB0aW1lb3V0SWQ7XG5cbiAgICAgICAgdmFyIGNsZWFyVHJhbnNpdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZVt0cmFuc2l0aW9uTmFtZV0gPSAnJztcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBhZGQgXCJ0cmFuc2l0aW9uZW5kXCIgZXZlbnQgaGFuZGxlclxuICAgICAgICB2YXIgcmVtb3ZlTGlzdGVuZXJzID0gdXRpbC5vbmNlT25UcmFuc2l0aW9uRW5kKGVsZW1lbnRzWzBdLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgICBjbGVhclRyYW5zaXRpb24oKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGZvciBmYWlsIHNhZmUuXG4gICAgICAgIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmVtb3ZlTGlzdGVuZXJzKCk7XG4gICAgICAgICAgY2xlYXJUcmFuc2l0aW9uKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9LCBvcHRpb25zLmR1cmF0aW9uICogMTAwMCAqIFRJTUVPVVRfUkFUSU8pO1xuXG4gICAgICAgIC8vIHRyYW5zaXRpb24gYW5kIHN0eWxlIHNldHRpbmdzXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcblxuICAgICAgICAgIHZhciBjc3MgPSBzZWxmLmxhc3RTdHlsZUF0dHJpYnV0ZURpY3RbaW5kZXhdO1xuXG4gICAgICAgICAgaWYgKCFjc3MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncmVzdG9yZVN0eWxlKCk6IFRoZSBzdHlsZSBpcyBub3Qgc2F2ZWQuIEludm9rZSBzYXZlU3R5bGUoKSBiZWZvcmUuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2VsZi5sYXN0U3R5bGVBdHRyaWJ1dGVEaWN0W2luZGV4XSA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgIHZhciBuYW1lO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbGVtZW50LnN0eWxlLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBuYW1lID0gZWxlbWVudC5zdHlsZVtpXTtcbiAgICAgICAgICAgIGlmIChjc3NbbmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBjc3NbbmFtZV0gPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbGVtZW50LnN0eWxlW3RyYW5zaXRpb25OYW1lXSA9IHRyYW5zaXRpb25WYWx1ZTtcblxuICAgICAgICAgIE9iamVjdC5rZXlzKGNzcykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICAgIGlmIChrZXkgIT09IHRyYW5zaXRpb25OYW1lKSB7XG4gICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IGNzc1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZWxlbWVudC5zdHlsZVt0cmFuc2l0aW9uTmFtZV0gPSB0cmFuc2l0aW9uVmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudHJhbnNpdGlvblF1ZXVlLnB1c2goZnVuY3Rpb24oZG9uZSkge1xuICAgICAgICByZXNldCgpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcblxuICAgIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgICAgLy8gQ2xlYXIgdHJhbnNpdGlvbiBhbmltYXRpb24gc2V0dGluZ3MuXG4gICAgICBzZWxmLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZVt0cmFuc2l0aW9uTmFtZV0gPSAnbm9uZSc7XG5cbiAgICAgICAgdmFyIGNzcyA9IHNlbGYubGFzdFN0eWxlQXR0cmlidXRlRGljdFtpbmRleF07XG5cbiAgICAgICAgaWYgKCFjc3MpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jlc3RvcmVTdHlsZSgpOiBUaGUgc3R5bGUgaXMgbm90IHNhdmVkLiBJbnZva2Ugc2F2ZVN0eWxlKCkgYmVmb3JlLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZi5sYXN0U3R5bGVBdHRyaWJ1dGVEaWN0W2luZGV4XSA9IHVuZGVmaW5lZDtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbmFtZSA9ICcnOyBpIDwgZWxlbWVudC5zdHlsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG5hbWUgPSBlbGVtZW50LnN0eWxlW2ldO1xuICAgICAgICAgIGlmICh0eXBlb2YgY3NzW2VsZW1lbnQuc3R5bGVbaV1dID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgY3NzW2VsZW1lbnQuc3R5bGVbaV1dID0gJyc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgT2JqZWN0LmtleXMoY3NzKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgICAgICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IGNzc1trZXldO1xuICAgICAgICB9KTtcblxuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTdGFydCBhbmltYXRpb24gc2VxdWVuY2UuXG4gICAqL1xuICBzdGFydEFuaW1hdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fZGVxdWV1ZVRyYW5zaXRpb24oKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIF9kZXF1ZXVlVHJhbnNpdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRyYW5zaXRpb24gPSB0aGlzLnRyYW5zaXRpb25RdWV1ZS5zaGlmdCgpO1xuICAgIGlmICh0aGlzLl9jdXJyZW50VHJhbnNpdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDdXJyZW50IHRyYW5zaXRpb24gZXhpc3RzLicpO1xuICAgIH1cbiAgICB0aGlzLl9jdXJyZW50VHJhbnNpdGlvbiA9IHRyYW5zaXRpb247XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBjYWxsZWQgPSBmYWxzZTtcblxuICAgIHZhciBkb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICBzZWxmLl9jdXJyZW50VHJhbnNpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgc2VsZi5fZGVxdWV1ZVRyYW5zaXRpb24oKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdGF0ZTogVGhpcyBjYWxsYmFjayBpcyBjYWxsZWQgdHdpY2UuJyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0cmFuc2l0aW9uKSB7XG4gICAgICB0cmFuc2l0aW9uLmNhbGwodGhpcywgZG9uZSk7XG4gICAgfVxuICB9XG5cbn07XG5cbi8qKlxuICogQHBhcmFtIHtBbmltaXR9IGFyZ3VtZW50c1xuICovXG5BbmltaXQucnVuQWxsID0gZnVuY3Rpb24oLyogYXJndW1lbnRzLi4uICovKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgYXJndW1lbnRzW2ldLnBsYXkoKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0Zsb2F0fSBbb3B0aW9ucy5kdXJhdGlvbl1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5wcm9wZXJ0eV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50aW1pbmddXG4gKi9cbkFuaW1pdC5UcmFuc2l0aW9uID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICB0aGlzLm9wdGlvbnMuZHVyYXRpb24gPSB0aGlzLm9wdGlvbnMuZHVyYXRpb24gfHwgMDtcbiAgdGhpcy5vcHRpb25zLnRpbWluZyA9IHRoaXMub3B0aW9ucy50aW1pbmcgfHwgJ2xpbmVhcic7XG4gIHRoaXMub3B0aW9ucy5jc3MgPSB0aGlzLm9wdGlvbnMuY3NzIHx8IHt9O1xuICB0aGlzLm9wdGlvbnMucHJvcGVydHkgPSB0aGlzLm9wdGlvbnMucHJvcGVydHkgfHwgJ2FsbCc7XG59O1xuXG5BbmltaXQuVHJhbnNpdGlvbi5wcm90b3R5cGUgPSB7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuICBidWlsZDogZnVuY3Rpb24oKSB7XG5cbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5vcHRpb25zLmNzcykubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29wdGlvbnMuY3NzIGlzIHJlcXVpcmVkLicpO1xuICAgIH1cblxuICAgIHZhciBjc3MgPSBjcmVhdGVBY3R1YWxDc3NQcm9wcyh0aGlzLm9wdGlvbnMuY3NzKTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZHVyYXRpb24gPiAwKSB7XG4gICAgICB2YXIgdHJhbnNpdGlvblZhbHVlID0gdXRpbC5idWlsZFRyYW5zaXRpb25WYWx1ZSh0aGlzLm9wdGlvbnMpO1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50cztcbiAgICAgICAgdmFyIHRpbWVvdXQgPSBzZWxmLm9wdGlvbnMuZHVyYXRpb24gKiAxMDAwICogVElNRU9VVF9SQVRJTztcbiAgICAgICAgdmFyIHRpbWVvdXRJZDtcblxuICAgICAgICB2YXIgcmVtb3ZlTGlzdGVuZXJzID0gdXRpbC5vbmNlT25UcmFuc2l0aW9uRW5kKGVsZW1lbnRzWzBdLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dElkKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJlbW92ZUxpc3RlbmVycygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgIGVsZW1lbnQuc3R5bGVbdXRpbC50cmFuc2l0aW9uUHJvcGVydHlOYW1lXSA9IHRyYW5zaXRpb25WYWx1ZTtcblxuICAgICAgICAgIE9iamVjdC5rZXlzKGNzcykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW25hbWVdID0gY3NzW25hbWVdO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmR1cmF0aW9uIDw9IDApIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihjYWxsYmFjaykge1xuICAgICAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzO1xuXG4gICAgICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgIGVsZW1lbnQuc3R5bGVbdXRpbC50cmFuc2l0aW9uUHJvcGVydHlOYW1lXSA9ICcnO1xuXG4gICAgICAgICAgT2JqZWN0LmtleXMoY3NzKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGVbbmFtZV0gPSBjc3NbbmFtZV07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdXRpbC5mb3JjZUxheW91dEF0T25jZShlbGVtZW50cywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB1dGlsLmJhdGNoQW5pbWF0aW9uRnJhbWUoY2FsbGJhY2spO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHV0aWwuYmF0Y2hBbmltYXRpb25GcmFtZShjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlQWN0dWFsQ3NzUHJvcHMoY3NzKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG5cbiAgICAgIE9iamVjdC5rZXlzKGNzcykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGNzc1tuYW1lXTtcblxuICAgICAgICBpZiAodXRpbC5oYXNDc3NQcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcmVmaXhlZCA9IHV0aWwudmVuZG9yUHJlZml4ICsgdXRpbC5jYXBpdGFsaXplKG5hbWUpO1xuICAgICAgICBpZiAodXRpbC5oYXNDc3NQcm9wZXJ0eShwcmVmaXhlZCkpIHtcbiAgICAgICAgICByZXN1bHRbcHJlZml4ZWRdID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W3ByZWZpeGVkXSA9IHZhbHVlO1xuICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgQW5pbWl0O1xuXG4iLCIvKlxuICogR2VzdHVyZSBkZXRlY3RvciBsaWJyYXJ5IHRoYXQgZm9ya2VkIGZyb20gZ2l0aHViLmNvbS9FaWdodE1lZGlhL2hhbW1lci5qcy5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmltcG9ydCB1dGlsIGZyb20gJy4vdXRpbCc7XG5cbnZhciBFdmVudCwgVXRpbHMsIERldGVjdGlvbiwgUG9pbnRlckV2ZW50O1xuXG4vKipcbiAqIEBvYmplY3Qgb25zLkdlc3R1cmVEZXRlY3RvclxuICogQGNhdGVnb3J5IGdlc3R1cmVcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dVXRpbGl0eSBjbGFzcyBmb3IgZ2VzdHVyZSBkZXRlY3Rpb24uWy9lbl1cbiAqICAgW2phXeOCuOOCp+OCueODgeODo+OCkuaknOefpeOBmeOCi+OBn+OCgeOBruODpuODvOODhuOCo+ODquODhuOCo+OCr+ODqeOCueOBp+OBmeOAglsvamFdXG4gKi9cblxuLyoqXG4gKiBAbWV0aG9kIGNvbnN0cnVjdG9yXG4gKiBAc2lnbmF0dXJlIGNvbnN0cnVjdG9yKGVsZW1lbnRbLCBvcHRpb25zXSlcbiAqIEBkZXNjcmlwdGlvblxuICogIFtlbl1DcmVhdGUgYSBuZXcgR2VzdHVyZURldGVjdG9yIGluc3RhbmNlLlsvZW5dXG4gKiAgW2phXUdlc3R1cmVEZXRlY3RvcuOBruOCpOODs+OCueOCv+ODs+OCueOCkueUn+aIkOOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqICAgW2VuXU5hbWUgb2YgdGhlIGV2ZW50LlsvZW5dXG4gKiAgIFtqYV3jgrjjgqfjgrnjg4Hjg6PjgpLmpJznn6XjgZnjgotET03opoHntKDjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dT3B0aW9ucyBvYmplY3QuWy9lbl1cbiAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcmV0dXJuIHtvbnMuR2VzdHVyZURldGVjdG9yLkluc3RhbmNlfVxuICovXG52YXIgR2VzdHVyZURldGVjdG9yID0gZnVuY3Rpb24gR2VzdHVyZURldGVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBHZXN0dXJlRGV0ZWN0b3IuSW5zdGFuY2UoZWxlbWVudCwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5cbi8qKlxuICogZGVmYXVsdCBzZXR0aW5ncy5cbiAqIG1vcmUgc2V0dGluZ3MgYXJlIGRlZmluZWQgcGVyIGdlc3R1cmUgYXQgYC9nZXN0dXJlc2AuIEVhY2ggZ2VzdHVyZSBjYW4gYmUgZGlzYWJsZWQvZW5hYmxlZFxuICogYnkgc2V0dGluZyBpdCdzIG5hbWUgKGxpa2UgYHN3aXBlYCkgdG8gZmFsc2UuXG4gKiBZb3UgY2FuIHNldCB0aGUgZGVmYXVsdHMgZm9yIGFsbCBpbnN0YW5jZXMgYnkgY2hhbmdpbmcgdGhpcyBvYmplY3QgYmVmb3JlIGNyZWF0aW5nIGFuIGluc3RhbmNlLlxuICogQGV4YW1wbGVcbiAqIGBgYGBcbiAqICBHZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHMuZHJhZyA9IGZhbHNlO1xuICogIEdlc3R1cmVEZXRlY3Rvci5kZWZhdWx0cy5iZWhhdmlvci50b3VjaEFjdGlvbiA9ICdwYW4teSc7XG4gKiAgZGVsZXRlIEdlc3R1cmVEZXRlY3Rvci5kZWZhdWx0cy5iZWhhdmlvci51c2VyU2VsZWN0O1xuICogYGBgYFxuICogQHByb3BlcnR5IGRlZmF1bHRzXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5HZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHMgPSB7XG4gIGJlaGF2aW9yOiB7XG4gICAgLy8gdXNlclNlbGVjdDogJ25vbmUnLCAvLyBBbHNvIGRpc2FibGVzIHNlbGVjdGlvbiBpbiBgaW5wdXRgIGNoaWxkcmVuXG4gICAgdG91Y2hBY3Rpb246ICdwYW4teScsXG4gICAgdG91Y2hDYWxsb3V0OiAnbm9uZScsXG4gICAgY29udGVudFpvb21pbmc6ICdub25lJyxcbiAgICB1c2VyRHJhZzogJ25vbmUnLFxuICAgIHRhcEhpZ2hsaWdodENvbG9yOiAncmdiYSgwLDAsMCwwKSdcbiAgfVxufTtcblxuLyoqXG4gKiBHZXN0dXJlRGV0ZWN0b3IgZG9jdW1lbnQgd2hlcmUgdGhlIGJhc2UgZXZlbnRzIGFyZSBhZGRlZCBhdFxuICogQHByb3BlcnR5IERPQ1VNRU5UXG4gKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gKiBAZGVmYXVsdCB3aW5kb3cuZG9jdW1lbnRcbiAqL1xuR2VzdHVyZURldGVjdG9yLkRPQ1VNRU5UID0gZG9jdW1lbnQ7XG5cbi8qKlxuICogZGV0ZWN0IHN1cHBvcnQgZm9yIHBvaW50ZXIgZXZlbnRzXG4gKiBAcHJvcGVydHkgSEFTX1BPSU5URVJFVkVOVFNcbiAqIEB0eXBlIHtCb29sZWFufVxuICovXG5HZXN0dXJlRGV0ZWN0b3IuSEFTX1BPSU5URVJFVkVOVFMgPSBuYXZpZ2F0b3IucG9pbnRlckVuYWJsZWQgfHwgbmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQ7XG5cbi8qKlxuICogZGV0ZWN0IHN1cHBvcnQgZm9yIHRvdWNoIGV2ZW50c1xuICogQHByb3BlcnR5IEhBU19UT1VDSEVWRU5UU1xuICogQHR5cGUge0Jvb2xlYW59XG4gKi9cbkdlc3R1cmVEZXRlY3Rvci5IQVNfVE9VQ0hFVkVOVFMgPSAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KTtcblxuLyoqXG4gKiBkZXRlY3QgbW9iaWxlIGJyb3dzZXJzXG4gKiBAcHJvcGVydHkgSVNfTU9CSUxFXG4gKiBAdHlwZSB7Qm9vbGVhbn1cbiAqL1xuR2VzdHVyZURldGVjdG9yLklTX01PQklMRSA9IC9tb2JpbGV8dGFibGV0fGlwKGFkfGhvbmV8b2QpfGFuZHJvaWR8c2lsay9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cbi8qKlxuICogZGV0ZWN0IGlmIHdlIHdhbnQgdG8gc3VwcG9ydCBtb3VzZWV2ZW50cyBhdCBhbGxcbiAqIEBwcm9wZXJ0eSBOT19NT1VTRUVWRU5UU1xuICogQHR5cGUge0Jvb2xlYW59XG4gKi9cbkdlc3R1cmVEZXRlY3Rvci5OT19NT1VTRUVWRU5UUyA9IChHZXN0dXJlRGV0ZWN0b3IuSEFTX1RPVUNIRVZFTlRTICYmIEdlc3R1cmVEZXRlY3Rvci5JU19NT0JJTEUpIHx8IEdlc3R1cmVEZXRlY3Rvci5IQVNfUE9JTlRFUkVWRU5UUztcblxuLyoqXG4gKiBpbnRlcnZhbCBpbiB3aGljaCBHZXN0dXJlRGV0ZWN0b3IgcmVjYWxjdWxhdGVzIGN1cnJlbnQgdmVsb2NpdHkvZGlyZWN0aW9uL2FuZ2xlIGluIG1zXG4gKiBAcHJvcGVydHkgQ0FMQ1VMQVRFX0lOVEVSVkFMXG4gKiBAdHlwZSB7TnVtYmVyfVxuICogQGRlZmF1bHQgMjVcbiAqL1xuR2VzdHVyZURldGVjdG9yLkNBTENVTEFURV9JTlRFUlZBTCA9IDI1O1xuXG4vKipcbiAqIGV2ZW50dHlwZXMgcGVyIHRvdWNoZXZlbnQgKHN0YXJ0LCBtb3ZlLCBlbmQpIGFyZSBmaWxsZWQgYnkgYEV2ZW50LmRldGVybWluZUV2ZW50VHlwZXNgIG9uIGBzZXR1cGBcbiAqIHRoZSBvYmplY3QgY29udGFpbnMgdGhlIERPTSBldmVudCBuYW1lcyBwZXIgdHlwZSAoYEVWRU5UX1NUQVJUYCwgYEVWRU5UX01PVkVgLCBgRVZFTlRfRU5EYClcbiAqIEBwcm9wZXJ0eSBFVkVOVF9UWVBFU1xuICogQHByaXZhdGVcbiAqIEB3cml0ZU9uY2VcbiAqIEB0eXBlIHtPYmplY3R9XG4gKi9cbnZhciBFVkVOVF9UWVBFUyA9IHt9O1xuXG4vKipcbiAqIGRpcmVjdGlvbiBzdHJpbmdzLCBmb3Igc2FmZSBjb21wYXJpc29uc1xuICogQHByb3BlcnR5IERJUkVDVElPTl9ET1dOfExFRlR8VVB8UklHSFRcbiAqIEBmaW5hbFxuICogQHR5cGUge1N0cmluZ31cbiAqIEBkZWZhdWx0ICdkb3duJyAnbGVmdCcgJ3VwJyAncmlnaHQnXG4gKi9cbnZhciBESVJFQ1RJT05fRE9XTiA9IEdlc3R1cmVEZXRlY3Rvci5ESVJFQ1RJT05fRE9XTiA9ICdkb3duJztcbnZhciBESVJFQ1RJT05fTEVGVCA9IEdlc3R1cmVEZXRlY3Rvci5ESVJFQ1RJT05fTEVGVCA9ICdsZWZ0JztcbnZhciBESVJFQ1RJT05fVVAgPSBHZXN0dXJlRGV0ZWN0b3IuRElSRUNUSU9OX1VQID0gJ3VwJztcbnZhciBESVJFQ1RJT05fUklHSFQgPSBHZXN0dXJlRGV0ZWN0b3IuRElSRUNUSU9OX1JJR0hUID0gJ3JpZ2h0JztcblxuLyoqXG4gKiBwb2ludGVydHlwZSBzdHJpbmdzLCBmb3Igc2FmZSBjb21wYXJpc29uc1xuICogQHByb3BlcnR5IFBPSU5URVJfTU9VU0V8VE9VQ0h8UEVOXG4gKiBAZmluYWxcbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAZGVmYXVsdCAnbW91c2UnICd0b3VjaCcgJ3BlbidcbiAqL1xudmFyIFBPSU5URVJfTU9VU0UgPSBHZXN0dXJlRGV0ZWN0b3IuUE9JTlRFUl9NT1VTRSA9ICdtb3VzZSc7XG52YXIgUE9JTlRFUl9UT1VDSCA9IEdlc3R1cmVEZXRlY3Rvci5QT0lOVEVSX1RPVUNIID0gJ3RvdWNoJztcbnZhciBQT0lOVEVSX1BFTiA9IEdlc3R1cmVEZXRlY3Rvci5QT0lOVEVSX1BFTiA9ICdwZW4nO1xuXG4vKipcbiAqIGV2ZW50dHlwZXNcbiAqIEBwcm9wZXJ0eSBFVkVOVF9TVEFSVHxNT1ZFfEVORHxSRUxFQVNFfFRPVUNIXG4gKiBAZmluYWxcbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAZGVmYXVsdCAnc3RhcnQnICdjaGFuZ2UnICdtb3ZlJyAnZW5kJyAncmVsZWFzZScgJ3RvdWNoJ1xuICovXG52YXIgRVZFTlRfU1RBUlQgPSBHZXN0dXJlRGV0ZWN0b3IuRVZFTlRfU1RBUlQgPSAnc3RhcnQnO1xudmFyIEVWRU5UX01PVkUgPSBHZXN0dXJlRGV0ZWN0b3IuRVZFTlRfTU9WRSA9ICdtb3ZlJztcbnZhciBFVkVOVF9FTkQgPSBHZXN0dXJlRGV0ZWN0b3IuRVZFTlRfRU5EID0gJ2VuZCc7XG52YXIgRVZFTlRfUkVMRUFTRSA9IEdlc3R1cmVEZXRlY3Rvci5FVkVOVF9SRUxFQVNFID0gJ3JlbGVhc2UnO1xudmFyIEVWRU5UX1RPVUNIID0gR2VzdHVyZURldGVjdG9yLkVWRU5UX1RPVUNIID0gJ3RvdWNoJztcblxuLyoqXG4gKiBpZiB0aGUgd2luZG93IGV2ZW50cyBhcmUgc2V0Li4uXG4gKiBAcHJvcGVydHkgUkVBRFlcbiAqIEB3cml0ZU9uY2VcbiAqIEB0eXBlIHtCb29sZWFufVxuICogQGRlZmF1bHQgZmFsc2VcbiAqL1xuR2VzdHVyZURldGVjdG9yLlJFQURZID0gZmFsc2U7XG5cbi8qKlxuICogcGx1Z2lucyBuYW1lc3BhY2VcbiAqIEBwcm9wZXJ0eSBwbHVnaW5zXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5HZXN0dXJlRGV0ZWN0b3IucGx1Z2lucyA9IEdlc3R1cmVEZXRlY3Rvci5wbHVnaW5zIHx8IHt9O1xuXG4vKipcbiAqIGdlc3R1cmVzIG5hbWVzcGFjZVxuICogc2VlIGAvZ2VzdHVyZXNgIGZvciB0aGUgZGVmaW5pdGlvbnNcbiAqIEBwcm9wZXJ0eSBnZXN0dXJlc1xuICogQHR5cGUge09iamVjdH1cbiAqL1xuR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzID0gR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzIHx8IHt9O1xuXG4vKipcbiAqIHNldHVwIGV2ZW50cyB0byBkZXRlY3QgZ2VzdHVyZXMgb24gdGhlIGRvY3VtZW50XG4gKiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIGNyZWF0aW5nIGFuIG5ldyBpbnN0YW5jZVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2V0dXAob3B0cykge1xuICBpZiAoR2VzdHVyZURldGVjdG9yLlJFQURZKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZmluZCB3aGF0IGV2ZW50dHlwZXMgd2UgYWRkIGxpc3RlbmVycyB0b1xuICBFdmVudC5kZXRlcm1pbmVFdmVudFR5cGVzKCk7XG5cbiAgLy8gUmVnaXN0ZXIgYWxsIGdlc3R1cmVzIGluc2lkZSBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZXNcbiAgVXRpbHMuZWFjaChHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZXMsIGZ1bmN0aW9uKGdlc3R1cmUpIHtcbiAgICBEZXRlY3Rpb24ucmVnaXN0ZXIoZ2VzdHVyZSk7XG4gIH0pO1xuXG4gIC8vIEFkZCB0b3VjaCBldmVudHMgb24gdGhlIGRvY3VtZW50XG4gIEV2ZW50Lm9uVG91Y2goR2VzdHVyZURldGVjdG9yLkRPQ1VNRU5ULCBFVkVOVF9NT1ZFLCBEZXRlY3Rpb24uZGV0ZWN0LCBvcHRzKTtcbiAgRXZlbnQub25Ub3VjaChHZXN0dXJlRGV0ZWN0b3IuRE9DVU1FTlQsIEVWRU5UX0VORCwgRGV0ZWN0aW9uLmRldGVjdCwgb3B0cyk7XG5cbiAgLy8gR2VzdHVyZURldGVjdG9yIGlzIHJlYWR5Li4uIVxuICBHZXN0dXJlRGV0ZWN0b3IuUkVBRFkgPSB0cnVlO1xufVxuXG4vKipcbiAqIEBtb2R1bGUgR2VzdHVyZURldGVjdG9yXG4gKlxuICogQGNsYXNzIFV0aWxzXG4gKiBAc3RhdGljXG4gKi9cblV0aWxzID0gR2VzdHVyZURldGVjdG9yLnV0aWxzID0ge1xuICAvKipcbiAgICogZXh0ZW5kIG1ldGhvZCwgY291bGQgYWxzbyBiZSB1c2VkIGZvciBjbG9uaW5nIHdoZW4gYGRlc3RgIGlzIGFuIGVtcHR5IG9iamVjdC5cbiAgICogY2hhbmdlcyB0aGUgZGVzdCBvYmplY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGRlc3RcbiAgICogQHBhcmFtIHtPYmplY3R9IHNyY1xuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFttZXJnZT1mYWxzZV0gIGRvIGEgbWVyZ2VcbiAgICogQHJldHVybiB7T2JqZWN0fSBkZXN0XG4gICAqL1xuICBleHRlbmQ6IGZ1bmN0aW9uIGV4dGVuZChkZXN0LCBzcmMsIG1lcmdlKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgICAgaWYgKHNyYy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIChkZXN0W2tleV0gPT09IHVuZGVmaW5lZCB8fCAhbWVyZ2UpKSB7XG4gICAgICAgIGRlc3Rba2V5XSA9IHNyY1trZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbiAgfSxcblxuICAvKipcbiAgICogc2ltcGxlIGFkZEV2ZW50TGlzdGVuZXIgd3JhcHBlclxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICovXG4gIG9uOiBmdW5jdGlvbiBvbihlbGVtZW50LCB0eXBlLCBoYW5kbGVyLCBvcHQpIHtcbiAgICB1dGlsLmFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudCwgdHlwZSwgaGFuZGxlciwgb3B0LCB0cnVlKTtcbiAgfSxcblxuICAvKipcbiAgICogc2ltcGxlIHJlbW92ZUV2ZW50TGlzdGVuZXIgd3JhcHBlclxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICovXG4gIG9mZjogZnVuY3Rpb24gb2ZmKGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIsIG9wdCkge1xuICAgIHV0aWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihlbGVtZW50LCB0eXBlLCBoYW5kbGVyLCBvcHQsIHRydWUpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBmb3JFYWNoIG92ZXIgYXJyYXlzIGFuZCBvYmplY3RzXG4gICAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0b3JcbiAgICogQHBhcmFtIHthbnl9IGl0ZXJhdG9yLml0ZW1cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGl0ZXJhdG9yLmluZGV4XG4gICAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBpdGVyYXRvci5vYmogdGhlIHNvdXJjZSBvYmplY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgdmFsdWUgdG8gdXNlIGFzIGB0aGlzYCBpbiB0aGUgaXRlcmF0b3JcbiAgICovXG4gIGVhY2g6IGZ1bmN0aW9uIGVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciBpLCBsZW47XG5cbiAgICAvLyBuYXRpdmUgZm9yRWFjaCBvbiBhcnJheXNcbiAgICBpZiAoJ2ZvckVhY2gnIGluIG9iaikge1xuICAgICAgb2JqLmZvckVhY2goaXRlcmF0b3IsIGNvbnRleHQpO1xuICAgICAgLy8gYXJyYXlzXG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZvciAoaSA9IDAsIGxlbiA9IG9iai5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBvYmplY3RzXG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSBpbiBvYmopIHtcbiAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSAmJlxuICAgICAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqW2ldLCBpLCBvYmopID09PSBmYWxzZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogZmluZCBpZiBhIHN0cmluZyBjb250YWlucyB0aGUgc3RyaW5nIHVzaW5nIGluZGV4T2ZcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNyY1xuICAgKiBAcGFyYW0ge1N0cmluZ30gZmluZFxuICAgKiBAcmV0dXJuIHtCb29sZWFufSBmb3VuZFxuICAgKi9cbiAgaW5TdHI6IGZ1bmN0aW9uIGluU3RyKHNyYywgZmluZCkge1xuICAgIHJldHVybiBzcmMuaW5kZXhPZihmaW5kKSA+IC0xO1xuICB9LFxuXG4gIC8qKlxuICAgKiBmaW5kIGlmIGEgYXJyYXkgY29udGFpbnMgdGhlIG9iamVjdCB1c2luZyBpbmRleE9mIG9yIGEgc2ltcGxlIHBvbHlmaWxsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzcmNcbiAgICogQHBhcmFtIHtTdHJpbmd9IGZpbmRcbiAgICogQHJldHVybiB7Qm9vbGVhbnxOdW1iZXJ9IGZhbHNlIHdoZW4gbm90IGZvdW5kLCBvciB0aGUgaW5kZXhcbiAgICovXG4gIGluQXJyYXk6IGZ1bmN0aW9uIGluQXJyYXkoc3JjLCBmaW5kLCBkZWVwKSB7XG4gICAgaWYgKGRlZXApIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzcmMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsgLy8gQXJyYXkuZmluZEluZGV4XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhmaW5kKS5ldmVyeShmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHNyY1tpXVtrZXldID09PSBmaW5kW2tleV07IH0pKSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICBpZiAoc3JjLmluZGV4T2YpIHtcbiAgICAgIHJldHVybiBzcmMuaW5kZXhPZihmaW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHNyYy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoc3JjW2ldID09PSBmaW5kKSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgYW4gYXJyYXktbGlrZSBvYmplY3QgKGBhcmd1bWVudHNgLCBgdG91Y2hsaXN0YCkgdG8gYW4gYXJyYXlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9ialxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIHRvQXJyYXk6IGZ1bmN0aW9uIHRvQXJyYXkob2JqKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG9iaiwgMCk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGZpbmQgaWYgYSBub2RlIGlzIGluIHRoZSBnaXZlbiBwYXJlbnRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbm9kZVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBwYXJlbnRcbiAgICogQHJldHVybiB7Qm9vbGVhbn0gZm91bmRcbiAgICovXG4gIGhhc1BhcmVudDogZnVuY3Rpb24gaGFzUGFyZW50KG5vZGUsIHBhcmVudCkge1xuICAgIHdoaWxlIChub2RlKSB7XG4gICAgICBpZiAobm9kZSA9PSBwYXJlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGdldCB0aGUgY2VudGVyIG9mIGFsbCB0aGUgdG91Y2hlc1xuICAgKiBAcGFyYW0ge0FycmF5fSB0b3VjaGVzXG4gICAqIEByZXR1cm4ge09iamVjdH0gY2VudGVyIGNvbnRhaW5zIGBwYWdlWGAsIGBwYWdlWWAsIGBjbGllbnRYYCBhbmQgYGNsaWVudFlgIHByb3BlcnRpZXNcbiAgICovXG4gIGdldENlbnRlcjogZnVuY3Rpb24gZ2V0Q2VudGVyKHRvdWNoZXMpIHtcbiAgICB2YXIgcGFnZVggPSBbXSxcbiAgICAgICAgcGFnZVkgPSBbXSxcbiAgICAgICAgY2xpZW50WCA9IFtdLFxuICAgICAgICBjbGllbnRZID0gW10sXG4gICAgICAgIG1pbiA9IE1hdGgubWluLFxuICAgICAgICBtYXggPSBNYXRoLm1heDtcblxuICAgIC8vIG5vIG5lZWQgdG8gbG9vcCB3aGVuIG9ubHkgb25lIHRvdWNoXG4gICAgaWYgKHRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYWdlWDogdG91Y2hlc1swXS5wYWdlWCxcbiAgICAgICAgcGFnZVk6IHRvdWNoZXNbMF0ucGFnZVksXG4gICAgICAgIGNsaWVudFg6IHRvdWNoZXNbMF0uY2xpZW50WCxcbiAgICAgICAgY2xpZW50WTogdG91Y2hlc1swXS5jbGllbnRZXG4gICAgICB9O1xuICAgIH1cblxuICAgIFV0aWxzLmVhY2godG91Y2hlcywgZnVuY3Rpb24odG91Y2gpIHtcbiAgICAgIHBhZ2VYLnB1c2godG91Y2gucGFnZVgpO1xuICAgICAgcGFnZVkucHVzaCh0b3VjaC5wYWdlWSk7XG4gICAgICBjbGllbnRYLnB1c2godG91Y2guY2xpZW50WCk7XG4gICAgICBjbGllbnRZLnB1c2godG91Y2guY2xpZW50WSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGFnZVg6IChtaW4uYXBwbHkoTWF0aCwgcGFnZVgpICsgbWF4LmFwcGx5KE1hdGgsIHBhZ2VYKSkgLyAyLFxuICAgICAgcGFnZVk6IChtaW4uYXBwbHkoTWF0aCwgcGFnZVkpICsgbWF4LmFwcGx5KE1hdGgsIHBhZ2VZKSkgLyAyLFxuICAgICAgY2xpZW50WDogKG1pbi5hcHBseShNYXRoLCBjbGllbnRYKSArIG1heC5hcHBseShNYXRoLCBjbGllbnRYKSkgLyAyLFxuICAgICAgY2xpZW50WTogKG1pbi5hcHBseShNYXRoLCBjbGllbnRZKSArIG1heC5hcHBseShNYXRoLCBjbGllbnRZKSkgLyAyXG4gICAgfTtcbiAgfSxcblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSB2ZWxvY2l0eSBiZXR3ZWVuIHR3byBwb2ludHMuIHVuaXQgaXMgaW4gcHggcGVyIG1zLlxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFUaW1lXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVhcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhWVxuICAgKiBAcmV0dXJuIHtPYmplY3R9IHZlbG9jaXR5IGB4YCBhbmQgYHlgXG4gICAqL1xuICBnZXRWZWxvY2l0eTogZnVuY3Rpb24gZ2V0VmVsb2NpdHkoZGVsdGFUaW1lLCBkZWx0YVgsIGRlbHRhWSkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiBNYXRoLmFicyhkZWx0YVggLyBkZWx0YVRpbWUpIHx8IDAsXG4gICAgICB5OiBNYXRoLmFicyhkZWx0YVkgLyBkZWx0YVRpbWUpIHx8IDBcbiAgICB9O1xuICB9LFxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIGFuZ2xlIGJldHdlZW4gdHdvIGNvb3JkaW5hdGVzXG4gICAqIEBwYXJhbSB7VG91Y2h9IHRvdWNoMVxuICAgKiBAcGFyYW0ge1RvdWNofSB0b3VjaDJcbiAgICogQHJldHVybiB7TnVtYmVyfSBhbmdsZVxuICAgKi9cbiAgZ2V0QW5nbGU6IGZ1bmN0aW9uIGdldEFuZ2xlKHRvdWNoMSwgdG91Y2gyKSB7XG4gICAgdmFyIHggPSB0b3VjaDIuY2xpZW50WCAtIHRvdWNoMS5jbGllbnRYLFxuICAgICAgICB5ID0gdG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WTtcblxuICAgIHJldHVybiBNYXRoLmF0YW4yKHksIHgpICogMTgwIC8gTWF0aC5QSTtcbiAgfSxcblxuICAvKipcbiAgICogZG8gYSBzbWFsbCBjb21wYXJpc29uIHRvIGdldCB0aGUgZGlyZWN0aW9uIGJldHdlZW4gdHdvIHRvdWNoZXMuXG4gICAqIEBwYXJhbSB7VG91Y2h9IHRvdWNoMVxuICAgKiBAcGFyYW0ge1RvdWNofSB0b3VjaDJcbiAgICogQHJldHVybiB7U3RyaW5nfSBkaXJlY3Rpb24gbWF0Y2hlcyBgRElSRUNUSU9OX0xFRlR8UklHSFR8VVB8RE9XTmBcbiAgICovXG4gIGdldERpcmVjdGlvbjogZnVuY3Rpb24gZ2V0RGlyZWN0aW9uKHRvdWNoMSwgdG91Y2gyKSB7XG4gICAgdmFyIHggPSBNYXRoLmFicyh0b3VjaDEuY2xpZW50WCAtIHRvdWNoMi5jbGllbnRYKSxcbiAgICAgICAgeSA9IE1hdGguYWJzKHRvdWNoMS5jbGllbnRZIC0gdG91Y2gyLmNsaWVudFkpO1xuXG4gICAgaWYgKHggPj0geSkge1xuICAgICAgcmV0dXJuIHRvdWNoMS5jbGllbnRYIC0gdG91Y2gyLmNsaWVudFggPiAwID8gRElSRUNUSU9OX0xFRlQgOiBESVJFQ1RJT05fUklHSFQ7XG4gICAgfVxuICAgIHJldHVybiB0b3VjaDEuY2xpZW50WSAtIHRvdWNoMi5jbGllbnRZID4gMCA/IERJUkVDVElPTl9VUCA6IERJUkVDVElPTl9ET1dOO1xuICB9LFxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHRvdWNoZXNcbiAgICogQHBhcmFtIHtUb3VjaH10b3VjaDFcbiAgICogQHBhcmFtIHtUb3VjaH0gdG91Y2gyXG4gICAqIEByZXR1cm4ge051bWJlcn0gZGlzdGFuY2VcbiAgICovXG4gIGdldERpc3RhbmNlOiBmdW5jdGlvbiBnZXREaXN0YW5jZSh0b3VjaDEsIHRvdWNoMikge1xuICAgIHZhciB4ID0gdG91Y2gyLmNsaWVudFggLSB0b3VjaDEuY2xpZW50WCxcbiAgICAgICAgeSA9IHRvdWNoMi5jbGllbnRZIC0gdG91Y2gxLmNsaWVudFk7XG5cbiAgICByZXR1cm4gTWF0aC5zcXJ0KCh4ICogeCkgKyAoeSAqIHkpKTtcbiAgfSxcblxuICAvKipcbiAgICogY2FsY3VsYXRlIHRoZSBzY2FsZSBmYWN0b3IgYmV0d2VlbiB0d28gdG91Y2hMaXN0c1xuICAgKiBubyBzY2FsZSBpcyAxLCBhbmQgZ29lcyBkb3duIHRvIDAgd2hlbiBwaW5jaGVkIHRvZ2V0aGVyLCBhbmQgYmlnZ2VyIHdoZW4gcGluY2hlZCBvdXRcbiAgICogQHBhcmFtIHtBcnJheX0gc3RhcnQgYXJyYXkgb2YgdG91Y2hlc1xuICAgKiBAcGFyYW0ge0FycmF5fSBlbmQgYXJyYXkgb2YgdG91Y2hlc1xuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IHNjYWxlXG4gICAqL1xuICBnZXRTY2FsZTogZnVuY3Rpb24gZ2V0U2NhbGUoc3RhcnQsIGVuZCkge1xuICAgIC8vIG5lZWQgdHdvIGZpbmdlcnMuLi5cbiAgICBpZiAoc3RhcnQubGVuZ3RoID49IDIgJiYgZW5kLmxlbmd0aCA+PSAyKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXREaXN0YW5jZShlbmRbMF0sIGVuZFsxXSkgLyB0aGlzLmdldERpc3RhbmNlKHN0YXJ0WzBdLCBzdGFydFsxXSk7XG4gICAgfVxuICAgIHJldHVybiAxO1xuICB9LFxuXG4gIC8qKlxuICAgKiBjYWxjdWxhdGUgdGhlIHJvdGF0aW9uIGRlZ3JlZXMgYmV0d2VlbiB0d28gdG91Y2hMaXN0c1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdGFydCBhcnJheSBvZiB0b3VjaGVzXG4gICAqIEBwYXJhbSB7QXJyYXl9IGVuZCBhcnJheSBvZiB0b3VjaGVzXG4gICAqIEByZXR1cm4ge051bWJlcn0gcm90YXRpb25cbiAgICovXG4gIGdldFJvdGF0aW9uOiBmdW5jdGlvbiBnZXRSb3RhdGlvbihzdGFydCwgZW5kKSB7XG4gICAgLy8gbmVlZCB0d28gZmluZ2Vyc1xuICAgIGlmIChzdGFydC5sZW5ndGggPj0gMiAmJiBlbmQubGVuZ3RoID49IDIpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEFuZ2xlKGVuZFsxXSwgZW5kWzBdKSAtIHRoaXMuZ2V0QW5nbGUoc3RhcnRbMV0sIHN0YXJ0WzBdKTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGZpbmQgb3V0IGlmIHRoZSBkaXJlY3Rpb24gaXMgdmVydGljYWwgICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkaXJlY3Rpb24gbWF0Y2hlcyBgRElSRUNUSU9OX1VQfERPV05gXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IGlzX3ZlcnRpY2FsXG4gICAqL1xuICBpc1ZlcnRpY2FsOiBmdW5jdGlvbiBpc1ZlcnRpY2FsKGRpcmVjdGlvbikge1xuICAgIHJldHVybiBkaXJlY3Rpb24gPT0gRElSRUNUSU9OX1VQIHx8IGRpcmVjdGlvbiA9PSBESVJFQ1RJT05fRE9XTjtcbiAgfSxcblxuICAvKipcbiAgICogc2V0IGNzcyBwcm9wZXJ0aWVzIHdpdGggdGhlaXIgcHJlZml4ZXNcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtCb29sZWFufSBbdG9nZ2xlPXRydWVdXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBzZXRQcmVmaXhlZENzczogZnVuY3Rpb24gc2V0UHJlZml4ZWRDc3MoZWxlbWVudCwgcHJvcCwgdmFsdWUsIHRvZ2dsZSkge1xuICAgIHZhciBwcmVmaXhlcyA9IFsnJywgJ1dlYmtpdCcsICdNb3onLCAnTycsICdtcyddO1xuICAgIHByb3AgPSBVdGlscy50b0NhbWVsQ2FzZShwcm9wKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJlZml4ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwID0gcHJvcDtcbiAgICAgIC8vIHByZWZpeGVzXG4gICAgICBpZiAocHJlZml4ZXNbaV0pIHtcbiAgICAgICAgcCA9IHByZWZpeGVzW2ldICsgcC5zbGljZSgwLCAxKS50b1VwcGVyQ2FzZSgpICsgcC5zbGljZSgxKTtcbiAgICAgIH1cblxuICAgICAgLy8gdGVzdCB0aGUgc3R5bGVcbiAgICAgIGlmIChwIGluIGVsZW1lbnQuc3R5bGUpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZVtwXSA9ICh0b2dnbGUgPT09IG51bGwgfHwgdG9nZ2xlKSAmJiB2YWx1ZSB8fCAnJztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiB0b2dnbGUgYnJvd3NlciBkZWZhdWx0IGJlaGF2aW9yIGJ5IHNldHRpbmcgY3NzIHByb3BlcnRpZXMuXG4gICAqIGB1c2VyU2VsZWN0PSdub25lJ2AgYWxzbyBzZXRzIGBlbGVtZW50Lm9uc2VsZWN0c3RhcnRgIHRvIGZhbHNlXG4gICAqIGB1c2VyRHJhZz0nbm9uZSdgIGFsc28gc2V0cyBgZWxlbWVudC5vbmRyYWdzdGFydGAgdG8gZmFsc2VcbiAgICpcbiAgICogQHBhcmFtIHtIdG1sRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcHNcbiAgICogQHBhcmFtIHtCb29sZWFufSBbdG9nZ2xlPXRydWVdXG4gICAqL1xuICB0b2dnbGVCZWhhdmlvcjogZnVuY3Rpb24gdG9nZ2xlQmVoYXZpb3IoZWxlbWVudCwgcHJvcHMsIHRvZ2dsZSkge1xuICAgIGlmICghcHJvcHMgfHwgIWVsZW1lbnQgfHwgIWVsZW1lbnQuc3R5bGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzZXQgdGhlIGNzcyBwcm9wZXJ0aWVzXG4gICAgVXRpbHMuZWFjaChwcm9wcywgZnVuY3Rpb24odmFsdWUsIHByb3ApIHtcbiAgICAgIFV0aWxzLnNldFByZWZpeGVkQ3NzKGVsZW1lbnQsIHByb3AsIHZhbHVlLCB0b2dnbGUpO1xuICAgIH0pO1xuXG4gICAgdmFyIGZhbHNlRm4gPSB0b2dnbGUgJiYgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8vIGFsc28gdGhlIGRpc2FibGUgb25zZWxlY3RzdGFydFxuICAgIGlmIChwcm9wcy51c2VyU2VsZWN0ID09ICdub25lJykge1xuICAgICAgZWxlbWVudC5vbnNlbGVjdHN0YXJ0ID0gZmFsc2VGbjtcbiAgICB9XG4gICAgLy8gYW5kIGRpc2FibGUgb25kcmFnc3RhcnRcbiAgICBpZiAocHJvcHMudXNlckRyYWcgPT0gJ25vbmUnKSB7XG4gICAgICBlbGVtZW50Lm9uZHJhZ3N0YXJ0ID0gZmFsc2VGbjtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgYSBzdHJpbmcgd2l0aCB1bmRlcnNjb3JlcyB0byBjYW1lbENhc2VcbiAgICogc28gcHJldmVudF9kZWZhdWx0IGJlY29tZXMgcHJldmVudERlZmF1bHRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGNhbWVsQ2FzZVN0clxuICAgKi9cbiAgdG9DYW1lbENhc2U6IGZ1bmN0aW9uIHRvQ2FtZWxDYXNlKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW18tXShbYS16XSkvZywgZnVuY3Rpb24ocykge1xuICAgICAgcmV0dXJuIHNbMV0udG9VcHBlckNhc2UoKTtcbiAgICB9KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEBtb2R1bGUgR2VzdHVyZURldGVjdG9yXG4gKi9cbi8qKlxuICogQGNsYXNzIEV2ZW50XG4gKiBAc3RhdGljXG4gKi9cbkV2ZW50ID0gR2VzdHVyZURldGVjdG9yLmV2ZW50ID0ge1xuICAvKipcbiAgICogd2hlbiB0b3VjaCBldmVudHMgaGF2ZSBiZWVuIGZpcmVkLCB0aGlzIGlzIHRydWVcbiAgICogdGhpcyBpcyB1c2VkIHRvIHN0b3AgbW91c2UgZXZlbnRzXG4gICAqIEBwcm9wZXJ0eSBwcmV2ZW50X21vdXNlZXZlbnRzXG4gICAqIEBwcml2YXRlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cbiAgcHJldmVudE1vdXNlRXZlbnRzOiBmYWxzZSxcblxuICAvKipcbiAgICogaWYgRVZFTlRfU1RBUlQgaGFzIGJlZW4gZmlyZWRcbiAgICogQHByb3BlcnR5IHN0YXJ0ZWRcbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqL1xuICBzdGFydGVkOiBmYWxzZSxcblxuICAvKipcbiAgICogd2hlbiB0aGUgbW91c2UgaXMgaG9sZCBkb3duLCB0aGlzIGlzIHRydWVcbiAgICogQHByb3BlcnR5IHNob3VsZF9kZXRlY3RcbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqL1xuICBzaG91bGREZXRlY3Q6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBzaW1wbGUgZXZlbnQgYmluZGVyIHdpdGggYSBob29rIGFuZCBzdXBwb3J0IGZvciBtdWx0aXBsZSB0eXBlc1xuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtob29rXVxuICAgKiBAcGFyYW0ge09iamVjdH0gaG9vay50eXBlXG4gICAqL1xuICBvbjogZnVuY3Rpb24gb24oZWxlbWVudCwgdHlwZSwgaGFuZGxlciwgb3B0LCBob29rKSB7XG4gICAgdmFyIHR5cGVzID0gdHlwZS5zcGxpdCgnICcpO1xuICAgIFV0aWxzLmVhY2godHlwZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgIFV0aWxzLm9uKGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIsIG9wdCk7XG4gICAgICBob29rICYmIGhvb2sodHlwZSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIHNpbXBsZSBldmVudCB1bmJpbmRlciB3aXRoIGEgaG9vayBhbmQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgdHlwZXNcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0XVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaG9va11cbiAgICogQHBhcmFtIHtPYmplY3R9IGhvb2sudHlwZVxuICAgKi9cbiAgb2ZmOiBmdW5jdGlvbiBvZmYoZWxlbWVudCwgdHlwZSwgaGFuZGxlciwgb3B0LCBob29rKSB7XG4gICAgdmFyIHR5cGVzID0gdHlwZS5zcGxpdCgnICcpO1xuICAgIFV0aWxzLmVhY2godHlwZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgIFV0aWxzLm9mZihlbGVtZW50LCB0eXBlLCBoYW5kbGVyLCBvcHQpO1xuICAgICAgaG9vayAmJiBob29rKHR5cGUpO1xuICAgIH0pO1xuICB9LFxuXG4gIC8qKlxuICAgKiB0aGUgY29yZSB0b3VjaCBldmVudCBoYW5kbGVyLlxuICAgKiB0aGlzIGZpbmRzIG91dCBpZiB3ZSBzaG91bGQgdG8gZGV0ZWN0IGdlc3R1cmVzXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZSBtYXRjaGVzIGBFVkVOVF9TVEFSVHxNT1ZFfEVORGBcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgKiBAcmV0dXJuIG9uVG91Y2hIYW5kbGVyIHtGdW5jdGlvbn0gdGhlIGNvcmUgZXZlbnQgaGFuZGxlclxuICAgKi9cbiAgb25Ub3VjaDogZnVuY3Rpb24gb25Ub3VjaChlbGVtZW50LCBldmVudFR5cGUsIGhhbmRsZXIsIG9wdCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBvblRvdWNoSGFuZGxlciA9IGZ1bmN0aW9uIG9uVG91Y2hIYW5kbGVyKGV2KSB7XG4gICAgICB2YXIgc3JjVHlwZSA9IGV2LnR5cGUudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICBpc1BvaW50ZXIgPSBHZXN0dXJlRGV0ZWN0b3IuSEFTX1BPSU5URVJFVkVOVFMsXG4gICAgICAgICAgaXNNb3VzZSA9IFV0aWxzLmluU3RyKHNyY1R5cGUsICdtb3VzZScpLFxuICAgICAgICAgIHRyaWdnZXJUeXBlO1xuXG4gICAgICAvLyBpZiB3ZSBhcmUgaW4gYSBtb3VzZWV2ZW50LCBidXQgdGhlcmUgaGFzIGJlZW4gYSB0b3VjaGV2ZW50IHRyaWdnZXJlZCBpbiB0aGlzIHNlc3Npb25cbiAgICAgIC8vIHdlIHdhbnQgdG8gZG8gbm90aGluZy4gc2ltcGx5IGJyZWFrIG91dCBvZiB0aGUgZXZlbnQuXG4gICAgICBpZiAoaXNNb3VzZSAmJiBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cykge1xuICAgICAgICByZXR1cm47XG5cbiAgICAgICAgLy8gbW91c2VidXR0b24gbXVzdCBiZSBkb3duXG4gICAgICB9IGVsc2UgaWYgKGlzTW91c2UgJiYgZXZlbnRUeXBlID09IEVWRU5UX1NUQVJUICYmIGV2LmJ1dHRvbiA9PT0gMCkge1xuICAgICAgICBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cyA9IGZhbHNlO1xuICAgICAgICBzZWxmLnNob3VsZERldGVjdCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGlzUG9pbnRlciAmJiBldmVudFR5cGUgPT0gRVZFTlRfU1RBUlQpIHtcbiAgICAgICAgc2VsZi5zaG91bGREZXRlY3QgPSAoZXYuYnV0dG9ucyA9PT0gMSB8fCBQb2ludGVyRXZlbnQubWF0Y2hUeXBlKFBPSU5URVJfVE9VQ0gsIGV2KSk7XG4gICAgICAgIC8vIGp1c3QgYSB2YWxpZCBzdGFydCBldmVudCwgYnV0IG5vIG1vdXNlXG4gICAgICB9IGVsc2UgaWYgKCFpc01vdXNlICYmIGV2ZW50VHlwZSA9PSBFVkVOVF9TVEFSVCkge1xuICAgICAgICBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cyA9IHRydWU7XG4gICAgICAgIHNlbGYuc2hvdWxkRGV0ZWN0ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlIHRoZSBwb2ludGVyIGV2ZW50IGJlZm9yZSBlbnRlcmluZyB0aGUgZGV0ZWN0aW9uXG4gICAgICBpZiAoaXNQb2ludGVyICYmIGV2ZW50VHlwZSAhPSBFVkVOVF9FTkQpIHtcbiAgICAgICAgUG9pbnRlckV2ZW50LnVwZGF0ZVBvaW50ZXIoZXZlbnRUeXBlLCBldik7XG4gICAgICB9XG5cbiAgICAgIC8vIHdlIGFyZSBpbiBhIHRvdWNoL2Rvd24gc3RhdGUsIHNvIGFsbG93ZWQgZGV0ZWN0aW9uIG9mIGdlc3R1cmVzXG4gICAgICBpZiAoc2VsZi5zaG91bGREZXRlY3QpIHtcbiAgICAgICAgdHJpZ2dlclR5cGUgPSBzZWxmLmRvRGV0ZWN0LmNhbGwoc2VsZiwgZXYsIGV2ZW50VHlwZSwgZWxlbWVudCwgaGFuZGxlcik7XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLmFuZCB3ZSBhcmUgZG9uZSB3aXRoIHRoZSBkZXRlY3Rpb25cbiAgICAgIC8vIHNvIHJlc2V0IGV2ZXJ5dGhpbmcgdG8gc3RhcnQgZWFjaCBkZXRlY3Rpb24gdG90YWxseSBmcmVzaFxuICAgICAgaWYgKHRyaWdnZXJUeXBlID09IEVWRU5UX0VORCkge1xuICAgICAgICBzZWxmLnByZXZlbnRNb3VzZUV2ZW50cyA9IGZhbHNlO1xuICAgICAgICBzZWxmLnNob3VsZERldGVjdCA9IGZhbHNlO1xuICAgICAgICBQb2ludGVyRXZlbnQucmVzZXQoKTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBwb2ludGVyZXZlbnQgb2JqZWN0IGFmdGVyIHRoZSBkZXRlY3Rpb25cbiAgICAgIH1cblxuICAgICAgaWYgKGlzUG9pbnRlciAmJiBldmVudFR5cGUgPT0gRVZFTlRfRU5EKSB7XG4gICAgICAgIFBvaW50ZXJFdmVudC51cGRhdGVQb2ludGVyKGV2ZW50VHlwZSwgZXYpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLm9uKGVsZW1lbnQsIEVWRU5UX1RZUEVTW2V2ZW50VHlwZV0sIG9uVG91Y2hIYW5kbGVyLCBvcHQpO1xuICAgIHJldHVybiBvblRvdWNoSGFuZGxlcjtcbiAgfSxcblxuICAvKipcbiAgICogdGhlIGNvcmUgZGV0ZWN0aW9uIG1ldGhvZFxuICAgKiB0aGlzIGZpbmRzIG91dCB3aGF0IEdlc3R1cmVEZXRlY3Rvci10b3VjaC1ldmVudHMgdG8gdHJpZ2dlclxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZSBtYXRjaGVzIGBFVkVOVF9TVEFSVHxNT1ZFfEVORGBcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyXG4gICAqIEByZXR1cm4ge1N0cmluZ30gdHJpZ2dlclR5cGUgbWF0Y2hlcyBgRVZFTlRfU1RBUlR8TU9WRXxFTkRgXG4gICAqL1xuICBkb0RldGVjdDogZnVuY3Rpb24gZG9EZXRlY3QoZXYsIGV2ZW50VHlwZSwgZWxlbWVudCwgaGFuZGxlcikge1xuICAgIHZhciB0b3VjaExpc3QgPSB0aGlzLmdldFRvdWNoTGlzdChldiwgZXZlbnRUeXBlKTtcbiAgICB2YXIgdG91Y2hMaXN0TGVuZ3RoID0gdG91Y2hMaXN0Lmxlbmd0aDtcbiAgICB2YXIgdHJpZ2dlclR5cGUgPSBldmVudFR5cGU7XG4gICAgdmFyIHRyaWdnZXJDaGFuZ2UgPSB0b3VjaExpc3QudHJpZ2dlcjsgLy8gdXNlZCBieSBmYWtlTXVsdGl0b3VjaCBwbHVnaW5cbiAgICB2YXIgY2hhbmdlZExlbmd0aCA9IHRvdWNoTGlzdExlbmd0aDtcblxuICAgIC8vIGF0IGVhY2ggdG91Y2hzdGFydC1saWtlIGV2ZW50IHdlIHdhbnQgYWxzbyB3YW50IHRvIHRyaWdnZXIgYSBUT1VDSCBldmVudC4uLlxuICAgIGlmIChldmVudFR5cGUgPT0gRVZFTlRfU1RBUlQpIHtcbiAgICAgIHRyaWdnZXJDaGFuZ2UgPSBFVkVOVF9UT1VDSDtcbiAgICAgIC8vIC4uLnRoZSBzYW1lIGZvciBhIHRvdWNoZW5kLWxpa2UgZXZlbnRcbiAgICB9IGVsc2UgaWYgKGV2ZW50VHlwZSA9PSBFVkVOVF9FTkQpIHtcbiAgICAgIHRyaWdnZXJDaGFuZ2UgPSBFVkVOVF9SRUxFQVNFO1xuXG4gICAgICAvLyBrZWVwIHRyYWNrIG9mIGhvdyBtYW55IHRvdWNoZXMgaGF2ZSBiZWVuIHJlbW92ZWRcbiAgICAgIGNoYW5nZWRMZW5ndGggPSB0b3VjaExpc3QubGVuZ3RoIC0gKChldi5jaGFuZ2VkVG91Y2hlcykgPyBldi5jaGFuZ2VkVG91Y2hlcy5sZW5ndGggOiAxKTtcbiAgICB9XG5cbiAgICAvLyBhZnRlciB0aGVyZSBhcmUgc3RpbGwgdG91Y2hlcyBvbiB0aGUgc2NyZWVuLFxuICAgIC8vIHdlIGp1c3Qgd2FudCB0byB0cmlnZ2VyIGEgTU9WRSBldmVudC4gc28gY2hhbmdlIHRoZSBTVEFSVCBvciBFTkQgdG8gYSBNT1ZFXG4gICAgLy8gYnV0IG9ubHkgYWZ0ZXIgZGV0ZWN0aW9uIGhhcyBiZWVuIHN0YXJ0ZWQsIHRoZSBmaXJzdCB0aW1lIHdlIGFjdHVhbGx5IHdhbnQgYSBTVEFSVFxuICAgIGlmIChjaGFuZ2VkTGVuZ3RoID4gMCAmJiB0aGlzLnN0YXJ0ZWQpIHtcbiAgICAgIHRyaWdnZXJUeXBlID0gRVZFTlRfTU9WRTtcbiAgICB9XG5cbiAgICAvLyBkZXRlY3Rpb24gaGFzIGJlZW4gc3RhcnRlZCwgd2Uga2VlcCB0cmFjayBvZiB0aGlzLCBzZWUgYWJvdmVcbiAgICB0aGlzLnN0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgLy8gZ2VuZXJhdGUgc29tZSBldmVudCBkYXRhLCBzb21lIGJhc2ljIGluZm9ybWF0aW9uXG4gICAgdmFyIGV2RGF0YSA9IHRoaXMuY29sbGVjdEV2ZW50RGF0YShlbGVtZW50LCB0cmlnZ2VyVHlwZSwgdG91Y2hMaXN0LCBldik7XG5cbiAgICAvLyB0cmlnZ2VyIHRoZSB0cmlnZ2VyVHlwZSBldmVudCBiZWZvcmUgdGhlIGNoYW5nZSAoVE9VQ0gsIFJFTEVBU0UpIGV2ZW50c1xuICAgIC8vIGJ1dCB0aGUgRU5EIGV2ZW50IHNob3VsZCBiZSBhdCBsYXN0XG4gICAgaWYgKGV2ZW50VHlwZSAhPSBFVkVOVF9FTkQpIHtcbiAgICAgIGhhbmRsZXIuY2FsbChEZXRlY3Rpb24sIGV2RGF0YSk7XG4gICAgfVxuXG4gICAgLy8gdHJpZ2dlciBhIGNoYW5nZSAoVE9VQ0gsIFJFTEVBU0UpIGV2ZW50LCB0aGlzIG1lYW5zIHRoZSBsZW5ndGggb2YgdGhlIHRvdWNoZXMgY2hhbmdlZFxuICAgIGlmICh0cmlnZ2VyQ2hhbmdlKSB7XG4gICAgICBldkRhdGEuY2hhbmdlZExlbmd0aCA9IGNoYW5nZWRMZW5ndGg7XG4gICAgICBldkRhdGEuZXZlbnRUeXBlID0gdHJpZ2dlckNoYW5nZTtcblxuICAgICAgaGFuZGxlci5jYWxsKERldGVjdGlvbiwgZXZEYXRhKTtcblxuICAgICAgZXZEYXRhLmV2ZW50VHlwZSA9IHRyaWdnZXJUeXBlO1xuICAgICAgZGVsZXRlIGV2RGF0YS5jaGFuZ2VkTGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIHRyaWdnZXIgdGhlIEVORCBldmVudFxuICAgIGlmICh0cmlnZ2VyVHlwZSA9PSBFVkVOVF9FTkQpIHtcbiAgICAgIGhhbmRsZXIuY2FsbChEZXRlY3Rpb24sIGV2RGF0YSk7XG5cbiAgICAgIC8vIC4uLmFuZCB3ZSBhcmUgZG9uZSB3aXRoIHRoZSBkZXRlY3Rpb25cbiAgICAgIC8vIHNvIHJlc2V0IGV2ZXJ5dGhpbmcgdG8gc3RhcnQgZWFjaCBkZXRlY3Rpb24gdG90YWxseSBmcmVzaFxuICAgICAgdGhpcy5zdGFydGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyaWdnZXJUeXBlO1xuICB9LFxuXG4gIC8qKlxuICAgKiB3ZSBoYXZlIGRpZmZlcmVudCBldmVudHMgZm9yIGVhY2ggZGV2aWNlL2Jyb3dzZXJcbiAgICogZGV0ZXJtaW5lIHdoYXQgd2UgbmVlZCBhbmQgc2V0IHRoZW0gaW4gdGhlIEVWRU5UX1RZUEVTIGNvbnN0YW50XG4gICAqIHRoZSBgb25Ub3VjaGAgbWV0aG9kIGlzIGJpbmQgdG8gdGhlc2UgcHJvcGVydGllcy5cbiAgICogQHJldHVybiB7T2JqZWN0fSBldmVudHNcbiAgICovXG4gIGRldGVybWluZUV2ZW50VHlwZXM6IGZ1bmN0aW9uIGRldGVybWluZUV2ZW50VHlwZXMoKSB7XG4gICAgdmFyIHR5cGVzO1xuICAgIGlmIChHZXN0dXJlRGV0ZWN0b3IuSEFTX1BPSU5URVJFVkVOVFMpIHtcbiAgICAgIGlmICh3aW5kb3cuUG9pbnRlckV2ZW50KSB7XG4gICAgICAgIHR5cGVzID0gW1xuICAgICAgICAgICdwb2ludGVyZG93bicsXG4gICAgICAgICAgJ3BvaW50ZXJtb3ZlJyxcbiAgICAgICAgICAncG9pbnRlcnVwIHBvaW50ZXJjYW5jZWwgbG9zdHBvaW50ZXJjYXB0dXJlJ1xuICAgICAgICBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZXMgPSBbXG4gICAgICAgICAgJ01TUG9pbnRlckRvd24nLFxuICAgICAgICAgICdNU1BvaW50ZXJNb3ZlJyxcbiAgICAgICAgICAnTVNQb2ludGVyVXAgTVNQb2ludGVyQ2FuY2VsIE1TTG9zdFBvaW50ZXJDYXB0dXJlJ1xuICAgICAgICBdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoR2VzdHVyZURldGVjdG9yLk5PX01PVVNFRVZFTlRTKSB7XG4gICAgICB0eXBlcyA9IFtcbiAgICAgICAgJ3RvdWNoc3RhcnQnLFxuICAgICAgICAndG91Y2htb3ZlJyxcbiAgICAgICAgJ3RvdWNoZW5kIHRvdWNoY2FuY2VsJ1xuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZXMgPSBbXG4gICAgICAgICd0b3VjaHN0YXJ0IG1vdXNlZG93bicsXG4gICAgICAgICd0b3VjaG1vdmUgbW91c2Vtb3ZlJyxcbiAgICAgICAgJ3RvdWNoZW5kIHRvdWNoY2FuY2VsIG1vdXNldXAnXG4gICAgICBdO1xuICAgIH1cblxuICAgIEVWRU5UX1RZUEVTW0VWRU5UX1NUQVJUXSA9IHR5cGVzWzBdO1xuICAgIEVWRU5UX1RZUEVTW0VWRU5UX01PVkVdID0gdHlwZXNbMV07XG4gICAgRVZFTlRfVFlQRVNbRVZFTlRfRU5EXSA9IHR5cGVzWzJdO1xuICAgIHJldHVybiBFVkVOVF9UWVBFUztcbiAgfSxcblxuICAvKipcbiAgICogY3JlYXRlIHRvdWNoTGlzdCBkZXBlbmRpbmcgb24gdGhlIGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRUeXBlXG4gICAqIEByZXR1cm4ge0FycmF5fSB0b3VjaGVzXG4gICAqL1xuICBnZXRUb3VjaExpc3Q6IGZ1bmN0aW9uIGdldFRvdWNoTGlzdChldiwgZXZlbnRUeXBlKSB7XG4gICAgLy8gZ2V0IHRoZSBmYWtlIHBvaW50ZXJFdmVudCB0b3VjaGxpc3RcbiAgICBpZiAoR2VzdHVyZURldGVjdG9yLkhBU19QT0lOVEVSRVZFTlRTKSB7XG4gICAgICByZXR1cm4gUG9pbnRlckV2ZW50LmdldFRvdWNoTGlzdCgpO1xuICAgIH1cblxuICAgIC8vIGdldCB0aGUgdG91Y2hsaXN0XG4gICAgaWYgKGV2LnRvdWNoZXMpIHtcbiAgICAgIGlmIChldmVudFR5cGUgPT0gRVZFTlRfTU9WRSkge1xuICAgICAgICByZXR1cm4gZXYudG91Y2hlcztcbiAgICAgIH1cblxuICAgICAgdmFyIGlkZW50aWZpZXJzID0gW107XG4gICAgICB2YXIgY29uY2F0ID0gW10uY29uY2F0KFV0aWxzLnRvQXJyYXkoZXYudG91Y2hlcyksIFV0aWxzLnRvQXJyYXkoZXYuY2hhbmdlZFRvdWNoZXMpKTtcbiAgICAgIHZhciB0b3VjaExpc3QgPSBbXTtcblxuICAgICAgVXRpbHMuZWFjaChjb25jYXQsIGZ1bmN0aW9uKHRvdWNoKSB7XG4gICAgICAgIGlmIChVdGlscy5pbkFycmF5KGlkZW50aWZpZXJzLCB0b3VjaC5pZGVudGlmaWVyKSA9PT0gLTEpIHtcbiAgICAgICAgICB0b3VjaExpc3QucHVzaCh0b3VjaCk7XG4gICAgICAgIH1cbiAgICAgICAgaWRlbnRpZmllcnMucHVzaCh0b3VjaC5pZGVudGlmaWVyKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdG91Y2hMaXN0O1xuICAgIH1cblxuICAgIC8vIG1ha2UgZmFrZSB0b3VjaExpc3QgZnJvbSBtb3VzZSBwb3NpdGlvblxuICAgIGV2LmlkZW50aWZpZXIgPSAxO1xuICAgIHJldHVybiBbZXZdO1xuICB9LFxuXG4gIC8qKlxuICAgKiBjb2xsZWN0IGJhc2ljIGV2ZW50IGRhdGFcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRUeXBlIG1hdGNoZXMgYEVWRU5UX1NUQVJUfE1PVkV8RU5EYFxuICAgKiBAcGFyYW0ge0FycmF5fSB0b3VjaGVzXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKiBAcmV0dXJuIHtPYmplY3R9IGV2XG4gICAqL1xuICBjb2xsZWN0RXZlbnREYXRhOiBmdW5jdGlvbiBjb2xsZWN0RXZlbnREYXRhKGVsZW1lbnQsIGV2ZW50VHlwZSwgdG91Y2hlcywgZXYpIHtcbiAgICAvLyBmaW5kIG91dCBwb2ludGVyVHlwZVxuICAgIHZhciBwb2ludGVyVHlwZSA9IFBPSU5URVJfVE9VQ0g7XG4gICAgaWYgKFV0aWxzLmluU3RyKGV2LnR5cGUsICdtb3VzZScpIHx8IFBvaW50ZXJFdmVudC5tYXRjaFR5cGUoUE9JTlRFUl9NT1VTRSwgZXYpKSB7XG4gICAgICBwb2ludGVyVHlwZSA9IFBPSU5URVJfTU9VU0U7XG4gICAgfSBlbHNlIGlmIChQb2ludGVyRXZlbnQubWF0Y2hUeXBlKFBPSU5URVJfUEVOLCBldikpIHtcbiAgICAgIHBvaW50ZXJUeXBlID0gUE9JTlRFUl9QRU47XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNlbnRlcjogVXRpbHMuZ2V0Q2VudGVyKHRvdWNoZXMpLFxuICAgICAgdGltZVN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgdGFyZ2V0OiBldi50YXJnZXQsXG4gICAgICB0b3VjaGVzOiB0b3VjaGVzLFxuICAgICAgZXZlbnRUeXBlOiBldmVudFR5cGUsXG4gICAgICBwb2ludGVyVHlwZTogcG9pbnRlclR5cGUsXG4gICAgICBzcmNFdmVudDogZXYsXG5cbiAgICAgIC8qKlxuICAgICAgICogcHJldmVudCB0aGUgYnJvd3NlciBkZWZhdWx0IGFjdGlvbnNcbiAgICAgICAqIG1vc3RseSB1c2VkIHRvIGRpc2FibGUgc2Nyb2xsaW5nIG9mIHRoZSBicm93c2VyXG4gICAgICAgKi9cbiAgICAgIHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHNyY0V2ZW50ID0gdGhpcy5zcmNFdmVudDtcbiAgICAgICAgc3JjRXZlbnQucHJldmVudE1hbmlwdWxhdGlvbiAmJiBzcmNFdmVudC5wcmV2ZW50TWFuaXB1bGF0aW9uKCk7XG4gICAgICAgIHNyY0V2ZW50LnByZXZlbnREZWZhdWx0ICYmIHNyY0V2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIHN0b3AgYnViYmxpbmcgdGhlIGV2ZW50IHVwIHRvIGl0cyBwYXJlbnRzXG4gICAgICAgKi9cbiAgICAgIHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc3JjRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIGltbWVkaWF0ZWx5IHN0b3AgZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICAgICAqIG1pZ2h0IGJlIHVzZWZ1bCBhZnRlciBhIHN3aXBlIHdhcyBkZXRlY3RlZFxuICAgICAgICogQHJldHVybiB7Kn1cbiAgICAgICAqL1xuICAgICAgc3RvcERldGVjdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBEZXRlY3Rpb24uc3RvcERldGVjdCgpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIEdlc3R1cmVEZXRlY3RvclxuICpcbiAqIEBjbGFzcyBQb2ludGVyRXZlbnRcbiAqIEBzdGF0aWNcbiAqL1xuUG9pbnRlckV2ZW50ID0gR2VzdHVyZURldGVjdG9yLlBvaW50ZXJFdmVudCA9IHtcbiAgLyoqXG4gICAqIGhvbGRzIGFsbCBwb2ludGVycywgYnkgYGlkZW50aWZpZXJgXG4gICAqIEBwcm9wZXJ0eSBwb2ludGVyc1xuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgcG9pbnRlcnM6IHt9LFxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHBvaW50ZXJzIGFzIGFuIGFycmF5XG4gICAqIEByZXR1cm4ge0FycmF5fSB0b3VjaGxpc3RcbiAgICovXG4gIGdldFRvdWNoTGlzdDogZnVuY3Rpb24gZ2V0VG91Y2hMaXN0KCkge1xuICAgIHZhciB0b3VjaGxpc3QgPSBbXTtcbiAgICAvLyB3ZSBjYW4gdXNlIGZvckVhY2ggc2luY2UgcG9pbnRlckV2ZW50cyBvbmx5IGlzIGluIElFMTBcbiAgICBVdGlscy5lYWNoKHRoaXMucG9pbnRlcnMsIGZ1bmN0aW9uKHBvaW50ZXIpIHtcbiAgICAgIHRvdWNobGlzdC5wdXNoKHBvaW50ZXIpO1xuICAgIH0pO1xuICAgIHJldHVybiB0b3VjaGxpc3Q7XG4gIH0sXG5cbiAgLyoqXG4gICAqIHVwZGF0ZSB0aGUgcG9zaXRpb24gb2YgYSBwb2ludGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFR5cGUgbWF0Y2hlcyBgRVZFTlRfU1RBUlR8TU9WRXxFTkRgXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwb2ludGVyRXZlbnRcbiAgICovXG4gIHVwZGF0ZVBvaW50ZXI6IGZ1bmN0aW9uIHVwZGF0ZVBvaW50ZXIoZXZlbnRUeXBlLCBwb2ludGVyRXZlbnQpIHtcbiAgICBpZiAoZXZlbnRUeXBlID09IEVWRU5UX0VORCB8fCAoZXZlbnRUeXBlICE9IEVWRU5UX0VORCAmJiBwb2ludGVyRXZlbnQuYnV0dG9ucyAhPT0gMSkpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnBvaW50ZXJzW3BvaW50ZXJFdmVudC5wb2ludGVySWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb2ludGVyRXZlbnQuaWRlbnRpZmllciA9IHBvaW50ZXJFdmVudC5wb2ludGVySWQ7XG4gICAgICB0aGlzLnBvaW50ZXJzW3BvaW50ZXJFdmVudC5wb2ludGVySWRdID0gcG9pbnRlckV2ZW50O1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogY2hlY2sgaWYgZXYgbWF0Y2hlcyBwb2ludGVydHlwZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcG9pbnRlclR5cGUgbWF0Y2hlcyBgUE9JTlRFUl9NT1VTRXxUT1VDSHxQRU5gXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBldlxuICAgKi9cbiAgbWF0Y2hUeXBlOiBmdW5jdGlvbiBtYXRjaFR5cGUocG9pbnRlclR5cGUsIGV2KSB7XG4gICAgaWYgKCFldi5wb2ludGVyVHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBwdCA9IGV2LnBvaW50ZXJUeXBlLFxuICAgICAgICB0eXBlcyA9IHt9O1xuXG4gICAgdHlwZXNbUE9JTlRFUl9NT1VTRV0gPSAocHQgPT09IChldi5NU1BPSU5URVJfVFlQRV9NT1VTRSB8fCBQT0lOVEVSX01PVVNFKSk7XG4gICAgdHlwZXNbUE9JTlRFUl9UT1VDSF0gPSAocHQgPT09IChldi5NU1BPSU5URVJfVFlQRV9UT1VDSCB8fCBQT0lOVEVSX1RPVUNIKSk7XG4gICAgdHlwZXNbUE9JTlRFUl9QRU5dID0gKHB0ID09PSAoZXYuTVNQT0lOVEVSX1RZUEVfUEVOIHx8IFBPSU5URVJfUEVOKSk7XG4gICAgcmV0dXJuIHR5cGVzW3BvaW50ZXJUeXBlXTtcbiAgfSxcblxuICAvKipcbiAgICogcmVzZXQgdGhlIHN0b3JlZCBwb2ludGVyc1xuICAgKi9cbiAgcmVzZXQ6IGZ1bmN0aW9uIHJlc2V0TGlzdCgpIHtcbiAgICB0aGlzLnBvaW50ZXJzID0ge307XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIEdlc3R1cmVEZXRlY3RvclxuICpcbiAqIEBjbGFzcyBEZXRlY3Rpb25cbiAqIEBzdGF0aWNcbiAqL1xuRGV0ZWN0aW9uID0gR2VzdHVyZURldGVjdG9yLmRldGVjdGlvbiA9IHtcbiAgLy8gY29udGFpbnMgYWxsIHJlZ2lzdGVyZWQgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzIGluIHRoZSBjb3JyZWN0IG9yZGVyXG4gIGdlc3R1cmVzOiBbXSxcblxuICAvLyBkYXRhIG9mIHRoZSBjdXJyZW50IEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlIGRldGVjdGlvbiBzZXNzaW9uXG4gIGN1cnJlbnQ6IG51bGwsXG5cbiAgLy8gdGhlIHByZXZpb3VzIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlIHNlc3Npb24gZGF0YVxuICAvLyBpcyBhIGZ1bGwgY2xvbmUgb2YgdGhlIHByZXZpb3VzIGdlc3R1cmUuY3VycmVudCBvYmplY3RcbiAgcHJldmlvdXM6IG51bGwsXG5cbiAgLy8gd2hlbiB0aGlzIGJlY29tZXMgdHJ1ZSwgbm8gZ2VzdHVyZXMgYXJlIGZpcmVkXG4gIHN0b3BwZWQ6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBzdGFydCBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSBkZXRlY3Rpb25cbiAgICogQHBhcmFtIHtHZXN0dXJlRGV0ZWN0b3IuSW5zdGFuY2V9IGluc3RcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50RGF0YVxuICAgKi9cbiAgc3RhcnREZXRlY3Q6IGZ1bmN0aW9uIHN0YXJ0RGV0ZWN0KGluc3QsIGV2ZW50RGF0YSkge1xuICAgIC8vIGFscmVhZHkgYnVzeSB3aXRoIGEgR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgZGV0ZWN0aW9uIG9uIGFuIGVsZW1lbnRcbiAgICBpZiAodGhpcy5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdG9wcGVkID0gZmFsc2U7XG5cbiAgICAvLyBob2xkcyBjdXJyZW50IHNlc3Npb25cbiAgICB0aGlzLmN1cnJlbnQgPSB7XG4gICAgICBpbnN0OiBpbnN0LCAvLyByZWZlcmVuY2UgdG8gR2VzdHVyZURldGVjdG9ySW5zdGFuY2Ugd2UncmUgd29ya2luZyBmb3JcbiAgICAgIHN0YXJ0RXZlbnQ6IFV0aWxzLmV4dGVuZCh7fSwgZXZlbnREYXRhKSwgLy8gc3RhcnQgZXZlbnREYXRhIGZvciBkaXN0YW5jZXMsIHRpbWluZyBldGNcbiAgICAgIGxhc3RFdmVudDogZmFsc2UsIC8vIGxhc3QgZXZlbnREYXRhXG4gICAgICBsYXN0Q2FsY0V2ZW50OiBmYWxzZSwgLy8gbGFzdCBldmVudERhdGEgZm9yIGNhbGN1bGF0aW9ucy5cbiAgICAgIGZ1dHVyZUNhbGNFdmVudDogZmFsc2UsIC8vIGxhc3QgZXZlbnREYXRhIGZvciBjYWxjdWxhdGlvbnMuXG4gICAgICBsYXN0Q2FsY0RhdGE6IHt9LCAvLyBsYXN0IGxhc3RDYWxjRGF0YVxuICAgICAgbmFtZTogJycgLy8gY3VycmVudCBnZXN0dXJlIHdlJ3JlIGluL2RldGVjdGVkLCBjYW4gYmUgJ3RhcCcsICdob2xkJyBldGNcbiAgICB9O1xuXG4gICAgdGhpcy5kZXRlY3QoZXZlbnREYXRhKTtcbiAgfSxcblxuICAvKipcbiAgICogR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgZGV0ZWN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudERhdGFcbiAgICogQHJldHVybiB7YW55fVxuICAgKi9cbiAgZGV0ZWN0OiBmdW5jdGlvbiBkZXRlY3QoZXZlbnREYXRhKSB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnQgfHwgdGhpcy5zdG9wcGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZXh0ZW5kIGV2ZW50IGRhdGEgd2l0aCBjYWxjdWxhdGlvbnMgYWJvdXQgc2NhbGUsIGRpc3RhbmNlIGV0Y1xuICAgIGV2ZW50RGF0YSA9IHRoaXMuZXh0ZW5kRXZlbnREYXRhKGV2ZW50RGF0YSk7XG5cbiAgICAvLyBHZXN0dXJlRGV0ZWN0b3IgaW5zdGFuY2UgYW5kIGluc3RhbmNlIG9wdGlvbnNcbiAgICB2YXIgaW5zdCA9IHRoaXMuY3VycmVudC5pbnN0LFxuICAgICAgICBpbnN0T3B0aW9ucyA9IGluc3Qub3B0aW9ucztcblxuICAgIC8vIGNhbGwgR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgaGFuZGxlcnNcbiAgICBVdGlscy5lYWNoKHRoaXMuZ2VzdHVyZXMsIGZ1bmN0aW9uIHRyaWdnZXJHZXN0dXJlKGdlc3R1cmUpIHtcbiAgICAgIC8vIG9ubHkgd2hlbiB0aGUgaW5zdGFuY2Ugb3B0aW9ucyBoYXZlIGVuYWJsZWQgdGhpcyBnZXN0dXJlXG4gICAgICBpZiAoIXRoaXMuc3RvcHBlZCAmJiBpbnN0LmVuYWJsZWQgJiYgaW5zdE9wdGlvbnNbZ2VzdHVyZS5uYW1lXSkge1xuICAgICAgICBnZXN0dXJlLmhhbmRsZXIuY2FsbChnZXN0dXJlLCBldmVudERhdGEsIGluc3QpO1xuICAgICAgfVxuICAgIH0sIHRoaXMpO1xuXG4gICAgLy8gc3RvcmUgYXMgcHJldmlvdXMgZXZlbnQgZXZlbnRcbiAgICBpZiAodGhpcy5jdXJyZW50KSB7XG4gICAgICB0aGlzLmN1cnJlbnQubGFzdEV2ZW50ID0gZXZlbnREYXRhO1xuICAgIH1cblxuICAgIGlmIChldmVudERhdGEuZXZlbnRUeXBlID09IEVWRU5UX0VORCkge1xuICAgICAgdGhpcy5zdG9wRGV0ZWN0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV2ZW50RGF0YTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICB9LFxuXG4gIC8qKlxuICAgKiBjbGVhciB0aGUgR2VzdHVyZURldGVjdG9yLmdlc3R1cmUgdmFyc1xuICAgKiB0aGlzIGlzIGNhbGxlZCBvbiBlbmREZXRlY3QsIGJ1dCBjYW4gYWxzbyBiZSB1c2VkIHdoZW4gYSBmaW5hbCBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSBoYXMgYmVlbiBkZXRlY3RlZFxuICAgKiB0byBzdG9wIG90aGVyIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcyBmcm9tIGJlaW5nIGZpcmVkXG4gICAqL1xuICBzdG9wRGV0ZWN0OiBmdW5jdGlvbiBzdG9wRGV0ZWN0KCkge1xuICAgIC8vIGNsb25lIGN1cnJlbnQgZGF0YSB0byB0aGUgc3RvcmUgYXMgdGhlIHByZXZpb3VzIGdlc3R1cmVcbiAgICAvLyB1c2VkIGZvciB0aGUgZG91YmxlIHRhcCBnZXN0dXJlLCBzaW5jZSB0aGlzIGlzIGFuIG90aGVyIGdlc3R1cmUgZGV0ZWN0IHNlc3Npb25cbiAgICB0aGlzLnByZXZpb3VzID0gVXRpbHMuZXh0ZW5kKHt9LCB0aGlzLmN1cnJlbnQpO1xuXG4gICAgLy8gcmVzZXQgdGhlIGN1cnJlbnRcbiAgICB0aGlzLmN1cnJlbnQgPSBudWxsO1xuICAgIHRoaXMuc3RvcHBlZCA9IHRydWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIGNhbGN1bGF0ZSB2ZWxvY2l0eSwgYW5nbGUgYW5kIGRpcmVjdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICogQHBhcmFtIHtPYmplY3R9IGNlbnRlclxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFUaW1lXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVhcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhWVxuICAgKi9cbiAgZ2V0Q2FsY3VsYXRlZERhdGE6IGZ1bmN0aW9uIGdldENhbGN1bGF0ZWREYXRhKGV2LCBjZW50ZXIsIGRlbHRhVGltZSwgZGVsdGFYLCBkZWx0YVkpIHtcbiAgICB2YXIgY3VyID0gdGhpcy5jdXJyZW50LFxuICAgICAgICByZWNhbGMgPSBmYWxzZSxcbiAgICAgICAgY2FsY0V2ID0gY3VyLmxhc3RDYWxjRXZlbnQsXG4gICAgICAgIGNhbGNEYXRhID0gY3VyLmxhc3RDYWxjRGF0YTtcblxuICAgIGlmIChjYWxjRXYgJiYgZXYudGltZVN0YW1wIC0gY2FsY0V2LnRpbWVTdGFtcCA+IEdlc3R1cmVEZXRlY3Rvci5DQUxDVUxBVEVfSU5URVJWQUwpIHtcbiAgICAgIGNlbnRlciA9IGNhbGNFdi5jZW50ZXI7XG4gICAgICBkZWx0YVRpbWUgPSBldi50aW1lU3RhbXAgLSBjYWxjRXYudGltZVN0YW1wO1xuICAgICAgZGVsdGFYID0gZXYuY2VudGVyLmNsaWVudFggLSBjYWxjRXYuY2VudGVyLmNsaWVudFg7XG4gICAgICBkZWx0YVkgPSBldi5jZW50ZXIuY2xpZW50WSAtIGNhbGNFdi5jZW50ZXIuY2xpZW50WTtcbiAgICAgIHJlY2FsYyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9UT1VDSCB8fCBldi5ldmVudFR5cGUgPT0gRVZFTlRfUkVMRUFTRSkge1xuICAgICAgY3VyLmZ1dHVyZUNhbGNFdmVudCA9IGV2O1xuICAgIH1cblxuICAgIGlmICghY3VyLmxhc3RDYWxjRXZlbnQgfHwgcmVjYWxjKSB7XG4gICAgICBjYWxjRGF0YS52ZWxvY2l0eSA9IFV0aWxzLmdldFZlbG9jaXR5KGRlbHRhVGltZSwgZGVsdGFYLCBkZWx0YVkpO1xuICAgICAgY2FsY0RhdGEuYW5nbGUgPSBVdGlscy5nZXRBbmdsZShjZW50ZXIsIGV2LmNlbnRlcik7XG4gICAgICBjYWxjRGF0YS5kaXJlY3Rpb24gPSBVdGlscy5nZXREaXJlY3Rpb24oY2VudGVyLCBldi5jZW50ZXIpO1xuXG4gICAgICBjdXIubGFzdENhbGNFdmVudCA9IGN1ci5mdXR1cmVDYWxjRXZlbnQgfHwgZXY7XG4gICAgICBjdXIuZnV0dXJlQ2FsY0V2ZW50ID0gZXY7XG4gICAgfVxuXG4gICAgZXYudmVsb2NpdHlYID0gY2FsY0RhdGEudmVsb2NpdHkueDtcbiAgICBldi52ZWxvY2l0eVkgPSBjYWxjRGF0YS52ZWxvY2l0eS55O1xuICAgIGV2LmludGVyaW1BbmdsZSA9IGNhbGNEYXRhLmFuZ2xlO1xuICAgIGV2LmludGVyaW1EaXJlY3Rpb24gPSBjYWxjRGF0YS5kaXJlY3Rpb247XG4gIH0sXG5cbiAgLyoqXG4gICAqIGV4dGVuZCBldmVudERhdGEgZm9yIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlc1xuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICogQHJldHVybiB7T2JqZWN0fSBldlxuICAgKi9cbiAgZXh0ZW5kRXZlbnREYXRhOiBmdW5jdGlvbiBleHRlbmRFdmVudERhdGEoZXYpIHtcbiAgICB2YXIgY3VyID0gdGhpcy5jdXJyZW50LFxuICAgICAgICBzdGFydEV2ID0gY3VyLnN0YXJ0RXZlbnQsXG4gICAgICAgIGxhc3RFdiA9IGN1ci5sYXN0RXZlbnQgfHwgc3RhcnRFdjtcblxuICAgIC8vIHVwZGF0ZSB0aGUgc3RhcnQgdG91Y2hsaXN0IHRvIGNhbGN1bGF0ZSB0aGUgc2NhbGUvcm90YXRpb25cbiAgICBpZiAoZXYuZXZlbnRUeXBlID09IEVWRU5UX1RPVUNIIHx8IGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9SRUxFQVNFKSB7XG4gICAgICBzdGFydEV2LnRvdWNoZXMgPSBbXTtcbiAgICAgIFV0aWxzLmVhY2goZXYudG91Y2hlcywgZnVuY3Rpb24odG91Y2gpIHtcbiAgICAgICAgc3RhcnRFdi50b3VjaGVzLnB1c2goe1xuICAgICAgICAgIGNsaWVudFg6IHRvdWNoLmNsaWVudFgsXG4gICAgICAgICAgY2xpZW50WTogdG91Y2guY2xpZW50WVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBkZWx0YVRpbWUgPSBldi50aW1lU3RhbXAgLSBzdGFydEV2LnRpbWVTdGFtcCxcbiAgICAgICAgZGVsdGFYID0gZXYuY2VudGVyLmNsaWVudFggLSBzdGFydEV2LmNlbnRlci5jbGllbnRYLFxuICAgICAgICBkZWx0YVkgPSBldi5jZW50ZXIuY2xpZW50WSAtIHN0YXJ0RXYuY2VudGVyLmNsaWVudFk7XG5cbiAgICB0aGlzLmdldENhbGN1bGF0ZWREYXRhKGV2LCBsYXN0RXYuY2VudGVyLCBkZWx0YVRpbWUsIGRlbHRhWCwgZGVsdGFZKTtcblxuICAgIFV0aWxzLmV4dGVuZChldiwge1xuICAgICAgc3RhcnRFdmVudDogc3RhcnRFdixcblxuICAgICAgZGVsdGFUaW1lOiBkZWx0YVRpbWUsXG4gICAgICBkZWx0YVg6IGRlbHRhWCxcbiAgICAgIGRlbHRhWTogZGVsdGFZLFxuXG4gICAgICBkaXN0YW5jZTogVXRpbHMuZ2V0RGlzdGFuY2Uoc3RhcnRFdi5jZW50ZXIsIGV2LmNlbnRlciksXG4gICAgICBhbmdsZTogVXRpbHMuZ2V0QW5nbGUoc3RhcnRFdi5jZW50ZXIsIGV2LmNlbnRlciksXG4gICAgICBkaXJlY3Rpb246IFV0aWxzLmdldERpcmVjdGlvbihzdGFydEV2LmNlbnRlciwgZXYuY2VudGVyKSxcbiAgICAgIHNjYWxlOiBVdGlscy5nZXRTY2FsZShzdGFydEV2LnRvdWNoZXMsIGV2LnRvdWNoZXMpLFxuICAgICAgcm90YXRpb246IFV0aWxzLmdldFJvdGF0aW9uKHN0YXJ0RXYudG91Y2hlcywgZXYudG91Y2hlcylcbiAgICB9KTtcblxuICAgIHJldHVybiBldjtcbiAgfSxcblxuICAvKipcbiAgICogcmVnaXN0ZXIgbmV3IGdlc3R1cmVcbiAgICogQHBhcmFtIHtPYmplY3R9IGdlc3R1cmUgb2JqZWN0LCBzZWUgYGdlc3R1cmVzL2AgZm9yIGRvY3VtZW50YXRpb25cbiAgICogQHJldHVybiB7QXJyYXl9IGdlc3R1cmVzXG4gICAqL1xuICByZWdpc3RlcjogZnVuY3Rpb24gcmVnaXN0ZXIoZ2VzdHVyZSkge1xuICAgIC8vIGFkZCBhbiBlbmFibGUgZ2VzdHVyZSBvcHRpb25zIGlmIHRoZXJlIGlzIG5vIGdpdmVuXG4gICAgdmFyIG9wdGlvbnMgPSBnZXN0dXJlLmRlZmF1bHRzIHx8IHt9O1xuICAgIGlmIChvcHRpb25zW2dlc3R1cmUubmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9uc1tnZXN0dXJlLm5hbWVdID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBleHRlbmQgR2VzdHVyZURldGVjdG9yIGRlZmF1bHQgb3B0aW9ucyB3aXRoIHRoZSBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSBvcHRpb25zXG4gICAgVXRpbHMuZXh0ZW5kKEdlc3R1cmVEZXRlY3Rvci5kZWZhdWx0cywgb3B0aW9ucywgdHJ1ZSk7XG5cbiAgICAvLyBzZXQgaXRzIGluZGV4XG4gICAgZ2VzdHVyZS5pbmRleCA9IGdlc3R1cmUuaW5kZXggfHwgMTAwMDtcblxuICAgIC8vIGFkZCBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZSB0byB0aGUgbGlzdFxuICAgIHRoaXMuZ2VzdHVyZXMucHVzaChnZXN0dXJlKTtcblxuICAgIC8vIHNvcnQgdGhlIGxpc3QgYnkgaW5kZXhcbiAgICB0aGlzLmdlc3R1cmVzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgaWYgKGEuaW5kZXggPCBiLmluZGV4KSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIGlmIChhLmluZGV4ID4gYi5pbmRleCkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2VzdHVyZXM7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIEdlc3R1cmVEZXRlY3RvclxuICovXG5cbi8qKlxuICogY3JlYXRlIG5ldyBHZXN0dXJlRGV0ZWN0b3IgaW5zdGFuY2VcbiAqIGFsbCBtZXRob2RzIHNob3VsZCByZXR1cm4gdGhlIGluc3RhbmNlIGl0c2VsZiwgc28gaXQgaXMgY2hhaW5hYmxlLlxuICpcbiAqIEBjbGFzcyBJbnN0YW5jZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIG9wdGlvbnMgYXJlIG1lcmdlZCB3aXRoIGBHZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHNgXG4gKiBAcmV0dXJuIHtHZXN0dXJlRGV0ZWN0b3IuSW5zdGFuY2V9XG4gKi9cbkdlc3R1cmVEZXRlY3Rvci5JbnN0YW5jZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgbGlzdGVuZXJPcHRpb25zID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5wYXNzaXZlKSA/IHsgcGFzc2l2ZTogdHJ1ZSB9IDogdW5kZWZpbmVkO1xuXG4gIC8vIHNldHVwIEdlc3R1cmVEZXRlY3RvckpTIHdpbmRvdyBldmVudHMgYW5kIHJlZ2lzdGVyIGFsbCBnZXN0dXJlc1xuICAvLyB0aGlzIGFsc28gc2V0cyB1cCB0aGUgZGVmYXVsdCBvcHRpb25zXG4gIHNldHVwKGxpc3RlbmVyT3B0aW9ucyk7XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBlbGVtZW50XG4gICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBlbmFibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICB0aGlzLmVuYWJsZWQgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBvcHRpb25zLCBtZXJnZWQgd2l0aCB0aGUgZGVmYXVsdHNcbiAgICogb3B0aW9ucyB3aXRoIGFuIF8gYXJlIGNvbnZlcnRlZCB0byBjYW1lbENhc2VcbiAgICogQHByb3BlcnR5IG9wdGlvbnNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIFV0aWxzLmVhY2gob3B0aW9ucywgZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICBkZWxldGUgb3B0aW9uc1tuYW1lXTtcbiAgICBvcHRpb25zW1V0aWxzLnRvQ2FtZWxDYXNlKG5hbWUpXSA9IHZhbHVlO1xuICB9KTtcblxuICB0aGlzLm9wdGlvbnMgPSBVdGlscy5leHRlbmQoVXRpbHMuZXh0ZW5kKHt9LCBHZXN0dXJlRGV0ZWN0b3IuZGVmYXVsdHMpLCBvcHRpb25zIHx8IHt9KTtcbiAgdGhpcy5vcHRpb25zLmxpc3RlbmVyT3B0aW9ucyA9IGxpc3RlbmVyT3B0aW9ucztcblxuICAvLyBhZGQgc29tZSBjc3MgdG8gdGhlIGVsZW1lbnQgdG8gcHJldmVudCB0aGUgYnJvd3NlciBmcm9tIGRvaW5nIGl0cyBuYXRpdmUgYmVoYXZpb3JcbiAgaWYgKHRoaXMub3B0aW9ucy5iZWhhdmlvcikge1xuICAgIFV0aWxzLnRvZ2dsZUJlaGF2aW9yKHRoaXMuZWxlbWVudCwgdGhpcy5vcHRpb25zLmJlaGF2aW9yLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBldmVudCBzdGFydCBoYW5kbGVyIG9uIHRoZSBlbGVtZW50IHRvIHN0YXJ0IHRoZSBkZXRlY3Rpb25cbiAgICogQHByb3BlcnR5IGV2ZW50U3RhcnRIYW5kbGVyXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLmV2ZW50U3RhcnRIYW5kbGVyID0gRXZlbnQub25Ub3VjaChlbGVtZW50LCBFVkVOVF9TVEFSVCwgZnVuY3Rpb24oZXYpIHtcbiAgICBpZiAoc2VsZi5lbmFibGVkICYmIGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9TVEFSVCkge1xuICAgICAgRGV0ZWN0aW9uLnN0YXJ0RGV0ZWN0KHNlbGYsIGV2KTtcbiAgICB9IGVsc2UgaWYgKGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9UT1VDSCkge1xuICAgICAgRGV0ZWN0aW9uLmRldGVjdChldik7XG4gICAgfVxuICB9LCBsaXN0ZW5lck9wdGlvbnMpO1xuXG4gIC8qKlxuICAgKiBrZWVwIGEgbGlzdCBvZiB1c2VyIGV2ZW50IGhhbmRsZXJzIHdoaWNoIG5lZWRzIHRvIGJlIHJlbW92ZWQgd2hlbiBjYWxsaW5nICdkaXNwb3NlJ1xuICAgKiBAcHJvcGVydHkgZXZlbnRIYW5kbGVyc1xuICAgKiBAdHlwZSB7QXJyYXl9XG4gICAqL1xuICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBbXTtcbn07XG5cbkdlc3R1cmVEZXRlY3Rvci5JbnN0YW5jZS5wcm90b3R5cGUgPSB7XG4gIC8qKlxuICAgKiBAbWV0aG9kIG9uXG4gICAqIEBzaWduYXR1cmUgb24oZ2VzdHVyZXMsIGhhbmRsZXIpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUFkZHMgYW4gZXZlbnQgaGFuZGxlciBmb3IgYSBnZXN0dXJlLiBBdmFpbGFibGUgZ2VzdHVyZXMgYXJlOiBkcmFnLCBkcmFnbGVmdCwgZHJhZ3JpZ2h0LCBkcmFndXAsIGRyYWdkb3duLCBob2xkLCByZWxlYXNlLCBzd2lwZSwgc3dpcGVsZWZ0LCBzd2lwZXJpZ2h0LCBzd2lwZXVwLCBzd2lwZWRvd24sIHRhcCwgZG91YmxldGFwLCB0b3VjaCwgdHJhbnNmb3JtLCBwaW5jaCwgcGluY2hpbiwgcGluY2hvdXQgYW5kIHJvdGF0ZS4gWy9lbl1cbiAgICogIFtqYV3jgrjjgqfjgrnjg4Hjg6Pjgavlr77jgZnjgovjgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgpLov73liqDjgZfjgb7jgZnjgILmjIflrprjgafjgY3jgovjgrjjgqfjgrnjg4Hjg6PlkI3jga/jgIFkcmFnIGRyYWdsZWZ0IGRyYWdyaWdodCBkcmFndXAgZHJhZ2Rvd24gaG9sZCByZWxlYXNlIHN3aXBlIHN3aXBlbGVmdCBzd2lwZXJpZ2h0IHN3aXBldXAgc3dpcGVkb3duIHRhcCBkb3VibGV0YXAgdG91Y2ggdHJhbnNmb3JtIHBpbmNoIHBpbmNoaW4gcGluY2hvdXQgcm90YXRlIOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBnZXN0dXJlc1xuICAgKiAgIFtlbl1BIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mIGdlc3R1cmVzLlsvZW5dXG4gICAqICAgW2phXeaknOefpeOBmeOCi+OCuOOCp+OCueODgeODo+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAguOCueODmuODvOOCueOBp+ikh+aVsOaMh+WumuOBmeOCi+OBk+OBqOOBjOOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAgICogICBbZW5dQW4gZXZlbnQgaGFuZGxpbmcgZnVuY3Rpb24uWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44OP44Oz44OJ44Op44Go44Gq44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIG9uOiBmdW5jdGlvbiBvbkV2ZW50KGdlc3R1cmVzLCBoYW5kbGVyLCBvcHQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBFdmVudC5vbihzZWxmLmVsZW1lbnQsIGdlc3R1cmVzLCBoYW5kbGVyLCB1dGlsLmV4dGVuZCh7fSwgc2VsZi5vcHRpb25zLmxpc3RlbmVyT3B0aW9ucywgb3B0KSwgZnVuY3Rpb24odHlwZSkge1xuICAgICAgc2VsZi5ldmVudEhhbmRsZXJzLnB1c2goeyBnZXN0dXJlOiB0eXBlLCBoYW5kbGVyOiBoYW5kbGVyIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBzZWxmO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIG9mZlxuICAgKiBAc2lnbmF0dXJlIG9mZihnZXN0dXJlcywgaGFuZGxlcilcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dUmVtb3ZlIGFuIGV2ZW50IGxpc3RlbmVyLlsvZW5dXG4gICAqICBbamFd44Kk44OZ44Oz44OI44Oq44K544OK44O844KS5YmK6Zmk44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGdlc3R1cmVzXG4gICAqICAgW2VuXUEgc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgZ2VzdHVyZXMuWy9lbl1cbiAgICogICBbamFd44K444Kn44K544OB44Oj5ZCN44KS5oyH5a6a44GX44G+44GZ44CC44K544Oa44O844K544Gn6KSH5pWw5oyH5a6a44GZ44KL44GT44Go44GM44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgKiAgIFtlbl1BbiBldmVudCBoYW5kbGluZyBmdW5jdGlvbi5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgajjgarjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgb2ZmOiBmdW5jdGlvbiBvZmZFdmVudChnZXN0dXJlcywgaGFuZGxlciwgb3B0KSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgRXZlbnQub2ZmKHNlbGYuZWxlbWVudCwgZ2VzdHVyZXMsIGhhbmRsZXIsIHV0aWwuZXh0ZW5kKHt9LCBzZWxmLm9wdGlvbnMubGlzdGVuZXJPcHRpb25zLCBvcHQpLCBmdW5jdGlvbih0eXBlKSB7XG4gICAgICB2YXIgaW5kZXggPSBVdGlscy5pbkFycmF5KHNlbGYuZXZlbnRIYW5kbGVycywgeyBnZXN0dXJlOiB0eXBlLCBoYW5kbGVyOiBoYW5kbGVyIH0sIHRydWUpO1xuICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgc2VsZi5ldmVudEhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHNlbGY7XG4gIH0sXG5cbiAgLyoqXG4gICAqIHRyaWdnZXIgZ2VzdHVyZSBldmVudFxuICAgKiBAbWV0aG9kIHRyaWdnZXJcbiAgICogQHNpZ25hdHVyZSB0cmlnZ2VyKGdlc3R1cmUsIGV2ZW50RGF0YSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IGdlc3R1cmVcbiAgICogQHBhcmFtIHtPYmplY3R9IFtldmVudERhdGFdXG4gICAqL1xuICB0cmlnZ2VyOiBmdW5jdGlvbiB0cmlnZ2VyRXZlbnQoZ2VzdHVyZSwgZXZlbnREYXRhKSB7XG4gICAgLy8gb3B0aW9uYWxcbiAgICBpZiAoIWV2ZW50RGF0YSkge1xuICAgICAgZXZlbnREYXRhID0ge307XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIERPTSBldmVudFxuICAgIHZhciBldmVudCA9IEdlc3R1cmVEZXRlY3Rvci5ET0NVTUVOVC5jcmVhdGVFdmVudCgnRXZlbnQnKTtcbiAgICBldmVudC5pbml0RXZlbnQoZ2VzdHVyZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgZXZlbnQuZ2VzdHVyZSA9IGV2ZW50RGF0YTtcblxuICAgIC8vIHRyaWdnZXIgb24gdGhlIHRhcmdldCBpZiBpdCBpcyBpbiB0aGUgaW5zdGFuY2UgZWxlbWVudCxcbiAgICAvLyB0aGlzIGlzIGZvciBldmVudCBkZWxlZ2F0aW9uIHRyaWNrc1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuICAgIGlmIChVdGlscy5oYXNQYXJlbnQoZXZlbnREYXRhLnRhcmdldCwgZWxlbWVudCkpIHtcbiAgICAgIGVsZW1lbnQgPSBldmVudERhdGEudGFyZ2V0O1xuICAgIH1cblxuICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgZW5hYmxlXG4gICAqIEBzaWduYXR1cmUgZW5hYmxlKHN0YXRlKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1FbmFibGUgb3IgZGlzYWJsZSBnZXN0dXJlIGRldGVjdGlvbi5bL2VuXVxuICAgKiAgW2phXeOCuOOCp+OCueODgeODo+aknOefpeOCkuacieWKueWMli/nhKHlirnljJbjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN0YXRlXG4gICAqICAgW2VuXVNwZWNpZnkgaWYgaXQgc2hvdWxkIGJlIGVuYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeacieWKueOBq+OBmeOCi+OBi+OBqeOBhuOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBlbmFibGU6IGZ1bmN0aW9uIGVuYWJsZShzdGF0ZSkge1xuICAgIHRoaXMuZW5hYmxlZCA9IHN0YXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGRpc3Bvc2VcbiAgICogQHNpZ25hdHVyZSBkaXNwb3NlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dUmVtb3ZlIGFuZCBkZXN0cm95IGFsbCBldmVudCBoYW5kbGVycyBmb3IgdGhpcyBpbnN0YW5jZS5bL2VuXVxuICAgKiAgW2phXeOBk+OBruOCpOODs+OCueOCv+ODs+OCueOBp+OBruOCuOOCp+OCueODgeODo+OBruaknOefpeOChOOAgeOCpOODmeODs+ODiOODj+ODs+ODieODqeOCkuWFqOOBpuino+mZpOOBl+OBpuW7g+ajhOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBkaXNwb3NlOiBmdW5jdGlvbiBkaXNwb3NlKCkge1xuICAgIHZhciBpLCBlaDtcblxuICAgIC8vIHVuZG8gYWxsIGNoYW5nZXMgbWFkZSBieSBzdG9wX2Jyb3dzZXJfYmVoYXZpb3JcbiAgICBVdGlscy50b2dnbGVCZWhhdmlvcih0aGlzLmVsZW1lbnQsIHRoaXMub3B0aW9ucy5iZWhhdmlvciwgZmFsc2UpO1xuXG4gICAgLy8gdW5iaW5kIGFsbCBjdXN0b20gZXZlbnQgaGFuZGxlcnNcbiAgICBmb3IgKGkgPSAtMTsgKGVoID0gdGhpcy5ldmVudEhhbmRsZXJzWysraV0pOykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWNvbmQtYXNzaWduXG4gICAgICBVdGlscy5vZmYodGhpcy5lbGVtZW50LCBlaC5nZXN0dXJlLCBlaC5oYW5kbGVyKTtcbiAgICB9XG5cbiAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBbXTtcblxuICAgIC8vIHVuYmluZCB0aGUgc3RhcnQgZXZlbnQgbGlzdGVuZXJcbiAgICBFdmVudC5vZmYodGhpcy5lbGVtZW50LCBFVkVOVF9UWVBFU1tFVkVOVF9TVEFSVF0sIHRoaXMuZXZlbnRTdGFydEhhbmRsZXIpO1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBAbW9kdWxlIGdlc3R1cmVzXG4gKi9cbi8qKlxuICogTW92ZSB3aXRoIHggZmluZ2VycyAoZGVmYXVsdCAxKSBhcm91bmQgb24gdGhlIHBhZ2UuXG4gKiBQcmV2ZW50aW5nIHRoZSBkZWZhdWx0IGJyb3dzZXIgYmVoYXZpb3IgaXMgYSBnb29kIHdheSB0byBpbXByb3ZlIGZlZWwgYW5kIHdvcmtpbmcuXG4gKiBgYGBgXG4gKiAgR2VzdHVyZURldGVjdG9ydGltZS5vbihcImRyYWdcIiwgZnVuY3Rpb24oZXYpIHtcbiAqICAgIGNvbnNvbGUubG9nKGV2KTtcbiAqICAgIGV2Lmdlc3R1cmUucHJldmVudERlZmF1bHQoKTtcbiAqICB9KTtcbiAqIGBgYGBcbiAqXG4gKiBAY2xhc3MgRHJhZ1xuICogQHN0YXRpY1xuICovXG4vKipcbiAqIEBldmVudCBkcmFnXG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ3N0YXJ0XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ2VuZFxuICogQHBhcmFtIHtPYmplY3R9IGV2XG4gKi9cbi8qKlxuICogQGV2ZW50IGRyYXBsZWZ0XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ3JpZ2h0XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ3VwXG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqL1xuLyoqXG4gKiBAZXZlbnQgZHJhZ2Rvd25cbiAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICovXG5cbi8qKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqL1xuKGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIHRyaWdnZXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGRyYWdHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgdmFyIGN1ciA9IERldGVjdGlvbi5jdXJyZW50O1xuXG4gICAgLy8gbWF4IHRvdWNoZXNcbiAgICBpZiAoaW5zdC5vcHRpb25zLmRyYWdNYXhUb3VjaGVzID4gMCAmJlxuICAgICAgZXYudG91Y2hlcy5sZW5ndGggPiBpbnN0Lm9wdGlvbnMuZHJhZ01heFRvdWNoZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGV2LmV2ZW50VHlwZSkge1xuICAgIGNhc2UgRVZFTlRfU1RBUlQ6XG4gICAgICB0cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBFVkVOVF9NT1ZFOlxuICAgICAgLy8gd2hlbiB0aGUgZGlzdGFuY2Ugd2UgbW92ZWQgaXMgdG9vIHNtYWxsIHdlIHNraXAgdGhpcyBnZXN0dXJlXG4gICAgICAvLyBvciB3ZSBjYW4gYmUgYWxyZWFkeSBpbiBkcmFnZ2luZ1xuICAgICAgaWYgKGV2LmRpc3RhbmNlIDwgaW5zdC5vcHRpb25zLmRyYWdNaW5EaXN0YW5jZSAmJlxuICAgICAgICBjdXIubmFtZSAhPSBuYW1lKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0YXJ0Q2VudGVyID0gY3VyLnN0YXJ0RXZlbnQuY2VudGVyO1xuXG4gICAgICAvLyB3ZSBhcmUgZHJhZ2dpbmchXG4gICAgICBpZiAoY3VyLm5hbWUgIT0gbmFtZSkge1xuICAgICAgICBjdXIubmFtZSA9IG5hbWU7XG4gICAgICAgIGlmIChpbnN0Lm9wdGlvbnMuZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvbiAmJiBldi5kaXN0YW5jZSA+IDApIHtcbiAgICAgICAgICAvLyBXaGVuIGEgZHJhZyBpcyB0cmlnZ2VyZWQsIHNldCB0aGUgZXZlbnQgY2VudGVyIHRvIGRyYWdNaW5EaXN0YW5jZSBwaXhlbHMgZnJvbSB0aGUgb3JpZ2luYWwgZXZlbnQgY2VudGVyLlxuICAgICAgICAgIC8vIFdpdGhvdXQgdGhpcyBjb3JyZWN0aW9uLCB0aGUgZHJhZ2dlZCBkaXN0YW5jZSB3b3VsZCBqdW1wc3RhcnQgYXQgZHJhZ01pbkRpc3RhbmNlIHBpeGVscyBpbnN0ZWFkIG9mIGF0IDAuXG4gICAgICAgICAgLy8gSXQgbWlnaHQgYmUgdXNlZnVsIHRvIHNhdmUgdGhlIG9yaWdpbmFsIHN0YXJ0IHBvaW50IHNvbWV3aGVyZVxuICAgICAgICAgIHZhciBmYWN0b3IgPSBNYXRoLmFicyhpbnN0Lm9wdGlvbnMuZHJhZ01pbkRpc3RhbmNlIC8gZXYuZGlzdGFuY2UpO1xuICAgICAgICAgIHN0YXJ0Q2VudGVyLnBhZ2VYICs9IGV2LmRlbHRhWCAqIGZhY3RvcjtcbiAgICAgICAgICBzdGFydENlbnRlci5wYWdlWSArPSBldi5kZWx0YVkgKiBmYWN0b3I7XG4gICAgICAgICAgc3RhcnRDZW50ZXIuY2xpZW50WCArPSBldi5kZWx0YVggKiBmYWN0b3I7XG4gICAgICAgICAgc3RhcnRDZW50ZXIuY2xpZW50WSArPSBldi5kZWx0YVkgKiBmYWN0b3I7XG5cbiAgICAgICAgICAvLyByZWNhbGN1bGF0ZSBldmVudCBkYXRhIHVzaW5nIG5ldyBzdGFydCBwb2ludFxuICAgICAgICAgIGV2ID0gRGV0ZWN0aW9uLmV4dGVuZEV2ZW50RGF0YShldik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbG9jayBkcmFnIHRvIGF4aXM/XG4gICAgICBpZiAoY3VyLmxhc3RFdmVudC5kcmFnTG9ja1RvQXhpcyB8fFxuICAgICAgICAoIGluc3Qub3B0aW9ucy5kcmFnTG9ja1RvQXhpcyAmJlxuICAgICAgICAgIGluc3Qub3B0aW9ucy5kcmFnTG9ja01pbkRpc3RhbmNlIDw9IGV2LmRpc3RhbmNlXG4gICAgICAgICkpIHtcbiAgICAgICAgICBldi5kcmFnTG9ja1RvQXhpcyA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBrZWVwIGRpcmVjdGlvbiBvbiB0aGUgYXhpcyB0aGF0IHRoZSBkcmFnIGdlc3R1cmUgc3RhcnRlZCBvblxuICAgICAgICB2YXIgbGFzdERpcmVjdGlvbiA9IGN1ci5sYXN0RXZlbnQuZGlyZWN0aW9uO1xuICAgICAgICBpZiAoZXYuZHJhZ0xvY2tUb0F4aXMgJiYgbGFzdERpcmVjdGlvbiAhPT0gZXYuZGlyZWN0aW9uKSB7XG4gICAgICAgICAgaWYgKFV0aWxzLmlzVmVydGljYWwobGFzdERpcmVjdGlvbikpIHtcbiAgICAgICAgICAgIGV2LmRpcmVjdGlvbiA9IChldi5kZWx0YVkgPCAwKSA/IERJUkVDVElPTl9VUCA6IERJUkVDVElPTl9ET1dOO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBldi5kaXJlY3Rpb24gPSAoZXYuZGVsdGFYIDwgMCkgPyBESVJFQ1RJT05fTEVGVCA6IERJUkVDVElPTl9SSUdIVDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaXJzdCB0aW1lLCB0cmlnZ2VyIGRyYWdzdGFydCBldmVudFxuICAgICAgICBpZiAoIXRyaWdnZXJlZCkge1xuICAgICAgICAgIGluc3QudHJpZ2dlcihuYW1lICsgJ3N0YXJ0JywgZXYpO1xuICAgICAgICAgIHRyaWdnZXJlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0cmlnZ2VyIGV2ZW50c1xuICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSwgZXYpO1xuICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSArIGV2LmRpcmVjdGlvbiwgZXYpO1xuXG4gICAgICAgIHZhciBpc1ZlcnRpY2FsID0gVXRpbHMuaXNWZXJ0aWNhbChldi5kaXJlY3Rpb24pO1xuXG4gICAgICAgIC8vIGJsb2NrIHRoZSBicm93c2VyIGV2ZW50c1xuICAgICAgICBpZiAoKGluc3Qub3B0aW9ucy5kcmFnQmxvY2tWZXJ0aWNhbCAmJiBpc1ZlcnRpY2FsKSB8fFxuICAgICAgICAgIChpbnN0Lm9wdGlvbnMuZHJhZ0Jsb2NrSG9yaXpvbnRhbCAmJiAhaXNWZXJ0aWNhbCkpIHtcbiAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX1JFTEVBU0U6XG4gICAgICAgIGlmICh0cmlnZ2VyZWQgJiYgZXYuY2hhbmdlZExlbmd0aCA8PSBpbnN0Lm9wdGlvbnMuZHJhZ01heFRvdWNoZXMpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSArICdlbmQnLCBldik7XG4gICAgICAgICAgdHJpZ2dlcmVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRVZFTlRfRU5EOlxuICAgICAgICB0cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLkRyYWcgPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDUwLFxuICAgICAgaGFuZGxlcjogZHJhZ0dlc3R1cmUsXG4gICAgICBkZWZhdWx0czoge1xuICAgICAgICAvKipcbiAgICAgICAgICogbWluaW1hbCBtb3ZlbWVudCB0aGF0IGhhdmUgdG8gYmUgbWFkZSBiZWZvcmUgdGhlIGRyYWcgZXZlbnQgZ2V0cyB0cmlnZ2VyZWRcbiAgICAgICAgICogQHByb3BlcnR5IGRyYWdNaW5EaXN0YW5jZVxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAxMFxuICAgICAgICAgKi9cbiAgICAgICAgZHJhZ01pbkRpc3RhbmNlOiAxMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogU2V0IGRyYWdEaXN0YW5jZUNvcnJlY3Rpb24gdG8gdHJ1ZSB0byBtYWtlIHRoZSBzdGFydGluZyBwb2ludCBvZiB0aGUgZHJhZ1xuICAgICAgICAgKiBiZSBjYWxjdWxhdGVkIGZyb20gd2hlcmUgdGhlIGRyYWcgd2FzIHRyaWdnZXJlZCwgbm90IGZyb20gd2hlcmUgdGhlIHRvdWNoIHN0YXJ0ZWQuXG4gICAgICAgICAqIFVzZWZ1bCB0byBhdm9pZCBhIGplcmstc3RhcnRpbmcgZHJhZywgd2hpY2ggY2FuIG1ha2UgZmluZS1hZGp1c3RtZW50c1xuICAgICAgICAgKiB0aHJvdWdoIGRyYWdnaW5nIGRpZmZpY3VsdCwgYW5kIGJlIHZpc3VhbGx5IHVuYXBwZWFsaW5nLlxuICAgICAgICAgKiBAcHJvcGVydHkgZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvblxuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAgICAgKi9cbiAgICAgICAgZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvbjogdHJ1ZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogc2V0IDAgZm9yIHVubGltaXRlZCwgYnV0IHRoaXMgY2FuIGNvbmZsaWN0IHdpdGggdHJhbnNmb3JtXG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnTWF4VG91Y2hlc1xuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAxXG4gICAgICAgICAqL1xuICAgICAgICBkcmFnTWF4VG91Y2hlczogMSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogcHJldmVudCBkZWZhdWx0IGJyb3dzZXIgYmVoYXZpb3Igd2hlbiBkcmFnZ2luZyBvY2N1cnNcbiAgICAgICAgICogYmUgY2FyZWZ1bCB3aXRoIGl0LCBpdCBtYWtlcyB0aGUgZWxlbWVudCBhIGJsb2NraW5nIGVsZW1lbnRcbiAgICAgICAgICogd2hlbiB5b3UgYXJlIHVzaW5nIHRoZSBkcmFnIGdlc3R1cmUsIGl0IGlzIGEgZ29vZCBwcmFjdGljZSB0byBzZXQgdGhpcyB0cnVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnQmxvY2tIb3Jpem9udGFsXG4gICAgICAgICAqIEB0eXBlIHtCb29sZWFufVxuICAgICAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAgICAgKi9cbiAgICAgICAgZHJhZ0Jsb2NrSG9yaXpvbnRhbDogZmFsc2UsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIHNhbWUgYXMgYGRyYWdCbG9ja0hvcml6b250YWxgLCBidXQgZm9yIHZlcnRpY2FsIG1vdmVtZW50XG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnQmxvY2tWZXJ0aWNhbFxuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAgICovXG4gICAgICAgIGRyYWdCbG9ja1ZlcnRpY2FsOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogZHJhZ0xvY2tUb0F4aXMga2VlcHMgdGhlIGRyYWcgZ2VzdHVyZSBvbiB0aGUgYXhpcyB0aGF0IGl0IHN0YXJ0ZWQgb24sXG4gICAgICAgICAqIEl0IGRpc2FsbG93cyB2ZXJ0aWNhbCBkaXJlY3Rpb25zIGlmIHRoZSBpbml0aWFsIGRpcmVjdGlvbiB3YXMgaG9yaXpvbnRhbCwgYW5kIHZpY2UgdmVyc2EuXG4gICAgICAgICAqIEBwcm9wZXJ0eSBkcmFnTG9ja1RvQXhpc1xuICAgICAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAgICovXG4gICAgICAgIGRyYWdMb2NrVG9BeGlzOiBmYWxzZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogZHJhZyBsb2NrIG9ubHkga2lja3MgaW4gd2hlbiBkaXN0YW5jZSA+IGRyYWdMb2NrTWluRGlzdGFuY2VcbiAgICAgICAgICogVGhpcyB3YXksIGxvY2tpbmcgb2NjdXJzIG9ubHkgd2hlbiB0aGUgZGlzdGFuY2UgaGFzIGJlY29tZSBsYXJnZSBlbm91Z2ggdG8gcmVsaWFibHkgZGV0ZXJtaW5lIHRoZSBkaXJlY3Rpb25cbiAgICAgICAgICogQHByb3BlcnR5IGRyYWdMb2NrTWluRGlzdGFuY2VcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMjVcbiAgICAgICAgICovXG4gICAgICAgIGRyYWdMb2NrTWluRGlzdGFuY2U6IDI1XG4gICAgICB9XG4gICAgfTtcbiAgfSkoJ2RyYWcnKTtcblxuICAvKipcbiAgICogQG1vZHVsZSBnZXN0dXJlc1xuICAgKi9cbiAgLyoqXG4gICAqIHRyaWdnZXIgYSBzaW1wbGUgZ2VzdHVyZSBldmVudCwgc28geW91IGNhbiBkbyBhbnl0aGluZyBpbiB5b3VyIGhhbmRsZXIuXG4gICAqIG9ubHkgdXNhYmxlIGlmIHlvdSBrbm93IHdoYXQgeW91ciBkb2luZy4uLlxuICAgKlxuICAgKiBAY2xhc3MgR2VzdHVyZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IGdlc3R1cmVcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICBHZXN0dXJlRGV0ZWN0b3IuZ2VzdHVyZXMuR2VzdHVyZSA9IHtcbiAgICBuYW1lOiAnZ2VzdHVyZScsXG4gICAgaW5kZXg6IDEzMzcsXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gcmVsZWFzZUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBtb2R1bGUgZ2VzdHVyZXNcbiAgICovXG4gIC8qKlxuICAgKiBUb3VjaCBzdGF5cyBhdCB0aGUgc2FtZSBwbGFjZSBmb3IgeCB0aW1lXG4gICAqXG4gICAqIEBjbGFzcyBIb2xkXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgaG9sZFxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqL1xuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciB0aW1lcjtcblxuICAgIGZ1bmN0aW9uIGhvbGRHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IGluc3Qub3B0aW9ucyxcbiAgICAgICAgICBjdXJyZW50ID0gRGV0ZWN0aW9uLmN1cnJlbnQ7XG5cbiAgICAgIHN3aXRjaCAoZXYuZXZlbnRUeXBlKSB7XG4gICAgICBjYXNlIEVWRU5UX1NUQVJUOlxuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuXG4gICAgICAgIC8vIHNldCB0aGUgZ2VzdHVyZSBzbyB3ZSBjYW4gY2hlY2sgaW4gdGhlIHRpbWVvdXQgaWYgaXQgc3RpbGwgaXNcbiAgICAgICAgY3VycmVudC5uYW1lID0gbmFtZTtcblxuICAgICAgICAvLyBzZXQgdGltZXIgYW5kIGlmIGFmdGVyIHRoZSB0aW1lb3V0IGl0IHN0aWxsIGlzIGhvbGQsXG4gICAgICAgIC8vIHdlIHRyaWdnZXIgdGhlIGhvbGQgZXZlbnRcbiAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChjdXJyZW50ICYmIGN1cnJlbnQubmFtZSA9PSBuYW1lKSB7XG4gICAgICAgICAgICBpbnN0LnRyaWdnZXIobmFtZSwgZXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgb3B0aW9ucy5ob2xkVGltZW91dCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX01PVkU6XG4gICAgICAgIGlmIChldi5kaXN0YW5jZSA+IG9wdGlvbnMuaG9sZFRocmVzaG9sZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRVZFTlRfUkVMRUFTRTpcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLkhvbGQgPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDEwLFxuICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBwcm9wZXJ0eSBob2xkVGltZW91dFxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCA1MDBcbiAgICAgICAgICovXG4gICAgICAgIGhvbGRUaW1lb3V0OiA1MDAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1vdmVtZW50IGFsbG93ZWQgd2hpbGUgaG9sZGluZ1xuICAgICAgICAgKiBAcHJvcGVydHkgaG9sZFRocmVzaG9sZFxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAyXG4gICAgICAgICAqL1xuICAgICAgICBob2xkVGhyZXNob2xkOiAyXG4gICAgICB9LFxuICAgICAgaGFuZGxlcjogaG9sZEdlc3R1cmVcbiAgICB9O1xuICB9KSgnaG9sZCcpO1xuXG4gIC8qKlxuICAgKiBAbW9kdWxlIGdlc3R1cmVzXG4gICAqL1xuICAvKipcbiAgICogd2hlbiBhIHRvdWNoIGlzIGJlaW5nIHJlbGVhc2VkIGZyb20gdGhlIHBhZ2VcbiAgICpcbiAgICogQGNsYXNzIFJlbGVhc2VcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgLyoqXG4gICAqIEBldmVudCByZWxlYXNlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKi9cbiAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLlJlbGVhc2UgPSB7XG4gICAgbmFtZTogJ3JlbGVhc2UnLFxuICAgIGluZGV4OiBJbmZpbml0eSxcbiAgICBoYW5kbGVyOiBmdW5jdGlvbiByZWxlYXNlR2VzdHVyZShldiwgaW5zdCkge1xuICAgICAgaWYgKGV2LmV2ZW50VHlwZSA9PSBFVkVOVF9SRUxFQVNFKSB7XG4gICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUsIGV2KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBtb2R1bGUgZ2VzdHVyZXNcbiAgICovXG4gIC8qKlxuICAgKiB0cmlnZ2VycyBzd2lwZSBldmVudHMgd2hlbiB0aGUgZW5kIHZlbG9jaXR5IGlzIGFib3ZlIHRoZSB0aHJlc2hvbGRcbiAgICogZm9yIGJlc3QgdXNhZ2UsIHNldCBgcHJldmVudERlZmF1bHRgIChvbiB0aGUgZHJhZyBnZXN0dXJlKSB0byBgdHJ1ZWBcbiAgICogYGBgYFxuICAgKiAgR2VzdHVyZURldGVjdG9ydGltZS5vbihcImRyYWdsZWZ0IHN3aXBlbGVmdFwiLCBmdW5jdGlvbihldikge1xuICAgKiAgICBjb25zb2xlLmxvZyhldik7XG4gICAqICAgIGV2Lmdlc3R1cmUucHJldmVudERlZmF1bHQoKTtcbiAgICogIH0pO1xuICAgKiBgYGBgXG4gICAqXG4gICAqIEBjbGFzcyBTd2lwZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKi9cbiAgLyoqXG4gICAqIEBldmVudCBzd2lwZWxlZnRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBlcmlnaHRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBldXBcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHN3aXBlZG93blxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcy5Td2lwZSA9IHtcbiAgICBuYW1lOiAnc3dpcGUnLFxuICAgIGluZGV4OiA0MCxcbiAgICBkZWZhdWx0czoge1xuICAgICAgLyoqXG4gICAgICAgKiBAcHJvcGVydHkgc3dpcGVNaW5Ub3VjaGVzXG4gICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICogQGRlZmF1bHQgMVxuICAgICAgICovXG4gICAgICBzd2lwZU1pblRvdWNoZXM6IDEsXG5cbiAgICAgIC8qKlxuICAgICAgICogQHByb3BlcnR5IHN3aXBlTWF4VG91Y2hlc1xuICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAqIEBkZWZhdWx0IDFcbiAgICAgICAqL1xuICAgICAgc3dpcGVNYXhUb3VjaGVzOiAxLFxuXG4gICAgICAvKipcbiAgICAgICAqIGhvcml6b250YWwgc3dpcGUgdmVsb2NpdHlcbiAgICAgICAqIEBwcm9wZXJ0eSBzd2lwZVZlbG9jaXR5WFxuICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAqIEBkZWZhdWx0IDAuNlxuICAgICAgICovXG4gICAgICBzd2lwZVZlbG9jaXR5WDogMC42LFxuXG4gICAgICAvKipcbiAgICAgICAqIHZlcnRpY2FsIHN3aXBlIHZlbG9jaXR5XG4gICAgICAgKiBAcHJvcGVydHkgc3dpcGVWZWxvY2l0eVlcbiAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgKiBAZGVmYXVsdCAwLjZcbiAgICAgICAqL1xuICAgICAgc3dpcGVWZWxvY2l0eVk6IDAuNlxuICAgIH0sXG5cbiAgICBoYW5kbGVyOiBmdW5jdGlvbiBzd2lwZUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAgIGlmIChldi5ldmVudFR5cGUgPT0gRVZFTlRfUkVMRUFTRSkge1xuICAgICAgICB2YXIgdG91Y2hlcyA9IGV2LnRvdWNoZXMubGVuZ3RoLFxuICAgICAgICAgICAgb3B0aW9ucyA9IGluc3Qub3B0aW9ucztcblxuICAgICAgICAvLyBtYXggdG91Y2hlc1xuICAgICAgICBpZiAodG91Y2hlcyA8IG9wdGlvbnMuc3dpcGVNaW5Ub3VjaGVzIHx8XG4gICAgICAgICAgdG91Y2hlcyA+IG9wdGlvbnMuc3dpcGVNYXhUb3VjaGVzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2hlbiB0aGUgZGlzdGFuY2Ugd2UgbW92ZWQgaXMgdG9vIHNtYWxsIHdlIHNraXAgdGhpcyBnZXN0dXJlXG4gICAgICAgIC8vIG9yIHdlIGNhbiBiZSBhbHJlYWR5IGluIGRyYWdnaW5nXG4gICAgICAgIGlmIChldi52ZWxvY2l0eVggPiBvcHRpb25zLnN3aXBlVmVsb2NpdHlYIHx8XG4gICAgICAgICAgZXYudmVsb2NpdHlZID4gb3B0aW9ucy5zd2lwZVZlbG9jaXR5WSkge1xuICAgICAgICAgIC8vIHRyaWdnZXIgc3dpcGUgZXZlbnRzXG4gICAgICAgICAgaW5zdC50cmlnZ2VyKHRoaXMubmFtZSwgZXYpO1xuICAgICAgICAgIGluc3QudHJpZ2dlcih0aGlzLm5hbWUgKyBldi5kaXJlY3Rpb24sIGV2KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQG1vZHVsZSBnZXN0dXJlc1xuICAgKi9cbiAgLyoqXG4gICAqIFNpbmdsZSB0YXAgYW5kIGEgZG91YmxlIHRhcCBvbiBhIHBsYWNlXG4gICAqXG4gICAqIEBjbGFzcyBUYXBcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgLyoqXG4gICAqIEBldmVudCB0YXBcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IGRvdWJsZXRhcFxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqL1xuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBoYXNNb3ZlZCA9IGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gdGFwR2VzdHVyZShldiwgaW5zdCkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBpbnN0Lm9wdGlvbnMsXG4gICAgICAgICAgY3VycmVudCA9IERldGVjdGlvbi5jdXJyZW50LFxuICAgICAgICAgIHByZXYgPSBEZXRlY3Rpb24ucHJldmlvdXMsXG4gICAgICAgICAgc2luY2VQcmV2LFxuICAgICAgICAgIGRpZERvdWJsZVRhcDtcblxuICAgICAgc3dpdGNoIChldi5ldmVudFR5cGUpIHtcbiAgICAgIGNhc2UgRVZFTlRfU1RBUlQ6XG4gICAgICAgIGhhc01vdmVkID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX01PVkU6XG4gICAgICAgIGhhc01vdmVkID0gaGFzTW92ZWQgfHwgKGV2LmRpc3RhbmNlID4gb3B0aW9ucy50YXBNYXhEaXN0YW5jZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEVWRU5UX0VORDpcbiAgICAgICAgaWYgKCFVdGlscy5pblN0cihldi5zcmNFdmVudC50eXBlLCAnY2FuY2VsJykgJiYgZXYuZGVsdGFUaW1lIDwgb3B0aW9ucy50YXBNYXhUaW1lICYmICFoYXNNb3ZlZCkge1xuICAgICAgICAgIC8vIHByZXZpb3VzIGdlc3R1cmUsIGZvciB0aGUgZG91YmxlIHRhcCBzaW5jZSB0aGVzZSBhcmUgdHdvIGRpZmZlcmVudCBnZXN0dXJlIGRldGVjdGlvbnNcbiAgICAgICAgICBzaW5jZVByZXYgPSBwcmV2ICYmIHByZXYubGFzdEV2ZW50ICYmIGV2LnRpbWVTdGFtcCAtIHByZXYubGFzdEV2ZW50LnRpbWVTdGFtcDtcbiAgICAgICAgICBkaWREb3VibGVUYXAgPSBmYWxzZTtcblxuICAgICAgICAgIC8vIGNoZWNrIGlmIGRvdWJsZSB0YXBcbiAgICAgICAgICBpZiAocHJldiAmJiBwcmV2Lm5hbWUgPT0gbmFtZSAmJlxuICAgICAgICAgICAgKHNpbmNlUHJldiAmJiBzaW5jZVByZXYgPCBvcHRpb25zLmRvdWJsZVRhcEludGVydmFsKSAmJlxuICAgICAgICAgICAgZXYuZGlzdGFuY2UgPCBvcHRpb25zLmRvdWJsZVRhcERpc3RhbmNlKSB7XG4gICAgICAgICAgICBpbnN0LnRyaWdnZXIoJ2RvdWJsZXRhcCcsIGV2KTtcbiAgICAgICAgICAgIGRpZERvdWJsZVRhcCA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gZG8gYSBzaW5nbGUgdGFwXG4gICAgICAgICAgaWYgKCFkaWREb3VibGVUYXAgfHwgb3B0aW9ucy50YXBBbHdheXMpIHtcbiAgICAgICAgICAgIGN1cnJlbnQubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBpbnN0LnRyaWdnZXIoY3VycmVudC5uYW1lLCBldik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcy5UYXAgPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDEwMCxcbiAgICAgIGhhbmRsZXI6IHRhcEdlc3R1cmUsXG4gICAgICBkZWZhdWx0czoge1xuICAgICAgICAvKipcbiAgICAgICAgICogbWF4IHRpbWUgb2YgYSB0YXAsIHRoaXMgaXMgZm9yIHRoZSBzbG93IHRhcHBlcnNcbiAgICAgICAgICogQHByb3BlcnR5IHRhcE1heFRpbWVcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMjUwXG4gICAgICAgICAqL1xuICAgICAgICB0YXBNYXhUaW1lOiAyNTAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1heCBkaXN0YW5jZSBvZiBtb3ZlbWVudCBvZiBhIHRhcCwgdGhpcyBpcyBmb3IgdGhlIHNsb3cgdGFwcGVyc1xuICAgICAgICAgKiBAcHJvcGVydHkgdGFwTWF4RGlzdGFuY2VcbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMTBcbiAgICAgICAgICovXG4gICAgICAgIHRhcE1heERpc3RhbmNlOiAxMCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogYWx3YXlzIHRyaWdnZXIgdGhlIGB0YXBgIGV2ZW50LCBldmVuIHdoaWxlIGRvdWJsZS10YXBwaW5nXG4gICAgICAgICAqIEBwcm9wZXJ0eSB0YXBBbHdheXNcbiAgICAgICAgICogQHR5cGUge0Jvb2xlYW59XG4gICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgICovXG4gICAgICAgIHRhcEFsd2F5czogdHJ1ZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogbWF4IGRpc3RhbmNlIGJldHdlZW4gdHdvIHRhcHNcbiAgICAgICAgICogQHByb3BlcnR5IGRvdWJsZVRhcERpc3RhbmNlXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgICAqIEBkZWZhdWx0IDIwXG4gICAgICAgICAqL1xuICAgICAgICBkb3VibGVUYXBEaXN0YW5jZTogMjAsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1heCB0aW1lIGJldHdlZW4gdHdvIHRhcHNcbiAgICAgICAgICogQHByb3BlcnR5IGRvdWJsZVRhcEludGVydmFsXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgICAqIEBkZWZhdWx0IDMwMFxuICAgICAgICAgKi9cbiAgICAgICAgZG91YmxlVGFwSW50ZXJ2YWw6IDMwMFxuICAgICAgfVxuICAgIH07XG4gIH0pKCd0YXAnKTtcblxuICAvKipcbiAgICogQG1vZHVsZSBnZXN0dXJlc1xuICAgKi9cbiAgLyoqXG4gICAqIHdoZW4gYSB0b3VjaCBpcyBiZWluZyB0b3VjaGVkIGF0IHRoZSBwYWdlXG4gICAqXG4gICAqIEBjbGFzcyBUb3VjaFxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHRvdWNoXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldlxuICAgKi9cbiAgR2VzdHVyZURldGVjdG9yLmdlc3R1cmVzLlRvdWNoID0ge1xuICAgIG5hbWU6ICd0b3VjaCcsXG4gICAgaW5kZXg6IC1JbmZpbml0eSxcbiAgICBkZWZhdWx0czoge1xuICAgICAgLyoqXG4gICAgICAgKiBjYWxsIHByZXZlbnREZWZhdWx0IGF0IHRvdWNoc3RhcnQsIGFuZCBtYWtlcyB0aGUgZWxlbWVudCBibG9ja2luZyBieSBkaXNhYmxpbmcgdGhlIHNjcm9sbGluZyBvZiB0aGUgcGFnZSxcbiAgICAgICAqIGJ1dCBpdCBpbXByb3ZlcyBnZXN0dXJlcyBsaWtlIHRyYW5zZm9ybWluZyBhbmQgZHJhZ2dpbmcuXG4gICAgICAgKiBiZSBjYXJlZnVsIHdpdGggdXNpbmcgdGhpcywgaXQgY2FuIGJlIHZlcnkgYW5ub3lpbmcgZm9yIHVzZXJzIHRvIGJlIHN0dWNrIG9uIHRoZSBwYWdlXG4gICAgICAgKiBAcHJvcGVydHkgcHJldmVudERlZmF1bHRcbiAgICAgICAqIEB0eXBlIHtCb29sZWFufVxuICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAqL1xuICAgICAgcHJldmVudERlZmF1bHQ6IGZhbHNlLFxuXG4gICAgICAvKipcbiAgICAgICAqIGRpc2FibGUgbW91c2UgZXZlbnRzLCBzbyBvbmx5IHRvdWNoIChvciBwZW4hKSBpbnB1dCB0cmlnZ2VycyBldmVudHNcbiAgICAgICAqIEBwcm9wZXJ0eSBwcmV2ZW50TW91c2VcbiAgICAgICAqIEB0eXBlIHtCb29sZWFufVxuICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAqL1xuICAgICAgcHJldmVudE1vdXNlOiBmYWxzZVxuICAgIH0sXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gdG91Y2hHZXN0dXJlKGV2LCBpbnN0KSB7XG4gICAgICBpZiAoaW5zdC5vcHRpb25zLnByZXZlbnRNb3VzZSAmJiBldi5wb2ludGVyVHlwZSA9PSBQT0lOVEVSX01PVVNFKSB7XG4gICAgICAgIGV2LnN0b3BEZXRlY3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5zdC5vcHRpb25zLnByZXZlbnREZWZhdWx0KSB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldi5ldmVudFR5cGUgPT0gRVZFTlRfVE9VQ0gpIHtcbiAgICAgICAgaW5zdC50cmlnZ2VyKCd0b3VjaCcsIGV2KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEBtb2R1bGUgZ2VzdHVyZXNcbiAgICovXG4gIC8qKlxuICAgKiBVc2VyIHdhbnQgdG8gc2NhbGUgb3Igcm90YXRlIHdpdGggMiBmaW5nZXJzXG4gICAqIFByZXZlbnRpbmcgdGhlIGRlZmF1bHQgYnJvd3NlciBiZWhhdmlvciBpcyBhIGdvb2Qgd2F5IHRvIGltcHJvdmUgZmVlbCBhbmQgd29ya2luZy4gVGhpcyBjYW4gYmUgZG9uZSB3aXRoIHRoZVxuICAgKiBgcHJldmVudERlZmF1bHRgIG9wdGlvbi5cbiAgICpcbiAgICogQGNsYXNzIFRyYW5zZm9ybVxuICAgKiBAc3RhdGljXG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHRyYW5zZm9ybVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgdHJhbnNmb3Jtc3RhcnRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHRyYW5zZm9ybWVuZFxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgcGluY2hpblxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG4gIC8qKlxuICAgKiBAZXZlbnQgcGluY2hvdXRcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAqL1xuICAvKipcbiAgICogQGV2ZW50IHJvdGF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZcbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqL1xuICAoZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciB0cmlnZ2VyZWQgPSBmYWxzZTtcblxuICAgIGZ1bmN0aW9uIHRyYW5zZm9ybUdlc3R1cmUoZXYsIGluc3QpIHtcbiAgICAgIHN3aXRjaCAoZXYuZXZlbnRUeXBlKSB7XG4gICAgICBjYXNlIEVWRU5UX1NUQVJUOlxuICAgICAgICB0cmlnZ2VyZWQgPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRVZFTlRfTU9WRTpcbiAgICAgICAgLy8gYXQgbGVhc3QgbXVsdGl0b3VjaFxuICAgICAgICBpZiAoZXYudG91Y2hlcy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNjYWxlVGhyZXNob2xkID0gTWF0aC5hYnMoMSAtIGV2LnNjYWxlKTtcbiAgICAgICAgdmFyIHJvdGF0aW9uVGhyZXNob2xkID0gTWF0aC5hYnMoZXYucm90YXRpb24pO1xuXG4gICAgICAgIC8vIHdoZW4gdGhlIGRpc3RhbmNlIHdlIG1vdmVkIGlzIHRvbyBzbWFsbCB3ZSBza2lwIHRoaXMgZ2VzdHVyZVxuICAgICAgICAvLyBvciB3ZSBjYW4gYmUgYWxyZWFkeSBpbiBkcmFnZ2luZ1xuICAgICAgICBpZiAoc2NhbGVUaHJlc2hvbGQgPCBpbnN0Lm9wdGlvbnMudHJhbnNmb3JtTWluU2NhbGUgJiZcbiAgICAgICAgICByb3RhdGlvblRocmVzaG9sZCA8IGluc3Qub3B0aW9ucy50cmFuc2Zvcm1NaW5Sb3RhdGlvbikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHdlIGFyZSB0cmFuc2Zvcm1pbmchXG4gICAgICAgIERldGVjdGlvbi5jdXJyZW50Lm5hbWUgPSBuYW1lO1xuXG4gICAgICAgIC8vIGZpcnN0IHRpbWUsIHRyaWdnZXIgZHJhZ3N0YXJ0IGV2ZW50XG4gICAgICAgIGlmICghdHJpZ2dlcmVkKSB7XG4gICAgICAgICAgaW5zdC50cmlnZ2VyKG5hbWUgKyAnc3RhcnQnLCBldik7XG4gICAgICAgICAgdHJpZ2dlcmVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGluc3QudHJpZ2dlcihuYW1lLCBldik7IC8vIGJhc2ljIHRyYW5zZm9ybSBldmVudFxuXG4gICAgICAgIC8vIHRyaWdnZXIgcm90YXRlIGV2ZW50XG4gICAgICAgIGlmIChyb3RhdGlvblRocmVzaG9sZCA+IGluc3Qub3B0aW9ucy50cmFuc2Zvcm1NaW5Sb3RhdGlvbikge1xuICAgICAgICAgIGluc3QudHJpZ2dlcigncm90YXRlJywgZXYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdHJpZ2dlciBwaW5jaCBldmVudFxuICAgICAgICBpZiAoc2NhbGVUaHJlc2hvbGQgPiBpbnN0Lm9wdGlvbnMudHJhbnNmb3JtTWluU2NhbGUpIHtcbiAgICAgICAgICBpbnN0LnRyaWdnZXIoJ3BpbmNoJywgZXYpO1xuICAgICAgICAgIGluc3QudHJpZ2dlcigncGluY2gnICsgKGV2LnNjYWxlIDwgMSA/ICdpbicgOiAnb3V0JyksIGV2KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBFVkVOVF9SRUxFQVNFOlxuICAgICAgICBpZiAodHJpZ2dlcmVkICYmIGV2LmNoYW5nZWRMZW5ndGggPCAyKSB7XG4gICAgICAgICAgaW5zdC50cmlnZ2VyKG5hbWUgKyAnZW5kJywgZXYpO1xuICAgICAgICAgIHRyaWdnZXJlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIEdlc3R1cmVEZXRlY3Rvci5nZXN0dXJlcy5UcmFuc2Zvcm0gPSB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW5kZXg6IDQ1LFxuICAgICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG1pbmltYWwgc2NhbGUgZmFjdG9yLCBubyBzY2FsZSBpcyAxLCB6b29taW4gaXMgdG8gMCBhbmQgem9vbW91dCB1bnRpbCBoaWdoZXIgdGhlbiAxXG4gICAgICAgICAqIEBwcm9wZXJ0eSB0cmFuc2Zvcm1NaW5TY2FsZVxuICAgICAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAgICAgKiBAZGVmYXVsdCAwLjAxXG4gICAgICAgICAqL1xuICAgICAgICB0cmFuc2Zvcm1NaW5TY2FsZTogMC4wMSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogcm90YXRpb24gaW4gZGVncmVlc1xuICAgICAgICAgKiBAcHJvcGVydHkgdHJhbnNmb3JtTWluUm90YXRpb25cbiAgICAgICAgICogQHR5cGUge051bWJlcn1cbiAgICAgICAgICogQGRlZmF1bHQgMVxuICAgICAgICAgKi9cbiAgICAgICAgdHJhbnNmb3JtTWluUm90YXRpb246IDFcbiAgICAgIH0sXG5cbiAgICAgIGhhbmRsZXI6IHRyYW5zZm9ybUdlc3R1cmVcbiAgICB9O1xuICB9KSgndHJhbnNmb3JtJyk7XG5cbmV4cG9ydCBkZWZhdWx0IEdlc3R1cmVEZXRlY3RvcjtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmxldCByZWFkeU1hcCwgcXVldWVNYXA7XG5cbmZ1bmN0aW9uIGlzQ29udGVudFJlYWR5KGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgc2V0Q29udGVudFJlYWR5KGVsZW1lbnQpO1xuICB9XG4gIHJldHVybiByZWFkeU1hcC5oYXMoZWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIHNldENvbnRlbnRSZWFkeShlbGVtZW50KSB7XG4gIHJlYWR5TWFwLnNldChlbGVtZW50LCB0cnVlKTtcbn1cblxuZnVuY3Rpb24gYWRkQ2FsbGJhY2soZWxlbWVudCwgZm4pIHtcbiAgaWYgKCFxdWV1ZU1hcC5oYXMoZWxlbWVudCkpIHtcbiAgICBxdWV1ZU1hcC5zZXQoZWxlbWVudCwgW10pO1xuICB9XG4gIHF1ZXVlTWFwLmdldChlbGVtZW50KS5wdXNoKGZuKTtcbn1cblxuZnVuY3Rpb24gY29uc3VtZVF1ZXVlKGVsZW1lbnQpIHtcbiAgY29uc3QgY2FsbGJhY2tzID0gcXVldWVNYXAuZ2V0KGVsZW1lbnQsIFtdKSB8fCBbXTtcbiAgcXVldWVNYXAuZGVsZXRlKGVsZW1lbnQpO1xuICBjYWxsYmFja3MuZm9yRWFjaChjYWxsYmFjayA9PiBjYWxsYmFjaygpKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29udGVudFJlYWR5KGVsZW1lbnQsIGZuID0gKCkgPT4ge30pIHtcbiAgaWYgKHJlYWR5TWFwID09PSB1bmRlZmluZWQpIHtcbiAgICByZWFkeU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcXVldWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICB9XG5cbiAgYWRkQ2FsbGJhY2soZWxlbWVudCwgZm4pO1xuXG4gIGlmIChpc0NvbnRlbnRSZWFkeShlbGVtZW50KSkge1xuICAgIGNvbnN1bWVRdWV1ZShlbGVtZW50KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKGNoYW5nZXMgPT4ge1xuICAgIHNldENvbnRlbnRSZWFkeShlbGVtZW50KTtcbiAgICBjb25zdW1lUXVldWUoZWxlbWVudCk7XG4gIH0pO1xuICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQsIHtjaGlsZExpc3Q6IHRydWUsIGNoYXJhY3RlckRhdGE6IHRydWV9KTtcblxuICAvLyBmYWlsYmFjayBmb3IgZWxlbWVudHMgaGFzIGVtcHR5IGNvbnRlbnQuXG4gIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgc2V0Q29udGVudFJlYWR5KGVsZW1lbnQpO1xuICAgIGNvbnN1bWVRdWV1ZShlbGVtZW50KTtcbiAgfSk7XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5jbGFzcyBUb2FzdFF1ZXVlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5xdWV1ZSA9IFtdO1xuICB9XG5cbiAgYWRkKGZuLCBwcm9taXNlKSB7XG4gICAgdGhpcy5xdWV1ZS5wdXNoKGZuKTtcblxuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMSkge1xuICAgICAgc2V0SW1tZWRpYXRlKHRoaXMucXVldWVbMF0pO1xuICAgIH1cblxuICAgIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cbiAgICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2V0VGltZW91dCh0aGlzLnF1ZXVlWzBdLCAxMDAwLzMwKTsgLy8gQXBwbHkgc29tZSB2aXN1YWwgZGVsYXlcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgVG9hc3RRdWV1ZSgpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi9jb250ZW50LXJlYWR5JztcbmltcG9ydCBUb2FzdFF1ZXVlIGZyb20gJy4vaW50ZXJuYWwvdG9hc3QtcXVldWUnO1xuXG5jb25zdCBfc2V0QXR0cmlidXRlcyA9IChlbGVtZW50LCBvcHRpb25zKSA9PiB7XG4gIFsnaWQnLCAnY2xhc3MnLCAnYW5pbWF0aW9uJ11cbiAgICAuZm9yRWFjaChhID0+IG9wdGlvbnMuaGFzT3duUHJvcGVydHkoYSkgJiYgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYSwgb3B0aW9uc1thXSkpO1xuXG4gIGlmIChvcHRpb25zLm1vZGlmaWVyKSB7XG4gICAgdXRpbC5hZGRNb2RpZmllcihlbGVtZW50LCBvcHRpb25zLm1vZGlmaWVyKTtcbiAgfVxufTtcblxuY29uc3QgX25vcm1hbGl6ZUFyZ3VtZW50cyA9IChtZXNzYWdlLCBvcHRpb25zID0ge30sIGRlZmF1bHRzID0ge30pID0+IHtcbiAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9O1xuICB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgPyAob3B0aW9ucy5tZXNzYWdlID0gbWVzc2FnZSkgOiAob3B0aW9ucyA9IG1lc3NhZ2UpO1xuICBpZiAoIW9wdGlvbnMgfHwgIW9wdGlvbnMubWVzc2FnZSAmJiAhb3B0aW9ucy5tZXNzYWdlSFRNTCkge1xuICAgIHV0aWwudGhyb3coJ05vdGlmaWNhdGlvbnMgbXVzdCBjb250YWluIGEgbWVzc2FnZScpO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2J1dHRvbkxhYmVscycpIHx8IG9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2J1dHRvbkxhYmVsJykpIHtcbiAgICBvcHRpb25zLmJ1dHRvbkxhYmVscyA9IG9wdGlvbnMuYnV0dG9uTGFiZWxzIHx8IG9wdGlvbnMuYnV0dG9uTGFiZWw7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wdGlvbnMuYnV0dG9uTGFiZWxzKSkge1xuICAgICAgb3B0aW9ucy5idXR0b25MYWJlbHMgPSBbb3B0aW9ucy5idXR0b25MYWJlbHMgfHwgJyddXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHV0aWwuZXh0ZW5kKHtcbiAgICAgIGNvbXBpbGU6IHBhcmFtID0+IHBhcmFtLFxuICAgICAgY2FsbGJhY2s6IHBhcmFtID0+IHBhcmFtLFxuICAgICAgYW5pbWF0aW9uOiAnZGVmYXVsdCcsXG4gICAgICBjYW5jZWxhYmxlOiBmYWxzZSxcbiAgICAgIHByaW1hcnlCdXR0b25JbmRleDogKG9wdGlvbnMuYnV0dG9uTGFiZWxzIHx8IGRlZmF1bHRzLmJ1dHRvbkxhYmVscyB8fCBbXSkubGVuZ3RoIC0gMVxuICAgIH0sIGRlZmF1bHRzLCBvcHRpb25zKTtcbn07XG5cbi8qKlxuICogQG9iamVjdCBvbnMubm90aWZpY2F0aW9uXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvbm90aWZpY2F0aW9uXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIFV0aWxpdHkgbWV0aG9kcyB0byBjcmVhdGUgZGlmZmVyZW50IGtpbmRzIG9mIG5vdGlmaWNhdGlvbnMuIFRoZXJlIGFyZSB0aHJlZSBtZXRob2RzIGF2YWlsYWJsZTpcbiAqXG4gKiAgICAgKiBgb25zLm5vdGlmaWNhdGlvbi5hbGVydCgpYFxuICogICAgICogYG9ucy5ub3RpZmljYXRpb24uY29uZmlybSgpYFxuICogICAgICogYG9ucy5ub3RpZmljYXRpb24ucHJvbXB0KClgXG4gKiAgICAgKiBgb25zLm5vdGlmaWNhdGlvbi50b2FzdCgpYFxuICpcbiAqICAgICBJdCB3aWxsIGF1dG9tYXRpY2FsbHkgZGlzcGxheSBhIE1hdGVyaWFsIERlc2lnbiBkaWFsb2cgb24gQW5kcm9pZCBkZXZpY2VzLlxuICogICBbL2VuXVxuICogICBbamFd44GE44GP44Gk44GL44Gu56iu6aGe44Gu44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44KS5L2c5oiQ44GZ44KL44Gf44KB44Gu44Om44O844OG44Kj44Oq44OG44Kj44Oh44K944OD44OJ44KS5Y+O44KB44Gf44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqIEBleGFtcGxlXG4gKiBvbnMubm90aWZpY2F0aW9uLmFsZXJ0KCdIZWxsbywgd29ybGQhJyk7XG4gKlxuICogb25zLm5vdGlmaWNhdGlvbi5jb25maXJtKCdBcmUgeW91IHJlYWR5PycpXG4gKiAgIC50aGVuKFxuICogICAgIGZ1bmN0aW9uKGFuc3dlcikge1xuICogICAgICAgaWYgKGFuc3dlciA9PT0gMSkge1xuICogICAgICAgICBvbnMubm90aWZpY2F0aW9uLmFsZXJ0KCdMZXRcXCdzIGdvIScpO1xuICogICAgICAgfVxuICogICAgIH1cbiAqICAgKTtcbiAqXG4gKiBvbnMubm90aWZpY2F0aW9uLnByb21wdCgnSG93IG9sZCBhcmUgPycpXG4gKiAgIC50aGVuKFxuICogICAgIGZ1bmN0aW9uKGFnZSkge1xuICogICAgICAgb25zLm5vdGlmaWNhdGlvbi5hbGVydCgnWW91IGFyZSAnICsgYWdlICsgJyB5ZWFycyBvbGQuJyk7XG4gKiAgICAgfVxuICogICApO1xuICovXG5jb25zdCBub3RpZmljYXRpb24gPSB7fTtcblxubm90aWZpY2F0aW9uLl9jcmVhdGVBbGVydERpYWxvZyA9ICguLi5wYXJhbXMpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICBjb25zdCBvcHRpb25zID0gX25vcm1hbGl6ZUFyZ3VtZW50cyguLi5wYXJhbXMpO1xuICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnQWxlcnREaWFsb2cnLCAnQWxlcnREaWFsb2dCdXR0b24nKTtcblxuICAvLyBQcm9tcHQgaW5wdXQgc3RyaW5nXG4gIGxldCBpbnB1dFN0cmluZyA9ICcnO1xuICBpZiAob3B0aW9ucy5pc1Byb21wdCkge1xuICAgIGlucHV0U3RyaW5nID0gYFxuICAgICAgPGlucHV0XG4gICAgICAgIGNsYXNzPVwidGV4dC1pbnB1dCB0ZXh0LWlucHV0LS11bmRlcmJhclwiXG4gICAgICAgIHR5cGU9XCIke29wdGlvbnMuaW5wdXRUeXBlIHx8ICd0ZXh0J31cIlxuICAgICAgICBwbGFjZWhvbGRlcj1cIiR7b3B0aW9ucy5wbGFjZWhvbGRlciB8fCAnJ31cIlxuICAgICAgICB2YWx1ZT1cIiR7b3B0aW9ucy5kZWZhdWx0VmFsdWUgfHwgJyd9XCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgbWFyZ2luLXRvcDogMTBweDtcIlxuICAgICAgLz5cbiAgICBgO1xuICB9XG5cbiAgLy8gQnV0dG9ucyBzdHJpbmdcbiAgbGV0IGJ1dHRvbnMgPSAnJztcbiAgb3B0aW9ucy5idXR0b25MYWJlbHMuZm9yRWFjaCgobGFiZWwsIGluZGV4KSA9PiB7XG4gICAgYnV0dG9ucyArPSBgXG4gICAgICA8b25zLWFsZXJ0LWRpYWxvZy1idXR0b25cbiAgICAgICAgY2xhc3M9XCJcbiAgICAgICAgICAke2luZGV4ID09PSBvcHRpb25zLnByaW1hcnlCdXR0b25JbmRleCA/ICcgYWxlcnQtZGlhbG9nLWJ1dHRvbi0tcHJpbWFsJyA6ICcnfVxuICAgICAgICAgICR7b3B0aW9ucy5idXR0b25MYWJlbHMubGVuZ3RoIDw9IDIgPyAnIGFsZXJ0LWRpYWxvZy1idXR0b24tLXJvd2Zvb3RlcicgOiAnJ31cbiAgICAgICAgXCJcbiAgICAgICAgc3R5bGU9XCJwb3NpdGlvbjogcmVsYXRpdmU7XCI+XG4gICAgICAgICR7bGFiZWx9XG4gICAgICA8L29ucy1hbGVydC1kaWFsb2ctYnV0dG9uPlxuICAgIGA7XG4gIH0pO1xuXG4gIC8vIERpYWxvZyBFbGVtZW50XG4gIGxldCBlbCA9IHt9O1xuICBjb25zdCBfZGVzdHJveURpYWxvZyA9ICgpID0+IHtcbiAgICBpZiAoZWwuZGlhbG9nLm9uRGlhbG9nQ2FuY2VsKSB7XG4gICAgICBlbC5kaWFsb2cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGlhbG9nLWNhbmNlbCcsIGVsLmRpYWxvZy5vbkRpYWxvZ0NhbmNlbCk7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoZWwpLmZvckVhY2goa2V5ID0+IGRlbGV0ZSBlbFtrZXldKTtcbiAgICBlbCA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy5kZXN0cm95IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIG9wdGlvbnMuZGVzdHJveSgpO1xuICAgIH1cbiAgfTtcblxuICBlbC5kaWFsb2cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvbnMtYWxlcnQtZGlhbG9nJyk7XG4gIGVsLmRpYWxvZy5pbm5lckhUTUwgPSBgXG4gICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy1tYXNrXCJcbiAgICAgIHN0eWxlPVwiXG4gICAgICAgICR7b3B0aW9ucy5tYXNrQ29sb3IgPyAnYmFja2dyb3VuZC1jb2xvcjogJyArIG9wdGlvbnMubWFza0NvbG9yIDogJyd9XG4gICAgICBcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWNvbnRhaW5lclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLXRpdGxlXCI+XG4gICAgICAgICAgJHtvcHRpb25zLnRpdGxlIHx8ICcnfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy1jb250ZW50XCI+XG4gICAgICAgICAgJHtvcHRpb25zLm1lc3NhZ2UgfHwgb3B0aW9ucy5tZXNzYWdlSFRNTH1cbiAgICAgICAgICAke2lucHV0U3RyaW5nfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIlxuICAgICAgICAgIGFsZXJ0LWRpYWxvZy1mb290ZXJcbiAgICAgICAgICAke29wdGlvbnMuYnV0dG9uTGFiZWxzLmxlbmd0aCA8PSAyID8gJyBhbGVydC1kaWFsb2ctZm9vdGVyLS1yb3dmb290ZXInIDogJyd9XG4gICAgICAgIFwiPlxuICAgICAgICAgICR7YnV0dG9uc31cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYDtcbiAgY29udGVudFJlYWR5KGVsLmRpYWxvZyk7XG5cbiAgLy8gU2V0IGF0dHJpYnV0ZXNcbiAgX3NldEF0dHJpYnV0ZXMoZWwuZGlhbG9nLCBvcHRpb25zKTtcblxuICAvLyBQcm9tcHQgZXZlbnRzXG4gIGlmIChvcHRpb25zLmlzUHJvbXB0ICYmIG9wdGlvbnMuc3VibWl0T25FbnRlcikge1xuICAgIGVsLmlucHV0ID0gZWwuZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoJy50ZXh0LWlucHV0Jyk7XG4gICAgZWwuaW5wdXQub25rZXlwcmVzcyA9IGV2ZW50ID0+IHtcbiAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMykge1xuICAgICAgICBlbC5kaWFsb2cuaGlkZSgpXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVWYWx1ZSA9IGVsLmlucHV0LnZhbHVlO1xuICAgICAgICAgICAgICBfZGVzdHJveURpYWxvZygpO1xuICAgICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHJlc29sdmVWYWx1ZSk7XG4gICAgICAgICAgICAgIHJlc29sdmUocmVzb2x2ZVZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gQnV0dG9uIGV2ZW50c1xuICBlbC5mb290ZXIgPSBlbC5kaWFsb2cucXVlcnlTZWxlY3RvcignLmFsZXJ0LWRpYWxvZy1mb290ZXInKTtcbiAgdXRpbC5hcnJheUZyb20oZWwuZGlhbG9nLnF1ZXJ5U2VsZWN0b3JBbGwoJy5hbGVydC1kaWFsb2ctYnV0dG9uJykpLmZvckVhY2goKGJ1dHRvbkVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgYnV0dG9uRWxlbWVudC5vbmNsaWNrID0gKCkgPT4ge1xuICAgICAgICBlbC5kaWFsb2cuaGlkZSgpXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgIGxldCByZXNvbHZlVmFsdWUgPSBpbmRleDtcbiAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuaXNQcm9tcHQpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlVmFsdWUgPSBpbmRleCA9PT0gb3B0aW9ucy5wcmltYXJ5QnV0dG9uSW5kZXggPyBlbC5pbnB1dC52YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWwuZGlhbG9nLnJlbW92ZSgpO1xuICAgICAgICAgICAgICBfZGVzdHJveURpYWxvZygpO1xuICAgICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHJlc29sdmVWYWx1ZSk7XG4gICAgICAgICAgICAgIHJlc29sdmUocmVzb2x2ZVZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgZWwuZm9vdGVyLmFwcGVuZENoaWxkKGJ1dHRvbkVsZW1lbnQpO1xuICB9KTtcblxuICAvLyBDYW5jZWwgZXZlbnRzXG4gIGlmIChvcHRpb25zLmNhbmNlbGFibGUpIHtcbiAgICBlbC5kaWFsb2cuY2FuY2VsYWJsZSA9IHRydWU7XG4gICAgZWwuZGlhbG9nLm9uRGlhbG9nQ2FuY2VsID0gKCkgPT4ge1xuICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHtcbiAgICAgICAgZWwuZGlhbG9nLnJlbW92ZSgpO1xuICAgICAgICBfZGVzdHJveURpYWxvZygpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCByZXNvbHZlVmFsdWUgPSBvcHRpb25zLmlzUHJvbXB0ID8gbnVsbCA6IC0xO1xuICAgICAgb3B0aW9ucy5jYWxsYmFjayhyZXNvbHZlVmFsdWUpO1xuICAgICAgcmVzb2x2ZShyZXNvbHZlVmFsdWUpO1xuICAgIH07XG4gICAgZWwuZGlhbG9nLmFkZEV2ZW50TGlzdGVuZXIoJ2RpYWxvZy1jYW5jZWwnLCBlbC5kaWFsb2cub25EaWFsb2dDYW5jZWwsIGZhbHNlKTtcbiAgfVxuXG4gIC8vIFNob3cgZGlhbG9nXG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZWwuZGlhbG9nKTtcbiAgb3B0aW9ucy5jb21waWxlKGVsLmRpYWxvZyk7XG4gIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgZWwuZGlhbG9nLnNob3coKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAoZWwuaW5wdXQgJiYgb3B0aW9ucy5pc1Byb21wdCAmJiBvcHRpb25zLmF1dG9mb2N1cykge1xuICAgICAgICAgIGNvbnN0IHN0ckxlbmd0aCA9IGVsLmlucHV0LnZhbHVlLmxlbmd0aDtcbiAgICAgICAgICBlbC5pbnB1dC5mb2N1cygpO1xuICAgICAgICAgIGVsLmlucHV0LnNldFNlbGVjdGlvblJhbmdlKHN0ckxlbmd0aCwgc3RyTGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH0pO1xufSk7XG5cbi8qKlxuICogQG1ldGhvZCBhbGVydFxuICogQHNpZ25hdHVyZSBhbGVydChtZXNzYWdlIFssIG9wdGlvbnNdIHwgb3B0aW9ucylcbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiAgIFtlbl1XaWxsIHJlc29sdmUgdG8gdGhlIGluZGV4IG9mIHRoZSBidXR0b24gdGhhdCB3YXMgcHJlc3NlZCBvciBgLTFgIHdoZW4gY2FuY2VsZWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICogICBbZW5dTm90aWZpY2F0aW9uIG1lc3NhZ2UuIFRoaXMgYXJndW1lbnQgaXMgb3B0aW9uYWwgYnV0IGlmIGl0J3Mgbm90IGRlZmluZWQgZWl0aGVyIGBvcHRpb25zLm1lc3NhZ2VgIG9yIGBvcHRpb25zLm1lc3NhZ2VIVE1MYCBtdXN0IGJlIGRlZmluZWQgaW5zdGVhZC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLm1lc3NhZ2VdXG4gKiAgIFtlbl1Ob3RpZmljYXRpb24gbWVzc2FnZS5bL2VuXVxuICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gr6KGo56S644GZ44KL5paH5a2X5YiX44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tZXNzYWdlSFRNTF1cbiAqICAgW2VuXU5vdGlmaWNhdGlvbiBtZXNzYWdlIGluIEhUTUwuWy9lbl1cbiAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBq+ihqOekuuOBmeOCi0hUTUzjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmcgfCBBcnJheX0gW29wdGlvbnMuYnV0dG9uTGFiZWxzXVxuICogICBbZW5dTGFiZWxzIGZvciB0aGUgYnV0dG9ucy4gRGVmYXVsdCBpcyBgXCJPS1wiYC5bL2VuXVxuICogICBbamFd56K66KqN44Oc44K/44Oz44Gu44Op44OZ44Or44KS5oyH5a6a44GX44G+44GZ44CCXCJPS1wi44GM44OH44OV44Kp44Or44OI44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5wcmltYXJ5QnV0dG9uSW5kZXhdXG4gKiAgIFtlbl1JbmRleCBvZiBwcmltYXJ5IGJ1dHRvbi4gRGVmYXVsdCBpcyB0aGUgbGFzdCBvbmUuWy9lbl1cbiAqICAgW2phXeODl+ODqeOCpOODnuODquODnOOCv+ODs+OBruOCpOODs+ODh+ODg+OCr+OCueOCkuaMh+WumuOBl+OBvuOBmeOAguODh+ODleOCqeODq+ODiOOBryAwIOOBp+OBmeOAglsvamFdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmNhbmNlbGFibGVdXG4gKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgY2FuY2VsYWJsZSBvciBub3QuIERlZmF1bHQgaXMgYGZhbHNlYC4gSWYgdGhlIGRpYWxvZyBpcyBjYW5jZWxhYmxlIGl0IGNhbiBiZSBjbG9zZWQgYnkgY2xpY2tpbmcgdGhlIGJhY2tncm91bmQgb3IgcHJlc3NpbmcgdGhlIEFuZHJvaWQgYmFjayBidXR0b24uWy9lbl1cbiAqICAgW2phXeODgOOCpOOCouODreOCsOOBjOOCreODo+ODs+OCu+ODq+WPr+iDveOBi+OBqeOBhuOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgbm9uZWAgYW5kIGBmYWRlYC4gRGVmYXVsdCBpcyBgZmFkZWAuWy9lbl1cbiAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOCkuihqOekuuOBmeOCi+mam+OBruOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcImZhZGVcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuaWRdXG4gKiAgIFtlbl1UaGUgYDxvbnMtYWxlcnQtZGlhbG9nPmAgZWxlbWVudCdzIElELlsvZW5dXG4gKiAgIFtqYV1vbnMtYWxlcnQtZGlhbG9n6KaB57Sg44GuSUTjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmNsYXNzXVxuICogICBbZW5dVGhlIGA8b25zLWFsZXJ0LWRpYWxvZz5gIGVsZW1lbnQncyBjbGFzcy5bL2VuXVxuICogICBbamFdb25zLWFsZXJ0LWRpYWxvZ+imgee0oOOBrmNsYXNz44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy50aXRsZV1cbiAqICAgW2VuXURpYWxvZyB0aXRsZS4gRGVmYXVsdCBpcyBgXCJBbGVydFwiYC5bL2VuXVxuICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gu5LiK6YOo44Gr6KGo56S644GZ44KL44K/44Kk44OI44Or44KS5oyH5a6a44GX44G+44GZ44CCXCJBbGVydFwi44GM44OH44OV44Kp44Or44OI44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tb2RpZmllcl1cbiAqICAgW2VuXU1vZGlmaWVyIGZvciB0aGUgZGlhbG9nLlsvZW5dXG4gKiAgIFtqYV3jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjga5tb2RpZmllcuWxnuaAp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMubWFza0NvbG9yXVxuICogICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBcInJnYmEoMCwgMCwgMCwgMC4yKVwiIChcInJnYmEoMCwgMCwgMCwgMC4zKVwiIGZvciBNYXRlcmlhbCkuWy9lbl1cbiAqICAgW2phXeiDjOaZr+OBruODnuOCueOCr+OBruiJsuOCkuaMh+WumuOBl+OBvuOBmeOAglwicmdiYSgwLCAwLCAwLCAwLjIpXCLjgYzjg4fjg5Xjgqnjg6vjg4jlgKTjgafjgZnjgIJbL2phXVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGV4ZWN1dGVzIGFmdGVyIGRpYWxvZyBoYXMgYmVlbiBjbG9zZWQuWy9lbl1cbiAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBjOmWieOBmOOCieOCjOOBn+aZguOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpc3BsYXkgYW4gYWxlcnQgZGlhbG9nIHRvIHNob3cgdGhlIHVzZXIgYSBtZXNzYWdlLlxuICpcbiAqICAgICBUaGUgY29udGVudCBvZiB0aGUgbWVzc2FnZSBjYW4gYmUgZWl0aGVyIHNpbXBsZSB0ZXh0IG9yIEhUTUwuXG4gKlxuICogICAgIEl0IGNhbiBiZSBjYWxsZWQgaW4gdGhlIGZvbGxvd2luZyB3YXlzOlxuICpcbiAqICAgICBgYGBcbiAqICAgICBvbnMubm90aWZpY2F0aW9uLmFsZXJ0KG1lc3NhZ2UsIG9wdGlvbnMpO1xuICogICAgIG9ucy5ub3RpZmljYXRpb24uYWxlcnQob3B0aW9ucyk7XG4gKiAgICAgYGBgXG4gKlxuICogICAgIE11c3Qgc3BlY2lmeSBlaXRoZXIgYG1lc3NhZ2VgIG9yIGBtZXNzYWdlSFRNTGAuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICDjg6bjg7zjgrbjg7zjgbjjg6Hjg4Pjgrvjg7zjgrjjgpLopovjgZvjgovjgZ/jgoHjga7jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjgpLooajnpLrjgZfjgb7jgZnjgIJcbiAqICAgICDooajnpLrjgZnjgovjg6Hjg4Pjgrvjg7zjgrjjga/jgIHjg4bjgq3jgrnjg4jjgYvjgoLjgZfjgY/jga9IVE1M44KS5oyH5a6a44Gn44GN44G+44GZ44CCXG4gKiAgICAg44GT44Gu44Oh44K944OD44OJ44Gu5byV5pWw44Gr44Gv44CBb3B0aW9ucy5tZXNzYWdl44KC44GX44GP44Gvb3B0aW9ucy5tZXNzYWdlSFRNTOOBruOBqeOBoeOCieOBi+OCkuW/heOBmuaMh+WumuOBmeOCi+W/heimgeOBjOOBguOCiuOBvuOBmeOAglxuICogICBbL2phXVxuICovXG5ub3RpZmljYXRpb24uYWxlcnQgPSAobWVzc2FnZSwgb3B0aW9ucykgPT5cbiAgbm90aWZpY2F0aW9uLl9jcmVhdGVBbGVydERpYWxvZyhtZXNzYWdlLCBvcHRpb25zLCB7XG4gICAgYnV0dG9uTGFiZWxzOiBbJ09LJ10sXG4gICAgdGl0bGU6ICdBbGVydCdcbiAgfSk7XG5cbi8qKlxuICogQG1ldGhvZCBjb25maXJtXG4gKiBAc2lnbmF0dXJlIGNvbmZpcm0obWVzc2FnZSBbLCBvcHRpb25zXSB8IG9wdGlvbnMpXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dV2lsbCByZXNvbHZlIHRvIHRoZSBpbmRleCBvZiB0aGUgYnV0dG9uIHRoYXQgd2FzIHByZXNzZWQgb3IgYC0xYCB3aGVuIGNhbmNlbGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAqICAgW2VuXU5vdGlmaWNhdGlvbiBtZXNzYWdlLiBUaGlzIGFyZ3VtZW50IGlzIG9wdGlvbmFsIGJ1dCBpZiBpdCdzIG5vdCBkZWZpbmVkIGVpdGhlciBgb3B0aW9ucy5tZXNzYWdlYCBvciBgb3B0aW9ucy5tZXNzYWdlSFRNTGAgbXVzdCBiZSBkZWZpbmVkIGluc3RlYWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogQHBhcmFtIHtBcnJheX0gW29wdGlvbnMuYnV0dG9uTGFiZWxzXVxuICogICBbZW5dTGFiZWxzIGZvciB0aGUgYnV0dG9ucy4gRGVmYXVsdCBpcyBgW1wiQ2FuY2VsXCIsIFwiT0tcIl1gLlsvZW5dXG4gKiAgIFtqYV3jg5zjgr/jg7Pjga7jg6njg5njg6vjga7phY3liJfjgpLmjIflrprjgZfjgb7jgZnjgIJbXCJDYW5jZWxcIiwgXCJPS1wiXeOBjOODh+ODleOCqeODq+ODiOOBp+OBmeOAglsvamFdXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMucHJpbWFyeUJ1dHRvbkluZGV4XVxuICogICBbZW5dSW5kZXggb2YgcHJpbWFyeSBidXR0b24uIERlZmF1bHQgaXMgdGhlIGxhc3Qgb25lLlsvZW5dXG4gKiAgIFtqYV3jg5fjg6njgqTjg57jg6rjg5zjgr/jg7Pjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLmjIflrprjgZfjgb7jgZnjgILjg4fjg5Xjgqnjg6vjg4jjga8gMSDjgafjgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBEaXNwbGF5IGEgZGlhbG9nIHRvIGFzayB0aGUgdXNlciBmb3IgY29uZmlybWF0aW9uLiBFeHRlbmRzIGBhbGVydCgpYCBwYXJhbWV0ZXJzLlxuICogICAgIFRoZSBkZWZhdWx0IGJ1dHRvbiBsYWJlbHMgYXJlIGBcIkNhbmNlbFwiYCBhbmQgYFwiT0tcImAgYnV0IHRoZXkgY2FuIGJlIGN1c3RvbWl6ZWQuXG4gKlxuICogICAgIEl0IGNhbiBiZSBjYWxsZWQgaW4gdGhlIGZvbGxvd2luZyB3YXlzOlxuICpcbiAqICAgICBgYGBcbiAqICAgICBvbnMubm90aWZpY2F0aW9uLmNvbmZpcm0obWVzc2FnZSwgb3B0aW9ucyk7XG4gKiAgICAgb25zLm5vdGlmaWNhdGlvbi5jb25maXJtKG9wdGlvbnMpO1xuICogICAgIGBgYFxuICpcbiAqICAgICBNdXN0IHNwZWNpZnkgZWl0aGVyIGBtZXNzYWdlYCBvciBgbWVzc2FnZUhUTUxgLlxuICogICBbL2VuXVxuICogICBbamFdXG4gKiAgICAg44Om44O844K244Gr56K66KqN44KS5L+D44GZ44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GX44G+44GZ44CCXG4gKiAgICAg44OH44Kq44Or44Go44Gu44Oc44K/44Oz44Op44OZ44Or44Gv44CBXCJDYW5jZWxcIuOBqFwiT0tcIuOBp+OBmeOBjOOAgeOBk+OCjOOBr+OBk+OBruODoeOCveODg+ODieOBruW8leaVsOOBp+OCq+OCueOCv+ODnuOCpOOCuuOBp+OBjeOBvuOBmeOAglxuICogICAgIOOBk+OBruODoeOCveODg+ODieOBruW8leaVsOOBq+OBr+OAgW9wdGlvbnMubWVzc2FnZeOCguOBl+OBj+OBr29wdGlvbnMubWVzc2FnZUhUTUzjga7jganjgaHjgonjgYvjgpLlv4XjgZrmjIflrprjgZnjgovlv4XopoHjgYzjgYLjgorjgb7jgZnjgIJcbiAqICAgWy9qYV1cbiAqL1xubm90aWZpY2F0aW9uLmNvbmZpcm0gPSAobWVzc2FnZSwgb3B0aW9ucykgPT5cbiAgbm90aWZpY2F0aW9uLl9jcmVhdGVBbGVydERpYWxvZyhtZXNzYWdlLCBvcHRpb25zLCB7XG4gICAgYnV0dG9uTGFiZWxzOiBbJ0NhbmNlbCcsICdPSyddLFxuICAgIHRpdGxlOiAnQ29uZmlybSdcbiAgfSk7XG5cbi8qKlxuICogQG1ldGhvZCBwcm9tcHRcbiAqIEBzaWduYXR1cmUgcHJvbXB0KG1lc3NhZ2UgWywgb3B0aW9uc10gfCBvcHRpb25zKVxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAqICAgW2VuXU5vdGlmaWNhdGlvbiBtZXNzYWdlLiBUaGlzIGFyZ3VtZW50IGlzIG9wdGlvbmFsIGJ1dCBpZiBpdCdzIG5vdCBkZWZpbmVkIGVpdGhlciBgb3B0aW9ucy5tZXNzYWdlYCBvciBgb3B0aW9ucy5tZXNzYWdlSFRNTGAgbXVzdCBiZSBkZWZpbmVkIGluc3RlYWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dV2lsbCByZXNvbHZlIHRvIHRoZSBpbnB1dCB2YWx1ZSB3aGVuIHRoZSBkaWFsb2cgaXMgY2xvc2VkIG9yIGBudWxsYCB3aGVuIGNhbmNlbGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZyB8IEFycmF5fSBbb3B0aW9ucy5idXR0b25MYWJlbHNdXG4gKiAgIFtlbl1MYWJlbHMgZm9yIHRoZSBidXR0b25zLiBEZWZhdWx0IGlzIGBcIk9LXCJgLlsvZW5dXG4gKiAgIFtqYV3norroqo3jg5zjgr/jg7Pjga7jg6njg5njg6vjgpLmjIflrprjgZfjgb7jgZnjgIJcIk9LXCLjgYzjg4fjg5Xjgqnjg6vjg4jjgafjgZnjgIJbL2phXVxuICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRpb25zLnByaW1hcnlCdXR0b25JbmRleF1cbiAqICAgW2VuXUluZGV4IG9mIHByaW1hcnkgYnV0dG9uLiBEZWZhdWx0IGlzIHRoZSBsYXN0IG9uZS5bL2VuXVxuICogICBbamFd44OX44Op44Kk44Oe44Oq44Oc44K/44Oz44Gu44Kk44Oz44OH44OD44Kv44K544KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvIDAg44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5wbGFjZWhvbGRlcl1cbiAqICAgW2VuXVBsYWNlaG9sZGVyIGZvciB0aGUgdGV4dCBpbnB1dC5bL2VuXVxuICogICBbamFd44OG44Kt44K544OI5qyE44Gu44OX44Os44O844K544Ob44Or44OA44Gr6KGo56S644GZ44KL44OG44Kt44K544OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5kZWZhdWx0VmFsdWVdXG4gKiAgIFtlbl1EZWZhdWx0IHZhbHVlIGZvciB0aGUgdGV4dCBpbnB1dC5bL2VuXVxuICogICBbamFd44OG44Kt44K544OI5qyE44Gu44OH44OV44Kp44Or44OI44Gu5YCk44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5pbnB1dFR5cGVdXG4gKiAgIFtlbl1UeXBlIG9mIHRoZSBpbnB1dCBlbGVtZW50IChgcGFzc3dvcmRgLCBgZGF0ZWAuLi4pLiBEZWZhdWx0IGlzIGB0ZXh0YC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuYXV0b2ZvY3VzXVxuICogICBbZW5dQXV0b2ZvY3VzIHRoZSBpbnB1dCBlbGVtZW50LiBEZWZhdWx0IGlzIGB0cnVlYC4gSW4gQ29yZG92YSwgYEtleWJvYXJkRGlzcGxheVJlcXVpcmVzVXNlckFjdGlvbmAgaW4gYGNvbmZpZy54bWxgIG11c3QgYmUgYGZhbHNlYCB0byBhY3RpdmF0ZSB0aGlzIGZlYXR1cmUuWy9lbl1cbiAqICAgW2phXWlucHV06KaB57Sg44Gr6Ieq5YuV55qE44Gr44OV44Kp44O844Kr44K544GZ44KL44GL44Gp44GG44GL44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvdHJ1ZeOBp+OBmeOAgkNvcmRvdmHnkrDlooPjgafjga/jgIHjgZPjga7mqZ/og73jgpLmnInlirnjgavjgZnjgovjgZ/jgoHjgavjga8gYGNvbmZpZy54bWxgIOOBpyBgS2V5Ym9hcmREaXNwbGF5UmVxdWlyZXNVc2VyQWN0aW9uYCDjgpIgYGZhbHNlYCDjgavoqK3lrprjgZnjgovlv4XopoHjgYzjgYLjgorjgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zdWJtaXRPbkVudGVyXVxuICogICBbZW5dU3VibWl0IGF1dG9tYXRpY2FsbHkgd2hlbiBlbnRlciBpcyBwcmVzc2VkLiBEZWZhdWx0IGlzIGB0cnVlYC5bL2VuXVxuICogICBbamFdRW50ZXLjgYzmirzjgZXjgozjgZ/pmpvjgavjgZ3jga5mb3Jt44KSc3VibWl044GZ44KL44GL44Gp44GG44GL44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvdHJ1ZeOBp+OBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpc3BsYXkgYSBkaWFsb2cgd2l0aCBhIHByb21wdCB0byBhc2sgdGhlIHVzZXIgYSBxdWVzdGlvbi4gRXh0ZW5kcyBgYWxlcnQoKWAgcGFyYW1ldGVycy5cbiAqXG4gKiAgICAgSXQgY2FuIGJlIGNhbGxlZCBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKlxuICogICAgIGBgYFxuICogICAgIG9ucy5ub3RpZmljYXRpb24ucHJvbXB0KG1lc3NhZ2UsIG9wdGlvbnMpO1xuICogICAgIG9ucy5ub3RpZmljYXRpb24ucHJvbXB0KG9wdGlvbnMpO1xuICogICAgIGBgYFxuICpcbiAqICAgICBNdXN0IHNwZWNpZnkgZWl0aGVyIGBtZXNzYWdlYCBvciBgbWVzc2FnZUhUTUxgLlxuICogICBbL2VuXVxuICogICBbamFdXG4gKiAgICAg44Om44O844K244O844Gr5YWl5Yqb44KS5L+D44GZ44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GX44G+44GZ44CCXG4gKiAgICAg44GT44Gu44Oh44K944OD44OJ44Gu5byV5pWw44Gr44Gv44CBb3B0aW9ucy5tZXNzYWdl44KC44GX44GP44Gvb3B0aW9ucy5tZXNzYWdlSFRNTOOBruOBqeOBoeOCieOBi+OCkuW/heOBmuaMh+WumuOBmeOCi+W/heimgeOBjOOBguOCiuOBvuOBmeOAglxuICogICBbL2phXVxuICovXG5ub3RpZmljYXRpb24ucHJvbXB0ID0gKG1lc3NhZ2UsIG9wdGlvbnMpID0+XG4gIG5vdGlmaWNhdGlvbi5fY3JlYXRlQWxlcnREaWFsb2cobWVzc2FnZSwgb3B0aW9ucywge1xuICAgIGJ1dHRvbkxhYmVsczogWydPSyddLFxuICAgIHRpdGxlOiAnQWxlcnQnLFxuICAgIGlzUHJvbXB0OiB0cnVlLFxuICAgIGF1dG9mb2N1czogdHJ1ZSxcbiAgICBzdWJtaXRPbkVudGVyOiB0cnVlXG4gIH0pO1xuXG4vKipcbiAqIEBtZXRob2QgdG9hc3RcbiAqIEBzaWduYXR1cmUgdG9hc3QobWVzc2FnZSBbLCBvcHRpb25zXSB8IG9wdGlvbnMpXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dV2lsbCByZXNvbHZlIHdoZW4gdGhlIHRvYXN0IGlzIGhpZGRlbi5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiAgIFtlbl1Ub2FzdCBtZXNzYWdlLiBUaGlzIGFyZ3VtZW50IGlzIG9wdGlvbmFsIGJ1dCBpZiBpdCdzIG5vdCBkZWZpbmVkIHRoZW4gYG9wdGlvbnMubWVzc2FnZWAgbXVzdCBiZSBkZWZpbmVkIGluc3RlYWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tZXNzYWdlXVxuICogICBbZW5dTm90aWZpY2F0aW9uIG1lc3NhZ2UuWy9lbl1cbiAqICAgW2phXeODiOODvOOCueODiOOBq+ihqOekuuOBmeOCi+aWh+Wtl+WIl+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYnV0dG9uTGFiZWxdXG4gKiAgIFtlbl1MYWJlbCBmb3IgdGhlIGJ1dHRvbi5bL2VuXVxuICogICBbamFd56K66KqN44Oc44K/44Oz44Gu44Op44OZ44Or44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBub25lYCwgYGZhZGVgLCBgYXNjZW5kYCwgYGxpZnRgIGFuZCBgZmFsbGAuIERlZmF1bHQgaXMgYGFzY2VuZGAgZm9yIEFuZHJvaWQgYW5kIGBsaWZ0YCBmb3IgaU9TLlsvZW5dXG4gKiAgIFtqYV3jg4jjg7zjgrnjg4jjgpLooajnpLrjgZnjgovpmpvjga7jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJmYWRlXCIsIFwiYXNjZW5kXCIsIFwibGlmdFwiLCBcImZhbGxcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMudGltZW91dF1cbiAqICAgW2VuXU51bWJlciBvZiBtaWxpc2Vjb25kcyB3aGVyZSB0aGUgdG9hc3QgaXMgdmlzaWJsZSBiZWZvcmUgaGlkaW5nIGF1dG9tYXRpY2FsbHkuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLmZvcmNlXVxuICogICBbZW5dSWYgYHRydWVgLCB0aGUgdG9hc3Qgc2tpcHMgdGhlIG5vdGlmaWNhdGlvbiBxdWV1ZSBhbmQgaXMgc2hvd24gaW1tZWRpYXRlbHkuIERlZmF1bHRzIHRvIGBmYWxzZWAuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuaWRdXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9hc3Q+YCBlbGVtZW50J3MgSUQuWy9lbl1cbiAqICAgW2phXW9ucy10b2FzdOimgee0oOOBrklE44CCWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5jbGFzc11cbiAqICAgW2VuXVRoZSBgPG9ucy10b2FzdD5gIGVsZW1lbnQncyBjbGFzcy5bL2VuXVxuICogICBbamFdb25zLXRvYXN06KaB57Sg44GuY2xhc3PjgIJbL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLm1vZGlmaWVyXVxuICogICBbZW5dTW9kaWZpZXIgZm9yIHRoZSBlbGVtZW50LlsvZW5dXG4gKiAgIFtqYV3jg4jjg7zjgrnjg4jjga5tb2RpZmllcuWxnuaAp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAqICAgW2VuXUZ1bmN0aW9uIHRoYXQgZXhlY3V0ZXMgYWZ0ZXIgdG9hc3QgaGFzIGJlZW4gaGlkZGVuLlsvZW5dXG4gKiAgIFtqYV3jg4jjg7zjgrnjg4jjgYzplonjgZjjgonjgozjgZ/mmYLjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBEaXNwbGF5IGEgc2ltcGxlIG5vdGlmaWNhdGlvbiB0b2FzdCB3aXRoIGFuIG9wdGlvbmFsIGJ1dHRvbiB0aGF0IGNhbiBiZSB1c2VkIGZvciBzaW1wbGUgYWN0aW9ucy5cbiAqXG4gKiAgICAgSXQgY2FuIGJlIGNhbGxlZCBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKlxuICogICAgIGBgYFxuICogICAgIG9ucy5ub3RpZmljYXRpb24udG9hc3QobWVzc2FnZSwgb3B0aW9ucyk7XG4gKiAgICAgb25zLm5vdGlmaWNhdGlvbi50b2FzdChvcHRpb25zKTtcbiAqICAgICBgYGBcbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKi9cbm5vdGlmaWNhdGlvbi50b2FzdCA9IChtZXNzYWdlLCBvcHRpb25zKSA9PiB7XG4gIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnVG9hc3QnKTsgLy8gVGhyb3dzIGVycm9yLCBtdXN0IGJlIGluc2lkZSBwcm9taXNlXG5cbiAgICBvcHRpb25zID0gX25vcm1hbGl6ZUFyZ3VtZW50cyhtZXNzYWdlLCBvcHRpb25zLCB7XG4gICAgICB0aW1lb3V0OiAwLFxuICAgICAgZm9yY2U6IGZhbHNlXG4gICAgfSk7XG5cbiAgICBsZXQgdG9hc3QgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoYFxuICAgICAgPG9ucy10b2FzdD5cbiAgICAgICAgJHtvcHRpb25zLm1lc3NhZ2V9XG4gICAgICAgICR7b3B0aW9ucy5idXR0b25MYWJlbHMgPyBgPGJ1dHRvbj4ke29wdGlvbnMuYnV0dG9uTGFiZWxzWzBdfTwvYnV0dG9uPmAgOiAnJ31cbiAgICAgIDwvb25zLXRvYXN0PlxuICAgIGApO1xuXG4gICAgX3NldEF0dHJpYnV0ZXModG9hc3QsIG9wdGlvbnMpO1xuXG4gICAgY29uc3QgZmluaXNoID0gdmFsdWUgPT4ge1xuICAgICAgaWYgKHRvYXN0KSB7XG4gICAgICAgIHRvYXN0XG4gICAgICAgIC5oaWRlKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGlmICh0b2FzdCkge1xuICAgICAgICAgICAgdG9hc3QucmVtb3ZlKCk7XG4gICAgICAgICAgICB0b2FzdCA9IG51bGw7XG4gICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHZhbHVlKTtcbiAgICAgICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zLmJ1dHRvbkxhYmVscykge1xuICAgICAgdXRpbC5maW5kQ2hpbGQodG9hc3QuX3RvYXN0LCAnYnV0dG9uJykub25jbGljayA9ICgpID0+IGZpbmlzaCgwKTtcbiAgICB9XG5cbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRvYXN0KTtcbiAgICBvcHRpb25zLmNvbXBpbGUodG9hc3QpO1xuXG4gICAgY29uc3Qgc2hvdyA9ICgpID0+IHtcbiAgICAgIHRvYXN0LnBhcmVudEVsZW1lbnQgJiYgdG9hc3Quc2hvdyhvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKG9wdGlvbnMudGltZW91dCkge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gZmluaXNoKC0xKSwgb3B0aW9ucy50aW1lb3V0KVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgc2V0SW1tZWRpYXRlKCgpID0+IG9wdGlvbnMuZm9yY2UgPyBzaG93KCkgOiBUb2FzdFF1ZXVlLmFkZChzaG93LCBwcm9taXNlKSlcbiAgfSk7XG5cbiAgcmV0dXJuIHByb21pc2U7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBub3RpZmljYXRpb247XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuL3V0aWwnO1xuXG4vLyBWYWxpZGF0ZSBwYXJhbWV0ZXJzXG5jb25zdCBjaGVja09wdGlvbnMgPSBvcHRpb25zID0+IHtcbiAgY29uc3QgZXJyID0gKHByb3AsIHR5cGUgPSAnRnVuY3Rpb24nKSA9PiB1dGlsLnRocm93KGBcIm9wdGlvbnMuJHtwcm9wfVwiIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgJHt0eXBlfWApO1xuICBjb25zdCBoYXNPd25Qcm9wZXJ0eSA9IHByb3AgPT4gT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgcHJvcCk7XG4gIGNvbnN0IGluc3RhbmNlT2YgPSAocHJvcCwgdHlwZSA9IEZ1bmN0aW9uKSA9PiBvcHRpb25zW3Byb3BdIGluc3RhbmNlb2YgdHlwZTtcblxuICBjb25zdCBiID0gJ2J1dHRvbnMnLCBjYiA9ICdjYWxsYmFjaycsIGMgPSAnY29tcGlsZScsIGQgPSAnZGVzdHJveSc7XG4gICghaGFzT3duUHJvcGVydHkoYikgfHwgIWluc3RhbmNlT2YoYiwgQXJyYXkpKSAmJiBlcnIoYiwgJ0FycmF5Jyk7XG4gIChoYXNPd25Qcm9wZXJ0eShjYikgJiYgIWluc3RhbmNlT2YoY2IpKSAmJiBlcnIoY2IpO1xuICAoaGFzT3duUHJvcGVydHkoYykgJiYgIWluc3RhbmNlT2YoYykpICYmIGVycihjKTtcbiAgKGhhc093blByb3BlcnR5KGQpICYmICFpbnN0YW5jZU9mKGQpKSAmJiBlcnIoZCk7XG59O1xuXG4vLyBBY3Rpb24gU2hlZXRcbmV4cG9ydCBkZWZhdWx0IChvcHRpb25zID0ge30pID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnQWN0aW9uU2hlZXQnKTtcbiAgY2hlY2tPcHRpb25zKG9wdGlvbnMpO1xuXG4gIC8vIE1haW4gY29tcG9uZW50XG4gIGxldCBhY3Rpb25TaGVldCA9IHV0aWwuY3JlYXRlRWxlbWVudChgXG4gICAgPG9ucy1hY3Rpb24tc2hlZXRcbiAgICAgICR7b3B0aW9ucy50aXRsZSA/IGB0aXRsZT1cIiR7b3B0aW9ucy50aXRsZX1cImAgOiAnJ31cbiAgICAgICR7b3B0aW9ucy5jYW5jZWxhYmxlID8gJ2NhbmNlbGFibGUnIDogJyd9XG4gICAgICAke29wdGlvbnMubW9kaWZpZXIgPyBgbW9kaWZpZXI9XCIke29wdGlvbnMubW9kaWZpZXJ9XCJgIDogJyd9XG4gICAgICAke29wdGlvbnMubWFza0NvbG9yID8gYG1hc2stY29sb3I9XCIke29wdGlvbnMubWFza0NvbG9yfVwiYCA6ICcnfVxuICAgICAgJHtvcHRpb25zLmlkID8gYGlkPVwiJHtvcHRpb25zLmlkfVwiYCA6ICcnfVxuICAgICAgJHtvcHRpb25zLmNsYXNzID8gYGNsYXNzPVwiJHtvcHRpb25zLmNsYXNzfVwiYCA6ICcnfVxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tc2hlZXRcIj48L2Rpdj5cbiAgICA8L29ucy1hY3Rpb24tc2hlZXQ+XG4gIGApO1xuXG4gIC8vIFJlc29sdmUgYWN0aW9uIGFuZCBjbGVhbiB1cFxuICBjb25zdCBmaW5pc2ggPSAoZXZlbnQsIGluZGV4ID0gLTEpID0+IHtcbiAgICBpZiAoYWN0aW9uU2hlZXQpIHtcbiAgICAgIG9wdGlvbnMuZGVzdHJveSAmJiBvcHRpb25zLmRlc3Ryb3koYWN0aW9uU2hlZXQpO1xuXG4gICAgICBhY3Rpb25TaGVldC5yZW1vdmVFdmVudExpc3RlbmVyKCdkaWFsb2ctY2FuY2VsJywgZmluaXNoLCBmYWxzZSk7XG4gICAgICBhY3Rpb25TaGVldC5yZW1vdmUoKTtcbiAgICAgIGFjdGlvblNoZWV0ID0gbnVsbDtcblxuICAgICAgb3B0aW9ucy5jYWxsYmFjayAmJiBvcHRpb25zLmNhbGxiYWNrKGluZGV4KTtcbiAgICAgIHJlc29sdmUoaW5kZXgpO1xuICAgIH1cbiAgfTtcblxuICAvLyBMaW5rIGNhbmNlbCBoYW5kbGVyXG4gIGFjdGlvblNoZWV0LmFkZEV2ZW50TGlzdGVuZXIoJ2RpYWxvZy1jYW5jZWwnLCBmaW5pc2gsIGZhbHNlKTtcblxuICAvLyBDcmVhdGUgYnV0dG9ucyBhbmQgbGluayBhY3Rpb24gaGFuZGxlclxuICBjb25zdCBidXR0b25zID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICBvcHRpb25zLmJ1dHRvbnMuZm9yRWFjaCgoaXRlbSwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBidXR0b25PcHRpb25zID0gKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykgPyB7IGxhYmVsOiBpdGVtIH0gOiB7IC4uLml0ZW0gfTtcbiAgICBpZiAob3B0aW9ucy5kZXN0cnVjdGl2ZSA9PT0gaW5kZXgpIHtcbiAgICAgIGJ1dHRvbk9wdGlvbnMubW9kaWZpZXIgPSAoYnV0dG9uT3B0aW9ucy5tb2RpZmllciB8fCAnJykgKyAnIGRlc3RydWN0aXZlJztcbiAgICB9XG5cbiAgICBjb25zdCBidXR0b24gPSB1dGlsLmNyZWF0ZUVsZW1lbnQoYFxuICAgICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uXG4gICAgICAgICR7YnV0dG9uT3B0aW9ucy5pY29uID8gYGljb249XCIke2J1dHRvbk9wdGlvbnMuaWNvbn1cImAgOiAnJ31cbiAgICAgICAgJHtidXR0b25PcHRpb25zLm1vZGlmaWVyID8gYG1vZGlmaWVyPVwiJHtidXR0b25PcHRpb25zLm1vZGlmaWVyfVwiYCA6ICcnfVxuICAgICAgPlxuICAgICAgICAke2J1dHRvbk9wdGlvbnMubGFiZWx9XG4gICAgICA8L29ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPlxuICAgIGApO1xuXG4gICAgYnV0dG9uLm9uY2xpY2sgPSBldmVudCA9PiBhY3Rpb25TaGVldC5oaWRlKCkudGhlbigoKSA9PiBmaW5pc2goZXZlbnQsIGluZGV4KSk7XG4gICAgYnV0dG9ucy5hcHBlbmRDaGlsZChidXR0b24pO1xuICB9KTtcblxuICAvLyBGaW5pc2ggY29tcG9uZW50IGFuZCBhdHRhY2hcbiAgdXRpbC5maW5kQ2hpbGQoYWN0aW9uU2hlZXQsICcuYWN0aW9uLXNoZWV0JykuYXBwZW5kQ2hpbGQoYnV0dG9ucyk7XG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYWN0aW9uU2hlZXQpO1xuICBvcHRpb25zLmNvbXBpbGUgJiYgb3B0aW9ucy5jb21waWxlKGVsLmRpYWxvZyk7XG5cbiAgLy8gU2hvd1xuICBzZXRJbW1lZGlhdGUoKCkgPT4gYWN0aW9uU2hlZXQuc2hvdyh7XG4gICAgYW5pbWF0aW9uOiBvcHRpb25zLmFuaW1hdGlvbixcbiAgICBhbmltYXRpb25PcHRpb25zOiBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNcbiAgfSkpO1xufSk7XG4iLCIvKipcbiAqIE1pY3JvRXZlbnQgLSB0byBtYWtlIGFueSBqcyBvYmplY3QgYW4gZXZlbnQgZW1pdHRlciAoc2VydmVyIG9yIGJyb3dzZXIpXG4gKlxuICogLSBwdXJlIGphdmFzY3JpcHQgLSBzZXJ2ZXIgY29tcGF0aWJsZSwgYnJvd3NlciBjb21wYXRpYmxlXG4gKiAtIGRvbnQgcmVseSBvbiB0aGUgYnJvd3NlciBkb21zXG4gKiAtIHN1cGVyIHNpbXBsZSAtIHlvdSBnZXQgaXQgaW1tZWRpYXRlbHksIG5vIG15c3RlcnksIG5vIG1hZ2ljIGludm9sdmVkXG4gKlxuICogLSBjcmVhdGUgYSBNaWNyb0V2ZW50RGVidWcgd2l0aCBnb29kaWVzIHRvIGRlYnVnXG4gKiAgIC0gbWFrZSBpdCBzYWZlciB0byB1c2VcbiovXG5cbi8qKiBOT1RFOiBUaGlzIGxpYnJhcnkgaXMgY3VzdG9taXplZCBmb3IgT25zZW4gVUkuICovXG5cbmNvbnN0IE1pY3JvRXZlbnQgID0gZnVuY3Rpb24oKXt9O1xuTWljcm9FdmVudC5wcm90b3R5cGUgID0ge1xuICBvbjogZnVuY3Rpb24oZXZlbnQsIGZjdCl7XG4gICAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSB0aGlzLl9ldmVudHNbZXZlbnRdIHx8IFtdO1xuICAgIHRoaXMuX2V2ZW50c1tldmVudF0ucHVzaChmY3QpO1xuICB9LFxuICBvbmNlOiBmdW5jdGlvbihldmVudCwgZmN0KXtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHdyYXBwZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYub2ZmKGV2ZW50LCB3cmFwcGVyKTtcbiAgICAgIHJldHVybiBmY3QuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICB9O1xuICAgIHRoaXMub24oZXZlbnQsIHdyYXBwZXIpO1xuICB9LFxuICBvZmY6IGZ1bmN0aW9uKGV2ZW50LCBmY3Qpe1xuICAgIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgICBpZiAoZXZlbnQgaW4gdGhpcy5fZXZlbnRzID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSB0aGlzLl9ldmVudHNbZXZlbnRdXG4gICAgICAuZmlsdGVyKGZ1bmN0aW9uKF9mY3QpIHtcbiAgICAgICAgaWYgKGZjdCkge1xuICAgICAgICAgICByZXR1cm4gZmN0ICE9PSBfZmN0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH0sXG4gIGVtaXQ6IGZ1bmN0aW9uKGV2ZW50IC8qICwgYXJncy4uLiAqLyl7XG4gICAgdGhpcy5fZXZlbnRzID0gdGhpcy5fZXZlbnRzIHx8IHt9O1xuICAgIGlmIChldmVudCBpbiB0aGlzLl9ldmVudHMgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fZXZlbnRzW2V2ZW50XS5sZW5ndGg7IGkrKyl7XG4gICAgICB0aGlzLl9ldmVudHNbZXZlbnRdW2ldLmFwcGx5KHRoaXMsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBtaXhpbiB3aWxsIGRlbGVnYXRlIGFsbCBNaWNyb0V2ZW50LmpzIGZ1bmN0aW9uIGluIHRoZSBkZXN0aW5hdGlvbiBvYmplY3RcbiAqXG4gKiAtIHJlcXVpcmUoJ01pY3JvRXZlbnQnKS5taXhpbihGb29iYXIpIHdpbGwgbWFrZSBGb29iYXIgYWJsZSB0byB1c2UgTWljcm9FdmVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0aGUgb2JqZWN0IHdoaWNoIHdpbGwgc3VwcG9ydCBNaWNyb0V2ZW50XG4qL1xuTWljcm9FdmVudC5taXhpbiAgPSBmdW5jdGlvbihkZXN0T2JqZWN0KXtcbiAgdmFyIHByb3BzID0gWydvbicsICdvbmNlJywgJ29mZicsICdlbWl0J107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpICsrKXtcbiAgICBpZiAodHlwZW9mIGRlc3RPYmplY3QgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGRlc3RPYmplY3QucHJvdG90eXBlW3Byb3BzW2ldXSAgPSBNaWNyb0V2ZW50LnByb3RvdHlwZVtwcm9wc1tpXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlc3RPYmplY3RbcHJvcHNbaV1dID0gTWljcm9FdmVudC5wcm90b3R5cGVbcHJvcHNbaV1dO1xuICAgIH1cbiAgfVxufVxuXG53aW5kb3cuTWljcm9FdmVudCA9IE1pY3JvRXZlbnQ7XG5leHBvcnQgZGVmYXVsdCBNaWNyb0V2ZW50O1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE1pY3JvRXZlbnQgZnJvbSAnLi9taWNyb2V2ZW50JztcblxuY29uc3QgY3JlYXRlID0gKCkgPT4ge1xuXG4gIC8qKlxuICAgKiBAb2JqZWN0IG9ucy5vcmllbnRhdGlvblxuICAgKiBAY2F0ZWdvcnkgdXRpbFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVXRpbGl0eSBtZXRob2RzIGZvciBvcmllbnRhdGlvbiBkZXRlY3Rpb24uWy9lbl1cbiAgICogICBbamFd55S76Z2i44Gu44Kq44Oq44Ko44Oz44OG44O844K344On44Oz5qSc55+l44Gu44Gf44KB44Gu44Om44O844OG44Kj44Oq44OG44Kj44Oh44K944OD44OJ44KS5Y+O44KB44Gm44GE44KL44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAgICovXG4gIGNvbnN0IG9iaiA9IHtcbiAgICAvKipcbiAgICAgKiBAZXZlbnQgY2hhbmdlXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgZGV2aWNlIG9yaWVudGF0aW9uIGNoYW5nZXMuWy9lbl1cbiAgICAgKiAgIFtqYV3jg4fjg5DjgqTjgrnjga7jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYzlpInljJbjgZfjgZ/pmpvjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAgICogQHBhcmFtIHtCb29sZWFufSBldmVudC5pc1BvcnRyYWl0XG4gICAgICogICBbZW5dV2lsbCBiZSB0cnVlIGlmIHRoZSBjdXJyZW50IG9yaWVudGF0aW9uIGlzIHBvcnRyYWl0IG1vZGUuWy9lbl1cbiAgICAgKiAgIFtqYV3nj77lnKjjga7jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxwb3J0cmFpdOOBruWgtOWQiOOBq3RydWXjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQG1ldGhvZCBvblxuICAgICAqIEBzaWduYXR1cmUgb24oZXZlbnROYW1lLCBsaXN0ZW5lcilcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiAgIFtlbl1BZGQgYW4gZXZlbnQgbGlzdGVuZXIuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjg6rjgrnjg4rjg7zjgpLov73liqDjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWVcbiAgICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBldmVudC5bL2VuXVxuICAgICAqICAgW2phXeOCpOODmeODs+ODiOWQjeOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXJcbiAgICAgKiAgIFtlbl1GdW5jdGlvbiB0byBleGVjdXRlIHdoZW4gdGhlIGV2ZW50IGlzIHRyaWdnZXJlZC5bL2VuXVxuICAgICAqICAgW2phXeOBk+OBruOCpOODmeODs+ODiOOBjOeZuueBq+OBleOCjOOBn+mam+OBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAgICovXG5cbiAgICAvKipcbiAgICAgKiBAbWV0aG9kIG9uY2VcbiAgICAgKiBAc2lnbmF0dXJlIG9uY2UoZXZlbnROYW1lLCBsaXN0ZW5lcilcbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiAgW2VuXUFkZCBhbiBldmVudCBsaXN0ZW5lciB0aGF0J3Mgb25seSB0cmlnZ2VyZWQgb25jZS5bL2VuXVxuICAgICAqICBbamFd5LiA5bqm44Gg44GR5ZG844Gz5Ye644GV44KM44KL44Kk44OZ44Oz44OI44Oq44K544OK44O844KS6L+95Yqg44GX44G+44GZ44CCWy9qYV1cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnROYW1lXG4gICAgICogICBbZW5dTmFtZSBvZiB0aGUgZXZlbnQuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICogICBbZW5dRnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgYznmbrngavjgZfjgZ/pmpvjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogQG1ldGhvZCBvZmZcbiAgICAgKiBAc2lnbmF0dXJlIG9mZihldmVudE5hbWUsIFtsaXN0ZW5lcl0pXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogIFtlbl1SZW1vdmUgYW4gZXZlbnQgbGlzdGVuZXIuIElmIHRoZSBsaXN0ZW5lciBpcyBub3Qgc3BlY2lmaWVkIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBldmVudCB0eXBlIHdpbGwgYmUgcmVtb3ZlZC5bL2VuXVxuICAgICAqICBbamFd44Kk44OZ44Oz44OI44Oq44K544OK44O844KS5YmK6Zmk44GX44G+44GZ44CC44KC44GX44Kk44OZ44Oz44OI44Oq44K544OK44O844KS5oyH5a6a44GX44Gq44GL44Gj44Gf5aC05ZCI44Gr44Gv44CB44Gd44Gu44Kk44OZ44Oz44OI44Gr57SQ44Gl44GP5YWo44Gm44Gu44Kk44OZ44Oz44OI44Oq44K544OK44O844GM5YmK6Zmk44GV44KM44G+44GZ44CCWy9qYV1cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnROYW1lXG4gICAgICogICBbZW5dTmFtZSBvZiB0aGUgZXZlbnQuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyXG4gICAgICogICBbZW5dRnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuWy9lbl1cbiAgICAgKiAgIFtqYV3liYrpmaTjgZnjgovjgqTjg5njg7Pjg4jjg6rjgrnjg4rjg7zjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuXG4gICAgLy8gYWN0dWFsIGltcGxlbWVudGF0aW9uIHRvIGRldGVjdCBpZiB3aGV0aGVyIGN1cnJlbnQgc2NyZWVuIGlzIHBvcnRyYWl0IG9yIG5vdFxuICAgIF9pc1BvcnRyYWl0OiBmYWxzZSxcblxuICAgIC8qKlxuICAgICAqIEBtZXRob2QgaXNQb3J0cmFpdFxuICAgICAqIEBzaWduYXR1cmUgaXNQb3J0cmFpdCgpXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKiAgIFtlbl1XaWxsIGJlIHRydWUgaWYgdGhlIGN1cnJlbnQgb3JpZW50YXRpb24gaXMgcG9ydHJhaXQgbW9kZS5bL2VuXVxuICAgICAqICAgW2phXeOCquODquOCqOODs+ODhuODvOOCt+ODp+ODs+OBjHBvcnRyYWl044Oi44O844OJ44Gu5aC05ZCI44GrdHJ1ZeOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAgICogQGRlc2NyaXB0aW9uXG4gICAgICogICBbZW5dUmV0dXJucyB3aGV0aGVyIHRoZSBjdXJyZW50IHNjcmVlbiBvcmllbnRhdGlvbiBpcyBwb3J0cmFpdCBvciBub3QuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxwb3J0cmFpdOODouODvOODieOBi+OBqeOBhuOBi+OCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAgICovXG4gICAgaXNQb3J0cmFpdDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5faXNQb3J0cmFpdCgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAbWV0aG9kIGlzTGFuZHNjYXBlXG4gICAgICogQHNpZ25hdHVyZSBpc0xhbmRzY2FwZSgpXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgKiAgIFtlbl1XaWxsIGJlIHRydWUgaWYgdGhlIGN1cnJlbnQgb3JpZW50YXRpb24gaXMgbGFuZHNjYXBlIG1vZGUuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxsYW5kc2NhcGXjg6Ljg7zjg4njga7loLTlkIjjgat0cnVl44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICAgKiBAZGVzY3JpcHRpb25cbiAgICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgc2NyZWVuIG9yaWVudGF0aW9uIGlzIGxhbmRzY2FwZSBvciBub3QuWy9lbl1cbiAgICAgKiAgIFtqYV3jgqrjg6rjgqjjg7Pjg4bjg7zjgrfjg6fjg7PjgYxsYW5kc2NhcGXjg6Ljg7zjg4njgYvjganjgYbjgYvjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgICAqL1xuICAgIGlzTGFuZHNjYXBlOiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAhdGhpcy5pc1BvcnRyYWl0KCk7XG4gICAgfSxcblxuICAgIF9pbml0OiBmdW5jdGlvbigpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCB0aGlzLl9vbkRPTUNvbnRlbnRMb2FkZWQuYmluZCh0aGlzKSwgZmFsc2UpO1xuXG4gICAgICBpZiAoJ29yaWVudGF0aW9uJyBpbiB3aW5kb3cpIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgdGhpcy5fb25PcmllbnRhdGlvbkNoYW5nZS5iaW5kKHRoaXMpLCBmYWxzZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fb25SZXNpemUuYmluZCh0aGlzKSwgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9pc1BvcnRyYWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBfb25ET01Db250ZW50TG9hZGVkOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuX2luc3RhbGxJc1BvcnRyYWl0SW1wbGVtZW50YXRpb24oKTtcbiAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJywge2lzUG9ydHJhaXQ6IHRoaXMuaXNQb3J0cmFpdCgpfSk7XG4gICAgfSxcblxuICAgIF9pbnN0YWxsSXNQb3J0cmFpdEltcGxlbWVudGF0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnN0IGlzUG9ydHJhaXQgPSB3aW5kb3cuaW5uZXJXaWR0aCA8IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgaWYgKCEoJ29yaWVudGF0aW9uJyBpbiB3aW5kb3cpKSB7XG4gICAgICAgIHRoaXMuX2lzUG9ydHJhaXQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0ID4gd2luZG93LmlubmVyV2lkdGg7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy5vcmllbnRhdGlvbiAlIDE4MCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9pc1BvcnRyYWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHdpbmRvdy5vcmllbnRhdGlvbiAlIDE4MCkgPT09IDAgPyBpc1BvcnRyYWl0IDogIWlzUG9ydHJhaXQ7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pc1BvcnRyYWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHdpbmRvdy5vcmllbnRhdGlvbiAlIDE4MCkgPT09IDkwID8gaXNQb3J0cmFpdCA6ICFpc1BvcnRyYWl0O1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBfb25PcmllbnRhdGlvbkNoYW5nZTogZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBpc1BvcnRyYWl0ID0gdGhpcy5faXNQb3J0cmFpdCgpO1xuXG4gICAgICAvLyBXYWl0IGZvciB0aGUgZGltZW5zaW9ucyB0byBjaGFuZ2UgYmVjYXVzZVxuICAgICAgLy8gb2YgQW5kcm9pZCBpbmNvbnNpc3RlbmN5LlxuICAgICAgbGV0IG5JdGVyID0gMDtcbiAgICAgIGNvbnN0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICBuSXRlcisrO1xuXG4gICAgICAgIGNvbnN0IHcgPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgICAgY29uc3QgaCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgICBpZiAoKGlzUG9ydHJhaXQgJiYgdyA8PSBoKSB8fFxuICAgICAgICAgICAoIWlzUG9ydHJhaXQgJiYgdyA+PSBoKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnY2hhbmdlJywge2lzUG9ydHJhaXQ6IGlzUG9ydHJhaXR9KTtcbiAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcbiAgICAgICAgfSBlbHNlIGlmIChuSXRlciA9PT0gNTApIHtcbiAgICAgICAgICB0aGlzLmVtaXQoJ2NoYW5nZScsIHtpc1BvcnRyYWl0OiBpc1BvcnRyYWl0fSk7XG4gICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgIH0sIDIwKTtcbiAgICB9LFxuXG4gICAgLy8gUnVuIG9uIG5vdCBtb2JpbGUgYnJvd3Nlci5cbiAgICBfb25SZXNpemU6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCB7aXNQb3J0cmFpdDogdGhpcy5pc1BvcnRyYWl0KCl9KTtcbiAgICB9XG4gIH07XG5cbiAgTWljcm9FdmVudC5taXhpbihvYmopO1xuXG4gIHJldHVybiBvYmo7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjcmVhdGUoKS5faW5pdCgpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBAb2JqZWN0IG9ucy5tb2RpZmllclxuICogQGNhdGVnb3J5IHZpc3VhbFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBVdGlsaXR5IG1ldGhvZHMgdG8gY2hhbmdlIG1vZGlmaWVyIGF0dHJpYnV0ZXMgb2YgT25zZW4gVUkgZWxlbWVudHMuLlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiBvbnMubW9kaWZpZXIuYWRkKG15T25zSW5wdXRFbGVtZW50LCAndW5kZXJiYXInKTtcbiAqIG9ucy5tb2RpZmllci50b2dnbGUobXlPbnNUb2FzdEVsZW1lbnQsICdjdXN0b20tbW9kaWZpZXInKTtcbiAqXG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIEBtZXRob2QgYWRkXG4gICAqIEBzaWduYXR1cmUgYWRkKGVsZW1lbnQsIG1vZGlmaWVyIFssIG1vZGlmaWVyXSlcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUFkZCB0aGUgc3BlY2lmaWVkIG1vZGlmaWVycyB0byB0aGUgZWxlbWVudCBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbmNsdWRlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllclxuICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgYWRkOiAoZWxlbWVudCwgLi4ubW9kaWZpZXJzKSA9PiBtb2RpZmllcnMuZm9yRWFjaChtb2RpZmllciA9PiB1dGlsLmFkZE1vZGlmaWVyKGVsZW1lbnQsIG1vZGlmaWVyKSksXG4gIC8qKlxuICAgKiBAbWV0aG9kIHJlbW92ZVxuICAgKiBAc2lnbmF0dXJlIHJlbW92ZShlbGVtZW50LCBtb2RpZmllciBbLCBtb2RpZmllcl0pXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZW1vdmUgdGhlIHNwZWNpZmllZCBtb2RpZmllcnMgZnJvbSB0aGUgZWxlbWVudCBpZiB0aGV5IGFyZSBpbmNsdWRlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllclxuICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgcmVtb3ZlOiAoZWxlbWVudCwgLi4ubW9kaWZpZXJzKSA9PiBtb2RpZmllcnMuZm9yRWFjaChtb2RpZmllciA9PiB1dGlsLnJlbW92ZU1vZGlmaWVyKGVsZW1lbnQsIG1vZGlmaWVyKSksXG4gIC8qKlxuICAgKiBAbWV0aG9kIGNvbnRhaW5zXG4gICAqIEBzaWduYXR1cmUgY29udGFpbnMoZWxlbWVudCwgbW9kaWZpZXIpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DaGVjayB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbW9kaWZpZXIgaXMgaW5jbHVkZWQgaW4gdGhlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICAgKiAgIFtlbl1UYXJnZXQgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbW9kaWZpZXJcbiAgICogICBbZW5dTmFtZSBvZiB0aGUgbW9kaWZpZXIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICogICBbZW5dYHRydWVgIHdoZW4gdGhlIHNwZWNpZmllZCBtb2RpZmllciBpcyBmb3VuZCBpbiB0aGUgZWxlbWVudCdzIGBtb2RpZmllcmAgYXR0cmlidXRlLiBgZmFsc2VgIG90aGVyd2lzZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgY29udGFpbnM6IHV0aWwuaGFzTW9kaWZpZXIsXG4gIC8qKlxuICAgKiBAbWV0aG9kIHRvZ2dsZVxuICAgKiBAc2lnbmF0dXJlIHRvZ2dsZShlbGVtZW50LCBtb2RpZmllciBbLCBmb3JjZV0pXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Ub2dnbGUgdGhlIHNwZWNpZmllZCBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtb2RpZmllclxuICAgKiAgIFtlbl1OYW1lIG9mIHRoZSBtb2RpZmllci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZm9yY2VcbiAgICogICBbZW5dSWYgaXQgZXZhbHVhdGVzIHRvIHRydWUsIGFkZCBzcGVjaWZpZWQgbW9kaWZpZXIgdmFsdWUsIGFuZCBpZiBpdCBldmFsdWF0ZXMgdG8gZmFsc2UsIHJlbW92ZSBpdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgdG9nZ2xlOiB1dGlsLnRvZ2dsZU1vZGlmaWVyXG59O1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcbmltcG9ydCBNaWNyb0V2ZW50IGZyb20gJy4vbWljcm9ldmVudCc7XG5cbmNvbnN0IHNvZnR3YXJlS2V5Ym9hcmQgPSBuZXcgTWljcm9FdmVudCgpO1xuc29mdHdhcmVLZXlib2FyZC5fdmlzaWJsZSA9IGZhbHNlO1xuXG5jb25zdCBvblNob3cgPSAoKSA9PiB7XG4gIHNvZnR3YXJlS2V5Ym9hcmQuX3Zpc2libGUgPSB0cnVlO1xuICBzb2Z0d2FyZUtleWJvYXJkLmVtaXQoJ3Nob3cnKTtcbn07XG5cbmNvbnN0IG9uSGlkZSA9ICgpID0+IHtcbiAgc29mdHdhcmVLZXlib2FyZC5fdmlzaWJsZSA9IGZhbHNlO1xuICBzb2Z0d2FyZUtleWJvYXJkLmVtaXQoJ2hpZGUnKTtcbn07XG5cbmNvbnN0IGJpbmRFdmVudHMgPSAoKSA9PiB7XG4gIGlmICh0eXBlb2YgS2V5Ym9hcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21hcnRpbm1vc2UvY29yZG92YS1rZXlib2FyZC9ibG9iLzk1ZjNkYTNhMzhkOGY4ZTFmYTQxZmJmNDAxNDUzNTJjMTM1MzVhMDAvUkVBRE1FLm1kXG4gICAgS2V5Ym9hcmQub25zaG93ID0gb25TaG93O1xuICAgIEtleWJvYXJkLm9uaGlkZSA9IG9uSGlkZTtcbiAgICBzb2Z0d2FyZUtleWJvYXJkLmVtaXQoJ2luaXQnLCB7dmlzaWJsZTogS2V5Ym9hcmQuaXNWaXNpYmxlfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY29yZG92YS5wbHVnaW5zICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgY29yZG92YS5wbHVnaW5zLktleWJvYXJkICE9PSAndW5kZWZpbmVkJykge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kcmlmdHljby9pb25pYy1wbHVnaW5zLWtleWJvYXJkL2Jsb2IvY2EyN2VjZi9SRUFETUUubWRcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbmF0aXZlLmtleWJvYXJkc2hvdycsIG9uU2hvdyk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ25hdGl2ZS5rZXlib2FyZGhpZGUnLCBvbkhpZGUpO1xuICAgIHNvZnR3YXJlS2V5Ym9hcmQuZW1pdCgnaW5pdCcsIHt2aXNpYmxlOiBjb3Jkb3ZhLnBsdWdpbnMuS2V5Ym9hcmQuaXNWaXNpYmxlfSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IG5vUGx1Z2luRXJyb3IgPSAoKSA9PiB7XG4gIHV0aWwud2Fybignb25zLWtleWJvYXJkOiBDb3Jkb3ZhIEtleWJvYXJkIHBsdWdpbiBpcyBub3QgcHJlc2VudC4nKTtcbn07XG5cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZXJlYWR5JywgKCkgPT4ge1xuICBpZiAoIWJpbmRFdmVudHMoKSkge1xuICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbb25zLWtleWJvYXJkLWFjdGl2ZV0nKSB8fFxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignW29ucy1rZXlib2FyZC1pbmFjdGl2ZV0nKSkge1xuICAgICAgbm9QbHVnaW5FcnJvcigpO1xuICAgIH1cblxuICAgIHNvZnR3YXJlS2V5Ym9hcmQub24gPSBub1BsdWdpbkVycm9yO1xuICB9XG59KTtcblxuZXhwb3J0IGRlZmF1bHQgc29mdHdhcmVLZXlib2FyZDtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmNvbnN0IGdlbmVyYXRlSWQgPSAoZnVuY3Rpb24oKSB7XG4gIGxldCBpID0gMDtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpKys7XG4gIH07XG59KSgpO1xuXG4vKipcbiAqIERvb3IgbG9ja2luZyBzeXN0ZW0uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMubG9nXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb29yTG9jayB7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5fbG9ja0xpc3QgPSBbXTtcbiAgICB0aGlzLl93YWl0TGlzdCA9IFtdO1xuICAgIHRoaXMuX2xvZyA9IG9wdGlvbnMubG9nIHx8IGZ1bmN0aW9uKCkge307XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBsb2NrLlxuICAgKlxuICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gQ2FsbGJhY2sgZm9yIHVubG9ja2luZy5cbiAgICovXG4gIGxvY2soKSB7XG4gICAgY29uc3QgdW5sb2NrID0gKCkgPT4ge1xuICAgICAgdGhpcy5fdW5sb2NrKHVubG9jayk7XG4gICAgfTtcbiAgICB1bmxvY2suaWQgPSBnZW5lcmF0ZUlkKCk7XG4gICAgdGhpcy5fbG9ja0xpc3QucHVzaCh1bmxvY2spO1xuICAgIHRoaXMuX2xvZygnbG9jazogJyArICh1bmxvY2suaWQpKTtcblxuICAgIHJldHVybiB1bmxvY2s7XG4gIH1cblxuICBfdW5sb2NrKGZuKSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9sb2NrTGlzdC5pbmRleE9mKGZuKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoaXMgZnVuY3Rpb24gaXMgbm90IHJlZ2lzdGVyZWQgaW4gdGhlIGxvY2sgbGlzdC4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9sb2NrTGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMuX2xvZygndW5sb2NrOiAnICsgZm4uaWQpO1xuXG4gICAgdGhpcy5fdHJ5VG9GcmVlV2FpdExpc3QoKTtcbiAgfVxuXG4gIF90cnlUb0ZyZWVXYWl0TGlzdCgpIHtcbiAgICB3aGlsZSAoIXRoaXMuaXNMb2NrZWQoKSAmJiB0aGlzLl93YWl0TGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl93YWl0TGlzdC5zaGlmdCgpKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIHdhaXRpbmcgdW5sb2NrZWQgZG9vci5cbiAgICpcbiAgICogQHBhcmFtcyB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIG9uIHVubG9ja2luZyB0aGUgZG9vciBjb21wbGV0ZWx5LlxuICAgKi9cbiAgd2FpdFVubG9jayhjYWxsYmFjaykge1xuICAgIGlmICghKGNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjYWxsYmFjayBwYXJhbSBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNMb2NrZWQoKSkge1xuICAgICAgdGhpcy5fd2FpdExpc3QucHVzaChjYWxsYmFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBpc0xvY2tlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9ja0xpc3QubGVuZ3RoID4gMDtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cbmltcG9ydCB1dGlsIGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi9pbnRlcm5hbCc7XG5cbi8vIERlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIGdsb2JhbCBQYWdlTG9hZGVyLlxuZnVuY3Rpb24gbG9hZFBhZ2Uoe3BhZ2UsIHBhcmVudCwgcGFyYW1zID0ge319LCBkb25lKSB7XG4gIGludGVybmFsLmdldFBhZ2VIVE1MQXN5bmMocGFnZSkudGhlbihodG1sID0+IHtcbiAgICBjb25zdCBwYWdlRWxlbWVudCA9IHV0aWwuY3JlYXRlRWxlbWVudChodG1sKTtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQocGFnZUVsZW1lbnQpO1xuXG4gICAgZG9uZShwYWdlRWxlbWVudCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB1bmxvYWRQYWdlKGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQuX2Rlc3Ryb3kgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgIGVsZW1lbnQuX2Rlc3Ryb3koKTtcbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50LnJlbW92ZSgpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQYWdlTG9hZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl0gUmV0dXJucyBhbiBvYmplY3QgdGhhdCBoYXMgXCJlbGVtZW50XCIgcHJvcGVydHkgYW5kIFwidW5sb2FkXCIgZnVuY3Rpb24uXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihsb2FkZXIsIHVubG9hZGVyKSB7XG4gICAgdGhpcy5fbG9hZGVyID0gbG9hZGVyIGluc3RhbmNlb2YgRnVuY3Rpb24gPyBsb2FkZXIgOiBsb2FkUGFnZTtcbiAgICB0aGlzLl91bmxvYWRlciA9IHVubG9hZGVyIGluc3RhbmNlb2YgRnVuY3Rpb24gPyB1bmxvYWRlciA6IHVubG9hZFBhZ2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGludGVybmFsIGxvYWRlciBpbXBsZW1lbnRhdGlvbi5cbiAgICovXG4gIHNldCBpbnRlcm5hbExvYWRlcihmbikge1xuICAgIGlmICghKGZuIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB0aHJvdyBFcnJvcignRmlyc3QgcGFyYW1ldGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgRnVuY3Rpb24nKTtcbiAgICB9XG4gICAgdGhpcy5fbG9hZGVyID0gZm47XG4gIH1cblxuICBnZXQgaW50ZXJuYWxMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xvYWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb3B0aW9ucy5wYWdlXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gb3B0aW9ucy5wYXJlbnQgQSBsb2NhdGlvbiB0byBsb2FkIHBhZ2UuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wYXJhbXNdIEV4dHJhIHBhcmFtZXRlcnMgZm9yIG9ucy1wYWdlLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIFRha2UgYW4gb2JqZWN0IHRoYXQgaGFzIFwiZWxlbWVudFwiIHByb3BlcnR5IGFuZCBcInVubG9hZFwiIGZ1bmN0aW9uLlxuICAgKi9cbiAgbG9hZCh7cGFnZSwgcGFyZW50LCBwYXJhbXMgPSB7fX0sIGRvbmUpIHtcbiAgICB0aGlzLl9sb2FkZXIoe3BhZ2UsIHBhcmVudCwgcGFyYW1zfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgaWYgKCEocGFnZUVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSkge1xuICAgICAgICB0aHJvdyBFcnJvcigncGFnZUVsZW1lbnQgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiBFbGVtZW50LicpO1xuICAgICAgfVxuXG4gICAgICBkb25lKHBhZ2VFbGVtZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHVubG9hZChwYWdlRWxlbWVudCkge1xuICAgIGlmICghKHBhZ2VFbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudCkpIHtcbiAgICAgIHRocm93IEVycm9yKCdwYWdlRWxlbWVudCBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIEVsZW1lbnQuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdW5sb2FkZXIocGFnZUVsZW1lbnQpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0UGFnZUxvYWRlciA9IG5ldyBQYWdlTG9hZGVyKCk7XG5cbmV4cG9ydCBjb25zdCBpbnN0YW50UGFnZUxvYWRlciA9IG5ldyBQYWdlTG9hZGVyKFxuICBmdW5jdGlvbih7cGFnZSwgcGFyZW50LCBwYXJhbXMgPSB7fX0sIGRvbmUpIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdXRpbC5jcmVhdGVFbGVtZW50KHBhZ2UudHJpbSgpKTtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cbiAgICBkb25lKGVsZW1lbnQpO1xuICB9LFxuICB1bmxvYWRQYWdlXG4pO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi91dGlsJztcbmltcG9ydCBlbGVtZW50cyBmcm9tICcuL2VsZW1lbnRzJ1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuL2FuaW1pdCdcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi9nZXN0dXJlLWRldGVjdG9yJztcbmltcG9ydCBwbGF0Zm9ybSBmcm9tICcuL3BsYXRmb3JtJztcbmltcG9ydCBub3RpZmljYXRpb24gZnJvbSAnLi9ub3RpZmljYXRpb24nO1xuaW1wb3J0IGFjdGlvblNoZWV0IGZyb20gJy4vYWN0aW9uLXNoZWV0JztcbmltcG9ydCBpbnRlcm5hbCBmcm9tICcuL2ludGVybmFsJztcbmltcG9ydCBvcmllbnRhdGlvbiBmcm9tICcuL29yaWVudGF0aW9uJztcbmltcG9ydCBtb2RpZmllciBmcm9tICcuL21vZGlmaWVyJztcbmltcG9ydCBzb2Z0d2FyZUtleWJvYXJkIGZyb20gJy4vc29mdHdhcmUta2V5Ym9hcmQnO1xuaW1wb3J0IHBhZ2VBdHRyaWJ1dGVFeHByZXNzaW9uIGZyb20gJy4vcGFnZS1hdHRyaWJ1dGUtZXhwcmVzc2lvbic7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4vYXV0b3N0eWxlJztcbmltcG9ydCBEb29yTG9jayBmcm9tICcuL2Rvb3Jsb2NrJztcbmltcG9ydCB7IGRlZmF1bHRQYWdlTG9hZGVyLCBQYWdlTG9hZGVyIH0gZnJvbSAnLi9wYWdlLWxvYWRlcic7XG5cbi8qKlxuICogQG9iamVjdCBvbnNcbiAqIEBjYXRlZ29yeSB1dGlsXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2phXU9uc2VuIFVJ44Gn5Yip55So44Gn44GN44KL44Kw44Ot44O844OQ44Or44Gq44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAqICAgW2VuXUEgZ2xvYmFsIG9iamVjdCB0aGF0J3MgdXNlZCBpbiBPbnNlbiBVSS4gWy9lbl1cbiAqL1xuY29uc3Qgb25zID0ge1xuICBhbmltaXQsXG4gIGRlZmF1bHRQYWdlTG9hZGVyLFxuICBlbGVtZW50cyxcbiAgR2VzdHVyZURldGVjdG9yLFxuICBtb2RpZmllcixcbiAgbm90aWZpY2F0aW9uLFxuICBvcmllbnRhdGlvbixcbiAgcGFnZUF0dHJpYnV0ZUV4cHJlc3Npb24sXG4gIFBhZ2VMb2FkZXIsXG4gIHBsYXRmb3JtLFxuICBzb2Z0d2FyZUtleWJvYXJkLFxuICBfYXV0b1N0eWxlOiBhdXRvU3R5bGUsXG4gIF9pbnRlcm5hbDogaW50ZXJuYWwsXG4gIF9yZWFkeUxvY2s6IG5ldyBEb29yTG9jaygpLFxuICBfdXRpbDogdXRpbCxcbn07XG5cbm9ucy5wbGF0Zm9ybS5zZWxlY3QoKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gubWF0Y2goL3BsYXRmb3JtPShbXFx3LV0rKS8pIHx8IFtdKVsxXSk7XG5cbndhaXREZXZpY2VSZWFkeSgpO1xuXG5jb25zdCByZWFkeUVycm9yID0gYWZ0ZXIgPT4gdXRpbC50aHJvdyhgVGhpcyBtZXRob2QgbXVzdCBiZSBjYWxsZWQgJHthZnRlciA/ICdhZnRlcicgOiAnYmVmb3JlJ30gb25zLmlzUmVhZHkoKSBpcyB0cnVlYCk7XG5cbi8qKlxuICogQG1ldGhvZCBpc1JlYWR5XG4gKiBAc2lnbmF0dXJlIGlzUmVhZHkoKVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqICAgW2VuXVdpbGwgYmUgdHJ1ZSBpZiBPbnNlbiBVSSBpcyBpbml0aWFsaXplZC5bL2VuXVxuICogICBbamFd5Yid5pyf5YyW44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dUmV0dXJucyB0cnVlIGlmIE9uc2VuIFVJIGlzIGluaXRpYWxpemVkLlsvZW5dXG4gKiAgIFtqYV1PbnNlbiBVSeOBjOOBmeOBp+OBq+WIneacn+WMluOBleOCjOOBpuOBhOOCi+OBi+OBqeOBhuOBi+OCkui/lOOBmeODoeOCveODg+ODieOBp+OBmeOAglsvamFdXG4gKi9cbm9ucy5pc1JlYWR5ID0gKCkgPT4ge1xuICByZXR1cm4gIW9ucy5fcmVhZHlMb2NrLmlzTG9ja2VkKCk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgaXNXZWJWaWV3XG4gKiBAc2lnbmF0dXJlIGlzV2ViVmlldygpXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogICBbZW5dV2lsbCBiZSB0cnVlIGlmIHRoZSBhcHAgaXMgcnVubmluZyBpbiBDb3Jkb3ZhLlsvZW5dXG4gKiAgIFtqYV1Db3Jkb3Zh44Gn5a6f6KGM44GV44KM44Gm44GE44KL5aC05ZCI44GrdHJ1ZeOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVJldHVybnMgdHJ1ZSBpZiBydW5uaW5nIGluc2lkZSBDb3Jkb3ZhLlsvZW5dXG4gKiAgIFtqYV1Db3Jkb3Zh44Gn5a6f6KGM44GV44KM44Gm44GE44KL44GL44Gp44GG44GL44KS6L+U44GZ44Oh44K944OD44OJ44Gn44GZ44CCWy9qYV1cbiAqL1xub25zLmlzV2ViVmlldyA9IG9ucy5wbGF0Zm9ybS5pc1dlYlZpZXc7XG5cbi8qKlxuICogQG1ldGhvZCByZWFkeVxuICogQHNpZ25hdHVyZSByZWFkeShjYWxsYmFjaylcbiAqIEBkZXNjcmlwdGlvblxuICogICBbamFd44Ki44OX44Oq44Gu5Yid5pyf5YyW44Gr5Yip55So44GZ44KL44Oh44K944OD44OJ44Gn44GZ44CC5rih44GV44KM44Gf6Zai5pWw44Gv44CBT25zZW4gVUnjga7liJ3mnJ/ljJbjgYzntYLkuobjgZfjgabjgYTjgovmmYLngrnjgaflv4XjgZrlkbzjgbDjgozjgb7jgZnjgIJbL2phXVxuICogICBbZW5dTWV0aG9kIHVzZWQgdG8gd2FpdCBmb3IgYXBwIGluaXRpYWxpemF0aW9uLiBXYWl0cyBmb3IgYERPTUNvbnRlbnRMb2FkZWRgIGFuZCBgZGV2aWNlcmVhZHlgLCB3aGVuIG5lY2Vzc2FyeSwgYmVmb3JlIGV4ZWN1dGluZyB0aGUgY2FsbGJhY2suWy9lbl1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGV4ZWN1dGVzIGFmdGVyIE9uc2VuIFVJIGhhcyBiZWVuIGluaXRpYWxpemVkLlsvZW5dXG4gKiAgIFtqYV1PbnNlbiBVSeOBjOWIneacn+WMluOBjOWujOS6huOBl+OBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5yZWFkeSA9IGNhbGxiYWNrID0+IHtcbiAgaWYgKG9ucy5pc1JlYWR5KCkpIHtcbiAgICBjYWxsYmFjaygpO1xuICB9IGVsc2Uge1xuICAgIG9ucy5fcmVhZHlMb2NrLndhaXRVbmxvY2soY2FsbGJhY2spO1xuICB9XG59O1xuXG4vKipcbiAqIEBtZXRob2Qgc2V0RGVmYXVsdERldmljZUJhY2tCdXR0b25MaXN0ZW5lclxuICogQHNpZ25hdHVyZSBzZXREZWZhdWx0RGV2aWNlQmFja0J1dHRvbkxpc3RlbmVyKGxpc3RlbmVyKVxuICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXJcbiAqICAgW2VuXUZ1bmN0aW9uIHRoYXQgZXhlY3V0ZXMgd2hlbiBkZXZpY2UgYmFjayBidXR0b24gaXMgcHJlc3NlZC4gTXVzdCBiZSBjYWxsZWQgb24gYG9ucy5yZWFkeWAuWy9lbl1cbiAqICAgW2phXeODh+ODkOOCpOOCueOBruODkOODg+OCr+ODnOOCv+ODs+OBjOaKvOOBleOCjOOBn+aZguOBq+Wun+ihjOOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNldCBkZWZhdWx0IGhhbmRsZXIgZm9yIGRldmljZSBiYWNrIGJ1dHRvbi5bL2VuXVxuICogICBbamFd44OH44OQ44Kk44K544Gu44OQ44OD44Kv44Oc44K/44Oz44Gu44Gf44KB44Gu44OH44OV44Kp44Or44OI44Gu44OP44Oz44OJ44Op44KS6Kit5a6a44GX44G+44GZ44CCWy9qYV1cbiAqL1xub25zLnNldERlZmF1bHREZXZpY2VCYWNrQnV0dG9uTGlzdGVuZXIgPSBmdW5jdGlvbihsaXN0ZW5lcikge1xuICBpZiAoIW9ucy5pc1JlYWR5KCkpIHtcbiAgICByZWFkeUVycm9yKHRydWUpO1xuICB9XG4gIG9ucy5fZGVmYXVsdERldmljZUJhY2tCdXR0b25IYW5kbGVyLnNldExpc3RlbmVyKGxpc3RlbmVyKTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBkaXNhYmxlRGV2aWNlQmFja0J1dHRvbkhhbmRsZXJcbiAqIEBzaWduYXR1cmUgZGlzYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyKClcbiAqIEBkZXNjcmlwdGlvblxuICogW2VuXURpc2FibGUgZGV2aWNlIGJhY2sgYnV0dG9uIGV2ZW50IGhhbmRsZXIuIE11c3QgYmUgY2FsbGVkIG9uIGBvbnMucmVhZHlgLlsvZW5dXG4gKiBbamFd44OH44OQ44Kk44K544Gu44OQ44OD44Kv44Oc44K/44Oz44Gu44Kk44OZ44Oz44OI44KS5Y+X44GR5LuY44GR44Gq44GE44KI44GG44Gr44GX44G+44GZ44CCWy9qYV1cbiAqL1xub25zLmRpc2FibGVEZXZpY2VCYWNrQnV0dG9uSGFuZGxlciA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIW9ucy5pc1JlYWR5KCkpIHtcbiAgICByZWFkeUVycm9yKHRydWUpO1xuICB9XG4gIGludGVybmFsLmRiYkRpc3BhdGNoZXIuZGlzYWJsZSgpO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIGVuYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyXG4gKiBAc2lnbmF0dXJlIGVuYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyKClcbiAqIEBkZXNjcmlwdGlvblxuICogW2VuXUVuYWJsZSBkZXZpY2UgYmFjayBidXR0b24gZXZlbnQgaGFuZGxlci4gTXVzdCBiZSBjYWxsZWQgb24gYG9ucy5yZWFkeWAuWy9lbl1cbiAqIFtqYV3jg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7Pjga7jgqTjg5njg7Pjg4jjgpLlj5fjgZHku5jjgZHjgovjgojjgYbjgavjgZfjgb7jgZnjgIJbL2phXVxuICovXG5vbnMuZW5hYmxlRGV2aWNlQmFja0J1dHRvbkhhbmRsZXIgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCFvbnMuaXNSZWFkeSgpKSB7XG4gICAgcmVhZHlFcnJvcih0cnVlKTtcbiAgfVxuICBpbnRlcm5hbC5kYmJEaXNwYXRjaGVyLmVuYWJsZSgpO1xufTtcblxub25zLmZpcmVEZXZpY2VCYWNrQnV0dG9uRXZlbnQgPSBmdW5jdGlvbigpIHtcbiAgaW50ZXJuYWwuZGJiRGlzcGF0Y2hlci5maXJlRGV2aWNlQmFja0J1dHRvbkV2ZW50KCk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgZW5hYmxlQXV0b1N0YXR1c0JhckZpbGxcbiAqIEBzaWduYXR1cmUgZW5hYmxlQXV0b1N0YXR1c0JhckZpbGwoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1FbmFibGUgc3RhdHVzIGJhciBmaWxsIGZlYXR1cmUgb24gaU9TNyBhbmQgYWJvdmUgKGV4Y2VwdCBmb3IgaVBob25lIFgpLiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgYG9ucy5yZWFkeWAuWy9lbl1cbiAqICAgW2phXWlPUzfku6XkuIrvvIhpUGhvbmUgWOOBr+mZpOOBj++8ieOBp+OAgeOCueODhuODvOOCv+OCueODkOODvOmDqOWIhuOBrumrmOOBleOCkuiHquWLleeahOOBq+Wfi+OCgeOCi+WHpueQhuOCkuacieWKueOBq+OBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5lbmFibGVBdXRvU3RhdHVzQmFyRmlsbCA9ICgpID0+IHtcbiAgaWYgKG9ucy5pc1JlYWR5KCkpIHtcbiAgICByZWFkeUVycm9yKGZhbHNlKTtcbiAgfVxuICBpbnRlcm5hbC5jb25maWcuYXV0b1N0YXR1c0JhckZpbGwgPSB0cnVlO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIGRpc2FibGVBdXRvU3RhdHVzQmFyRmlsbFxuICogQHNpZ25hdHVyZSBkaXNhYmxlQXV0b1N0YXR1c0JhckZpbGwoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1EaXNhYmxlIHN0YXR1cyBiYXIgZmlsbCBmZWF0dXJlIG9uIGlPUzcgYW5kIGFib3ZlIChleGNlcHQgZm9yIGlQaG9uZSBYKS4gTXVzdCBiZSBjYWxsZWQgYmVmb3JlIGBvbnMucmVhZHlgLlsvZW5dXG4gKiAgIFtqYV1pT1M35Lul5LiK77yIaVBob25lIFjjga/pmaTjgY/vvInjgafjgIHjgrnjg4bjg7zjgr/jgrnjg5Djg7zpg6jliIbjga7pq5jjgZXjgpLoh6rli5XnmoTjgavln4vjgoHjgovlh6bnkIbjgpLnhKHlirnjgavjgZfjgb7jgZnjgIJbL2phXVxuICovXG5vbnMuZGlzYWJsZUF1dG9TdGF0dXNCYXJGaWxsID0gKCkgPT4ge1xuICBpZiAob25zLmlzUmVhZHkoKSkge1xuICAgIHJlYWR5RXJyb3IoZmFsc2UpO1xuICB9XG4gIGludGVybmFsLmNvbmZpZy5hdXRvU3RhdHVzQmFyRmlsbCA9IGZhbHNlO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIG1vY2tTdGF0dXNCYXJcbiAqIEBzaWduYXR1cmUgbW9ja1N0YXR1c0JhcigpXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUNyZWF0ZXMgYSBzdGF0aWMgZWxlbWVudCBzaW1pbGFyIHRvIGlPUyBzdGF0dXMgYmFyLiBPbmx5IHVzZWZ1bCBmb3IgYnJvd3NlciB0ZXN0aW5nLiBNdXN0IGJlIGNhbGxlZCBiZWZvcmUgYG9ucy5yZWFkeWAuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKi9cbm9ucy5tb2NrU3RhdHVzQmFyID0gKCkgPT4ge1xuICBpZiAob25zLmlzUmVhZHkoKSkge1xuICAgIHJlYWR5RXJyb3IoZmFsc2UpO1xuICB9XG5cbiAgY29uc3QgbW9jayA9ICgpID0+IHtcbiAgICBpZiAoIWRvY3VtZW50LmJvZHkuY2hpbGRyZW5bMF0gfHwgIWRvY3VtZW50LmJvZHkuY2hpbGRyZW5bMF0uY2xhc3NMaXN0LmNvbnRhaW5zKCdvbnMtc3RhdHVzLWJhci1tb2NrJykpIHtcbiAgICAgIGNvbnN0IGFuZHJvaWQgPSBwbGF0Zm9ybS5pc0FuZHJvaWQoKSwgaSA9IGkgPT4gYDxpIGNsYXNzPVwiJHtpLnNwbGl0KCctJylbMF19ICR7aX1cIj48L2k+YDtcbiAgICAgIGNvbnN0IGxlZnQgPSBhbmRyb2lkID8gYCR7aSgnem1kaS10d2l0dGVyJyl9ICR7aSgnem1kaS1nb29nbGUtcGxheScpfWAgOiBgTm8gU0lNICR7aSgnZmEtd2lmaScpfWAsXG4gICAgICAgIGNlbnRlciA9IGFuZHJvaWQgPyAnJyA6ICcxMjoyOCBQTScsXG4gICAgICAgIHJpZ2h0ID0gYW5kcm9pZCA/IGAke2koJ3ptZGktbmV0d29yaycpfSAke2koJ3ptZGktd2lmaScpfSAke2koJ3ptZGktYmF0dGVyeScpfSAxMjoyOCBQTWAgOiBgODAlICR7aSgnZmEtYmF0dGVyeS10aHJlZS1xdWFydGVycycpfWA7XG5cbiAgICAgIGRvY3VtZW50LmJvZHkuaW5zZXJ0QmVmb3JlKHV0aWwuY3JlYXRlRWxlbWVudChcbiAgICAgICAgYDxkaXYgY2xhc3M9XCJvbnMtc3RhdHVzLWJhci1tb2NrICR7YW5kcm9pZCA/ICdhbmRyb2lkJyA6ICdpb3MnfVwiPmAgK1xuICAgICAgICAgIGA8ZGl2PiR7bGVmdH08L2Rpdj48ZGl2PiR7Y2VudGVyfTwvZGl2PjxkaXY+JHtyaWdodH08L2Rpdj5gICtcbiAgICAgICAgYDwvZGl2PmBcbiAgICAgICksIGRvY3VtZW50LmJvZHkuZmlyc3RDaGlsZCk7XG4gICAgfVxuICB9O1xuXG4gIGRvY3VtZW50LmJvZHlcbiAgICA/IG1vY2soKVxuICAgIDogaW50ZXJuYWwud2FpdERPTUNvbnRlbnRMb2FkZWQobW9jayk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgZGlzYWJsZUFuaW1hdGlvbnNcbiAqIEBzaWduYXR1cmUgZGlzYWJsZUFuaW1hdGlvbnMoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1EaXNhYmxlIGFsbCBhbmltYXRpb25zLiBDb3VsZCBiZSBoYW5keSBmb3IgdGVzdGluZyBhbmQgb2xkZXIgZGV2aWNlcy5bL2VuXVxuICogICBbamFd44Ki44OL44Oh44O844K344On44Oz44KS5YWo44Gm54Sh5Yq544Gr44GX44G+44GZ44CC44OG44K544OI44Gu6Zqb44Gr5L6/5Yip44Gn44GZ44CCWy9qYV1cbiAqL1xub25zLmRpc2FibGVBbmltYXRpb25zID0gKCkgPT4ge1xuICBpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkID0gdHJ1ZTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBlbmFibGVBbmltYXRpb25zXG4gKiBAc2lnbmF0dXJlIGVuYWJsZUFuaW1hdGlvbnMoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1FbmFibGUgYW5pbWF0aW9ucyAoZGVmYXVsdCkuWy9lbl1cbiAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+OCkuacieWKueOBq+OBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5lbmFibGVBbmltYXRpb25zID0gKCkgPT4ge1xuICBpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkID0gZmFsc2U7XG59O1xuXG5vbnMuX2Rpc2FibGVXYXJuaW5ncyA9ICgpID0+IHtcbiAgaW50ZXJuYWwuY29uZmlnLndhcm5pbmdzRGlzYWJsZWQgPSB0cnVlO1xufTtcblxub25zLl9lbmFibGVXYXJuaW5ncyA9ICgpID0+IHtcbiAgaW50ZXJuYWwuY29uZmlnLndhcm5pbmdzRGlzYWJsZWQgPSBmYWxzZTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBkaXNhYmxlQXV0b1N0eWxpbmdcbiAqIEBzaWduYXR1cmUgZGlzYWJsZUF1dG9TdHlsaW5nKClcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dRGlzYWJsZSBhdXRvbWF0aWMgc3R5bGluZy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqL1xub25zLmRpc2FibGVBdXRvU3R5bGluZyA9IGF1dG9TdHlsZS5kaXNhYmxlO1xuXG4vKipcbiAqIEBtZXRob2QgZW5hYmxlQXV0b1N0eWxpbmdcbiAqIEBzaWduYXR1cmUgZW5hYmxlQXV0b1N0eWxpbmcoKVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1FbmFibGUgYXV0b21hdGljIHN0eWxpbmcgYmFzZWQgb24gT1MgKGRlZmF1bHQpLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMuZW5hYmxlQXV0b1N0eWxpbmcgPSBhdXRvU3R5bGUuZW5hYmxlO1xuXG4vKipcbiAqIEBtZXRob2QgZGlzYWJsZUljb25BdXRvUHJlZml4XG4gKiBAc2lnbmF0dXJlIGRpc2FibGVJY29uQXV0b1ByZWZpeCgpXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXURpc2FibGUgYWRkaW5nIGBmYS1gIHByZWZpeCBhdXRvbWF0aWNhbGx5IHRvIGBvbnMtaWNvbmAgY2xhc3Nlcy4gVXNlZnVsIHdoZW4gaW5jbHVkaW5nIGN1c3RvbSBpY29uIHBhY2tzLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMuZGlzYWJsZUljb25BdXRvUHJlZml4ID0gKCkgPT4ge1xuICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnSWNvbicpO1xuICBlbGVtZW50cy5JY29uLnNldEF1dG9QcmVmaXgoZmFsc2UpO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIGZvcmNlVUlXZWJWaWV3U2Nyb2xsRml4XG4gKiBAc2lnbmF0dXJlIGZvcmNlVUlXZWJWaWV3U2Nyb2xsRml4KClcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yY2UgRW5hYmxlIG9yIGRpc2FibGUgdGhlIGZpeC5cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQXBwbGllcyBhIGZpeCBmb3IgaU9TIFVJV2ViVmlldyB3aGljaCBwcmV2ZW50cyBzY3JvbGwgZXZlbnRzIGp1bXBpbmcgdG8gcGFnZXMgdW5kZXIgdGhlIHRvcCBsYXllci4gVGhpcyBtYXkgdmlzdWFsbHkgYWZmZWN0IG5vcm1hbCBzY3JvbGxpbmcgb2YgVUlXZWJWaWV3IGlmIHlvdSBvcGVuIGEgZGlhbG9nL21lbnUgYmVmb3JlIHRoZSBzY3JvbGwgbW9tZW50dW0gZmluaXNoZWQuIERpc2FibGVkIGJ5IGRlZmF1bHQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKi9cbm9ucy5mb3JjZVVJV2ViVmlld1Njcm9sbEZpeCA9IChmb3JjZSA9IHRydWUpID0+IHtcbiAgaW50ZXJuYWwuY29uZmlnLmZvcmNlVUlXZWJWaWV3U2Nyb2xsRml4ID0gZm9yY2U7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgZm9yY2VQbGF0Zm9ybVN0eWxpbmdcbiAqIEBzaWduYXR1cmUgZm9yY2VQbGF0Zm9ybVN0eWxpbmcocGxhdGZvcm0pXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVJlZnJlc2ggc3R5bGluZyBmb3IgdGhlIGdpdmVuIHBsYXRmb3JtLiBPbmx5IHVzZWZ1bCBmb3IgZGVtb3MuIFVzZSBgb25zLnBsYXRmb3JtLnNlbGVjdCguLi4pYCBpbnN0ZWFkIGZvciBkZXZlbG9wbWVudCBhbmQgcHJvZHVjdGlvbi5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7c3RyaW5nfSBwbGF0Zm9ybSBOZXcgcGxhdGZvcm0gdG8gc3R5bGUgdGhlIGVsZW1lbnRzLlxuICovXG5vbnMuZm9yY2VQbGF0Zm9ybVN0eWxpbmcgPSBuZXdQbGF0Zm9ybSA9PiB7XG4gIG9ucy5lbmFibGVBdXRvU3R5bGluZygpO1xuICBvbnMucGxhdGZvcm0uc2VsZWN0KG5ld1BsYXRmb3JtIHx8ICdpb3MnKTtcblxuICBvbnMuX3V0aWwuYXJyYXlGcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyonKSlcbiAgICAuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdvbnMtaWYnKSB7XG4gICAgICAgIGVsZW1lbnQuX3BsYXRmb3JtVXBkYXRlKCk7XG4gICAgICB9IGVsc2UgaWYgKGVsZW1lbnQudGFnTmFtZS5tYXRjaCgvXm9ucy0vaSkpIHtcbiAgICAgICAgYXV0b1N0eWxlLnByZXBhcmUoZWxlbWVudCwgdHJ1ZSk7XG4gICAgICAgIGlmIChlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29ucy10YWJiYXInKSB7XG4gICAgICAgICAgZWxlbWVudC5fdXBkYXRlUG9zaXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xufTtcblxuLyoqXG4gKiBAbWV0aG9kIHByZWxvYWRcbiAqIEBzaWduYXR1cmUgcHJlbG9hZCh0ZW1wbGF0ZVBhdGhzKVxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXl9IHRlbXBsYXRlUGF0aHNcbiAqICAgW2VuXVNldCBvZiBIVE1MIGZpbGUgcGF0aHMgY29udGFpbmluZyAnb25zLXBhZ2UnIGVsZW1lbnRzLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqICAgW2VuXVByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCB0aGUgdGVtcGxhdGVzIGFyZSBjYWNoZWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNlcGFyYXRlZCBmaWxlcyBuZWVkIHRvIGJlIHJlcXVlc3RlZCBvbiBkZW1hbmQgYW5kIHRoaXMgY2FuIHNsaWdodGx5IGRlbGF5IHB1c2hpbmcgbmV3IHBhZ2VzLiBUaGlzIG1ldGhvZCByZXF1ZXN0cyBhbmQgY2FjaGVzIHRlbXBsYXRlcyBmb3IgbGF0ZXIgdXNlLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMucHJlbG9hZCA9IGZ1bmN0aW9uKHRlbXBsYXRlcyA9IFtdKSB7XG4gIHJldHVybiBQcm9taXNlLmFsbCgodGVtcGxhdGVzIGluc3RhbmNlb2YgQXJyYXkgPyB0ZW1wbGF0ZXMgOiBbdGVtcGxhdGVzXSkubWFwKHRlbXBsYXRlID0+IHtcbiAgICBpZiAodHlwZW9mIHRlbXBsYXRlICE9PSAnc3RyaW5nJykge1xuICAgICAgdXRpbC50aHJvdygnRXhwZWN0ZWQgc3RyaW5nIGFyZ3VtZW50cyBidXQgZ290ICcgKyB0eXBlb2YgdGVtcGxhdGUpO1xuICAgIH1cbiAgICByZXR1cm4gaW50ZXJuYWwuZ2V0VGVtcGxhdGVIVE1MQXN5bmModGVtcGxhdGUpO1xuICB9KSk7XG59O1xuXG4vKipcbiAqIEBtZXRob2QgY3JlYXRlRWxlbWVudFxuICogQHNpZ25hdHVyZSBjcmVhdGVFbGVtZW50KHRlbXBsYXRlLCBvcHRpb25zKVxuICogQHBhcmFtIHtTdHJpbmd9IHRlbXBsYXRlXG4gKiAgIFtlbl1FaXRoZXIgYW4gSFRNTCBmaWxlIHBhdGgsIGEgYDx0ZW1wbGF0ZT5gIGlkIG9yIGFuIEhUTUwgc3RyaW5nIHN1Y2ggYXMgYCc8ZGl2IGlkPVwiZm9vXCI+aG9nZTwvZGl2PidgLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAqIEBwYXJhbSB7Qm9vbGVhbnxIVE1MRWxlbWVudH0gW29wdGlvbnMuYXBwZW5kXVxuICogICBbZW5dV2hldGhlciBvciBub3QgdGhlIGVsZW1lbnQgc2hvdWxkIGJlIGF1dG9tYXRpY2FsbHkgYXBwZW5kZWQgdG8gdGhlIERPTS4gIERlZmF1bHRzIHRvIGBmYWxzZWAuIElmIGB0cnVlYCB2YWx1ZSBpcyBnaXZlbiwgYGRvY3VtZW50LmJvZHlgIHdpbGwgYmUgdXNlZCBhcyB0aGUgdGFyZ2V0LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gW29wdGlvbnMuaW5zZXJ0QmVmb3JlXVxuICogICBbZW5dUmVmZXJlbmNlIG5vZGUgdGhhdCBiZWNvbWVzIHRoZSBuZXh0IHNpYmxpbmcgb2YgdGhlIG5ldyBub2RlIChgb3B0aW9ucy5hcHBlbmRgIGVsZW1lbnQpLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHJldHVybiB7SFRNTEVsZW1lbnR8UHJvbWlzZX1cbiAqICAgW2VuXUlmIHRoZSBwcm92aWRlZCB0ZW1wbGF0ZSB3YXMgYW4gaW5saW5lIEhUTUwgc3RyaW5nLCBpdCByZXR1cm5zIHRoZSBuZXcgZWxlbWVudC4gT3RoZXJ3aXNlLCBpdCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBuZXcgZWxlbWVudC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQ3JlYXRlIGEgbmV3IGVsZW1lbnQgZnJvbSBhIHRlbXBsYXRlLiBCb3RoIGlubGluZSBIVE1MIGFuZCBleHRlcm5hbCBmaWxlcyBhcmUgc3VwcG9ydGVkIGFsdGhvdWdoIHRoZSByZXR1cm4gdmFsdWUgZGlmZmVycy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqL1xub25zLmNyZWF0ZUVsZW1lbnQgPSAodGVtcGxhdGUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICB0ZW1wbGF0ZSA9IHRlbXBsYXRlLnRyaW0oKTtcblxuICBjb25zdCBjcmVhdGUgPSBodG1sID0+IHtcbiAgICBjb25zdCBlbGVtZW50ID0gb25zLl91dGlsLmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgZWxlbWVudC5yZW1vdmUoKTtcblxuICAgIGlmIChvcHRpb25zLmFwcGVuZCkge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gb3B0aW9ucy5hcHBlbmQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCA/IG9wdGlvbnMuYXBwZW5kIDogZG9jdW1lbnQuYm9keTtcbiAgICAgIHRhcmdldC5pbnNlcnRCZWZvcmUoZWxlbWVudCwgb3B0aW9ucy5pbnNlcnRCZWZvcmUgfHwgbnVsbCk7XG4gICAgICBvcHRpb25zLmxpbmsgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiBvcHRpb25zLmxpbmsoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH07XG5cbiAgcmV0dXJuIHRlbXBsYXRlLmNoYXJBdCgwKSA9PT0gJzwnID8gY3JlYXRlKHRlbXBsYXRlKSA6IGludGVybmFsLmdldFBhZ2VIVE1MQXN5bmModGVtcGxhdGUpLnRoZW4oY3JlYXRlKTtcbn07XG5cbi8qKlxuICogQG1ldGhvZCBjcmVhdGVQb3BvdmVyXG4gKiBAc2lnbmF0dXJlIGNyZWF0ZVBvcG92ZXIocGFnZSwgW29wdGlvbnNdKVxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqICAgW2VuXVBhZ2UgbmFtZS4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGZpbGUgb3IgYSA8dGVtcGxhdGU+IGNvbnRhaW5pbmcgYSA8b25zLWRpYWxvZz4gY29tcG9uZW50LlsvZW5dXG4gKiAgIFtqYV1wYWdl44GuVVJM44GL44CB44KC44GX44GP44GvYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wYXJlbnRTY29wZV1cbiAqICAgW2VuXVBhcmVudCBzY29wZSBvZiB0aGUgZGlhbG9nLiBVc2VkIHRvIGJpbmQgbW9kZWxzIGFuZCBhY2Nlc3Mgc2NvcGUgbWV0aG9kcyBmcm9tIHRoZSBkaWFsb2cuWy9lbl1cbiAqICAgW2phXeODgOOCpOOCouODreOCsOWGheOBp+WIqeeUqOOBmeOCi+imquOCueOCs+ODvOODl+OCkuaMh+WumuOBl+OBvuOBmeOAguODgOOCpOOCouODreOCsOOBi+OCieODouODh+ODq+OChOOCueOCs+ODvOODl+OBruODoeOCveODg+ODieOBq+OCouOCr+OCu+OCueOBmeOCi+OBruOBq+S9v+OBhOOBvuOBmeOAguOBk+OBruODkeODqeODoeODvOOCv+OBr0FuZ3VsYXJKU+ODkOOCpOODs+ODh+OCo+ODs+OCsOOBp+OBruOBv+WIqeeUqOOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dUHJvbWlzZSBvYmplY3QgdGhhdCByZXNvbHZlcyB0byB0aGUgcG9wb3ZlciBjb21wb25lbnQgb2JqZWN0LlsvZW5dXG4gKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgpLop6PmsbrjgZnjgotQcm9taXNl44Kq44OW44K444Kn44Kv44OI44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQ3JlYXRlIGEgcG9wb3ZlciBpbnN0YW5jZSBmcm9tIGEgdGVtcGxhdGUuWy9lbl1cbiAqICAgW2phXeODhuODs+ODl+ODrOODvOODiOOBi+OCieODneODg+ODl+OCquODvOODkOODvOOBruOCpOODs+OCueOCv+ODs+OCueOCkueUn+aIkOOBl+OBvuOBmeOAglsvamFdXG4gKi9cbi8qKlxuICogQG1ldGhvZCBjcmVhdGVEaWFsb2dcbiAqIEBzaWduYXR1cmUgY3JlYXRlRGlhbG9nKHBhZ2UsIFtvcHRpb25zXSlcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYWdlXG4gKiAgIFtlbl1QYWdlIG5hbWUuIENhbiBiZSBlaXRoZXIgYW4gSFRNTCBmaWxlIG9yIGFuIGA8dGVtcGxhdGU+YCBjb250YWluaW5nIGEgPG9ucy1kaWFsb2c+IGNvbXBvbmVudC5bL2VuXVxuICogICBbamFdcGFnZeOBrlVSTOOBi+OAgeOCguOBl+OBj+OBr2A8dGVtcGxhdGU+YOOBp+Wuo+iogOOBl+OBn+ODhuODs+ODl+ODrOODvOODiOOBrmlk5bGe5oCn44Gu5YCk44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICogICBbZW5dUHJvbWlzZSBvYmplY3QgdGhhdCByZXNvbHZlcyB0byB0aGUgZGlhbG9nIGNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAqICAgW2phXeODgOOCpOOCouODreOCsOOBruOCs+ODs+ODneODvOODjeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOCkuino+axuuOBmeOCi1Byb21pc2Xjgqrjg5bjgrjjgqfjgq/jg4jjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1DcmVhdGUgYSBkaWFsb2cgaW5zdGFuY2UgZnJvbSBhIHRlbXBsYXRlLlsvZW5dXG4gKiAgIFtqYV3jg4bjg7Pjg5fjg6zjg7zjg4jjgYvjgonjg4DjgqTjgqLjg63jgrDjga7jgqTjg7Pjgrnjgr/jg7PjgrnjgpLnlJ/miJDjgZfjgb7jgZnjgIJbL2phXVxuICovXG4vKipcbiAqIEBtZXRob2QgY3JlYXRlQWxlcnREaWFsb2dcbiAqIEBzaWduYXR1cmUgY3JlYXRlQWxlcnREaWFsb2cocGFnZSwgW29wdGlvbnNdKVxuICogQHBhcmFtIHtTdHJpbmd9IHBhZ2VcbiAqICAgW2VuXVBhZ2UgbmFtZS4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGZpbGUgb3IgYW4gYDx0ZW1wbGF0ZT5gIGNvbnRhaW5pbmcgYSA8b25zLWFsZXJ0LWRpYWxvZz4gY29tcG9uZW50LlsvZW5dXG4gKiAgIFtqYV1wYWdl44GuVVJM44GL44CB44KC44GX44GP44GvYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiAgIFtlbl1Qcm9taXNlIG9iamVjdCB0aGF0IHJlc29sdmVzIHRvIHRoZSBhbGVydCBkaWFsb2cgY29tcG9uZW50IG9iamVjdC5bL2VuXVxuICogICBbamFd44OA44Kk44Ki44Ot44Kw44Gu44Kz44Oz44Od44O844ON44Oz44OI44Kq44OW44K444Kn44Kv44OI44KS6Kej5rG644GZ44KLUHJvbWlzZeOCquODluOCuOOCp+OCr+ODiOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUNyZWF0ZSBhIGFsZXJ0IGRpYWxvZyBpbnN0YW5jZSBmcm9tIGEgdGVtcGxhdGUuWy9lbl1cbiAqICAgW2phXeODhuODs+ODl+ODrOODvOODiOOBi+OCieOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBruOCpOODs+OCueOCv+ODs+OCueOCkueUn+aIkOOBl+OBvuOBmeOAglsvamFdXG4gKi9cbm9ucy5jcmVhdGVQb3BvdmVyID0gb25zLmNyZWF0ZURpYWxvZyA9IG9ucy5jcmVhdGVBbGVydERpYWxvZyA9ICh0ZW1wbGF0ZSwgb3B0aW9ucyA9IHt9KSA9PiBvbnMuY3JlYXRlRWxlbWVudCh0ZW1wbGF0ZSwgeyBhcHBlbmQ6IHRydWUsIC4uLm9wdGlvbnMgfSk7XG5cbi8qKlxuICogQG1ldGhvZCBvcGVuQWN0aW9uU2hlZXRcbiAqIEBzaWduYXR1cmUgb3BlbkFjdGlvblNoZWV0KG9wdGlvbnMpXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNob3dzIGFuIGluc3RhbnQgQWN0aW9uIFNoZWV0IGFuZCBsZXRzIHRoZSB1c2VyIGNob29zZSBhbiBhY3Rpb24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICogQHBhcmFtIHtBcnJheX0gW29wdGlvbnMuYnV0dG9uc11cbiAqICAgW2VuXVJlcHJlc2VudCBlYWNoIGJ1dHRvbiBvZiB0aGUgYWN0aW9uIHNoZWV0IGZvbGxvd2luZyB0aGUgc3BlY2lmaWVkIG9yZGVyLiBFdmVyeSBpdGVtIGNhbiBiZSBlaXRoZXIgYSBzdHJpbmcgbGFiZWwgb3IgYW4gb2JqZWN0IGNvbnRhaW5pbmcgYGxhYmVsYCwgYGljb25gIGFuZCBgbW9kaWZpZXJgIHByb3BlcnRpZXMuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMudGl0bGVdXG4gKiAgIFtlbl1PcHRpb25hbCB0aXRsZSBmb3IgdGhlIGFjdGlvbiBzaGVldC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbb3B0aW9ucy5kZXN0cnVjdGl2ZV1cbiAqICAgW2VuXU9wdGlvbmFsIGluZGV4IG9mIHRoZSBcImRlc3RydWN0aXZlXCIgYnV0dG9uIChvbmx5IGZvciBpT1MpLiBJdCBjYW4gYmUgc3BlY2lmaWVkIGluIHRoZSBidXR0b24gYXJyYXkgYXMgd2VsbC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuY2FuY2VsYWJsZV1cbiAqICAgW2VuXVdoZXRoZXIgdGhlIGFjdGlvbiBzaGVldCBjYW4gYmUgY2FuY2VsZWQgYnkgdGFwcGluZyBvbiB0aGUgYmFja2dyb3VuZCBtYXNrIG9yIG5vdC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tb2RpZmllcl1cbiAqICAgW2VuXU1vZGlmaWVyIGF0dHJpYnV0ZSBvZiB0aGUgYWN0aW9uIHNoZWV0LiBFLmcuIGAnZGVzdHJ1Y3RpdmUnYC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5tYXNrQ29sb3JdXG4gKiAgIFtlbl1PcHRpb25hbGx5IGNoYW5nZSB0aGUgYmFja2dyb3VuZCBtYXNrIGNvbG9yLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmlkXVxuICogICBbZW5dVGhlIGVsZW1lbnQncyBpZCBhdHRyaWJ1dGUuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuY2xhc3NdXG4gKiAgIFtlbl1UaGUgZWxlbWVudCdzIGNsYXNzIGF0dHJpYnV0ZS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKiAgIFtlbl1XaWxsIHJlc29sdmUgd2hlbiB0aGUgYWN0aW9uIHNoZWV0IGlzIGNsb3NlZC4gVGhlIHJlc29sdmUgdmFsdWUgaXMgZWl0aGVyIHRoZSBpbmRleCBvZiB0aGUgdGFwcGVkIGJ1dHRvbiBvciAtMSB3aGVuIGNhbmNlbGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5vbnMub3BlbkFjdGlvblNoZWV0ID0gYWN0aW9uU2hlZXQ7XG5cbi8qKlxuICogQG1ldGhvZCByZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyXG4gKiBAc2lnbmF0dXJlIHJlc29sdmVMb2FkaW5nUGxhY2Vob2xkZXIocGFnZSlcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYWdlXG4gKiAgIFtlbl1QYWdlIG5hbWUuIENhbiBiZSBlaXRoZXIgYW4gSFRNTCBmaWxlIG9yIGEgYDx0ZW1wbGF0ZT5gIGlkLlsvZW5dXG4gKiAgIFtqYV1wYWdl44GuVVJM44GL44CB44KC44GX44GP44GvYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1JZiBubyBwYWdlIGlzIGRlZmluZWQgZm9yIHRoZSBgb25zLWxvYWRpbmctcGxhY2Vob2xkZXJgIGF0dHJpYnV0ZSBpdCB3aWxsIHdhaXQgZm9yIHRoaXMgbWV0aG9kIGJlaW5nIGNhbGxlZCBiZWZvcmUgbG9hZGluZyB0aGUgcGFnZS5bL2VuXVxuICogICBbamFdb25zLWxvYWRpbmctcGxhY2Vob2xkZXLjga7lsZ7mgKflgKTjgajjgZfjgabjg5rjg7zjgrjjgYzmjIflrprjgZXjgozjgabjgYTjgarjgYTloLTlkIjjga/jgIHjg5rjg7zjgrjjg63jg7zjg4nliY3jgavlkbzjgbDjgozjgotvbnMucmVzb2x2ZUxvYWRpbmdQbGFjZWhvbGRlcuWHpueQhuOBjOihjOOCj+OCjOOCi+OBvuOBp+ihqOekuuOBleOCjOOBvuOBm+OCk+OAglsvamFdXG4gKi9cbm9ucy5yZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyID0gKHBhZ2UsIGxpbmspID0+IHtcbiAgY29uc3QgZWxlbWVudHMgPSBvbnMuX3V0aWwuYXJyYXlGcm9tKHdpbmRvdy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbb25zLWxvYWRpbmctcGxhY2Vob2xkZXJdJykpO1xuICBpZiAoZWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgdXRpbC50aHJvdygnTm8gb25zLWxvYWRpbmctcGxhY2Vob2xkZXIgZXhpc3RzJyk7XG4gIH1cblxuICBlbGVtZW50c1xuICAgIC5maWx0ZXIoZWxlbWVudCA9PiAhZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3BhZ2UnKSlcbiAgICAuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdvbnMtbG9hZGluZy1wbGFjZWhvbGRlcicsIHBhZ2UpO1xuICAgICAgb25zLl9yZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyKGVsZW1lbnQsIHBhZ2UsIGxpbmspO1xuICAgIH0pO1xufTtcblxuXG5vbnMuX3NldHVwTG9hZGluZ1BsYWNlSG9sZGVycyA9IGZ1bmN0aW9uKCkge1xuICBvbnMucmVhZHkoKCkgPT4ge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gb25zLl91dGlsLmFycmF5RnJvbSh3aW5kb3cuZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW29ucy1sb2FkaW5nLXBsYWNlaG9sZGVyXScpKTtcblxuICAgIGVsZW1lbnRzLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICBjb25zdCBwYWdlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ29ucy1sb2FkaW5nLXBsYWNlaG9sZGVyJyk7XG4gICAgICBpZiAodHlwZW9mIHBhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIG9ucy5fcmVzb2x2ZUxvYWRpbmdQbGFjZWhvbGRlcihlbGVtZW50LCBwYWdlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59O1xuXG5vbnMuX3Jlc29sdmVMb2FkaW5nUGxhY2Vob2xkZXIgPSBmdW5jdGlvbihwYXJlbnQsIHBhZ2UsIGxpbmsgPSAoKGVsLCBkb25lKSA9PiBkb25lKCkpKSB7XG4gIHBhZ2UgJiYgb25zLmNyZWF0ZUVsZW1lbnQocGFnZSlcbiAgICAudGhlbihlbGVtZW50ID0+IHtcbiAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgIGxpbmsoZWxlbWVudCwgKCkgPT4ge1xuICAgICAgICB3aGlsZSAocGFyZW50LmZpcnN0Q2hpbGQgJiYgcGFyZW50LmZpcnN0Q2hpbGQgIT09IGVsZW1lbnQpIHtcbiAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQocGFyZW50LmZpcnN0Q2hpbGQpO1xuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgfSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4gUHJvbWlzZS5yZWplY3QoJ1VuYWJsZWQgdG8gcmVzb2x2ZSBwbGFjZWhvbGRlcjogJyArIGVycm9yKSk7XG59O1xuXG5mdW5jdGlvbiB3YWl0RGV2aWNlUmVhZHkoKSB7XG4gIGNvbnN0IHVubG9ja0RldmljZVJlYWR5ID0gb25zLl9yZWFkeUxvY2subG9jaygpO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsICgpID0+IHtcbiAgICBpZiAob25zLmlzV2ViVmlldygpKSB7XG4gICAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZGV2aWNlcmVhZHknLCB1bmxvY2tEZXZpY2VSZWFkeSwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bmxvY2tEZXZpY2VSZWFkeSgpO1xuICAgIH1cbiAgfSwgZmFsc2UpO1xufVxuXG4vKipcbiAqIEBtZXRob2QgZ2V0U2NyaXB0UGFnZVxuICogQHNpZ25hdHVyZSBnZXRTY3JpcHRQYWdlKClcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQWNjZXNzIHRoZSBsYXN0IGNyZWF0ZWQgcGFnZSBmcm9tIHRoZSBjdXJyZW50IGBzY3JpcHRgIHNjb3BlLiBPbmx5IHdvcmtzIGluc2lkZSBgPHNjcmlwdD48L3NjcmlwdD5gIHRhZ3MgdGhhdCBhcmUgZGlyZWN0IGNoaWxkcmVuIG9mIGBvbnMtcGFnZWAgZWxlbWVudC4gVXNlIHRoaXMgdG8gYWRkIGxpZmVjeWNsZSBob29rcyB0byBhIHBhZ2UuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAqICAgW2VuXVJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGFnZSBlbGVtZW50LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5jb25zdCBnZXRDUyA9ICdjdXJyZW50U2NyaXB0JyBpbiBkb2N1bWVudCA/ICgpID0+IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQgOiAoKSA9PiBkb2N1bWVudC5zY3JpcHRzW2RvY3VtZW50LnNjcmlwdHMubGVuZ3RoIC0gMV07XG5vbnMuZ2V0U2NyaXB0UGFnZSA9ICgpID0+IGdldENTKCkgJiYgL29ucy1wYWdlL2kudGVzdChnZXRDUygpLnBhcmVudEVsZW1lbnQudGFnTmFtZSkgJiYgZ2V0Q1MoKS5wYXJlbnRFbGVtZW50IHx8IG51bGw7XG5cbmV4cG9ydCBkZWZhdWx0IG9ucztcbiIsIjsoZnVuY3Rpb24gKCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0LyoqXG5cdCAqIEBwcmVzZXJ2ZSBGYXN0Q2xpY2s6IHBvbHlmaWxsIHRvIHJlbW92ZSBjbGljayBkZWxheXMgb24gYnJvd3NlcnMgd2l0aCB0b3VjaCBVSXMuXG5cdCAqXG5cdCAqIEBjb2RpbmdzdGFuZGFyZCBmdGxhYnMtanN2MlxuXHQgKiBAY29weXJpZ2h0IFRoZSBGaW5hbmNpYWwgVGltZXMgTGltaXRlZCBbQWxsIFJpZ2h0cyBSZXNlcnZlZF1cblx0ICogQGxpY2Vuc2UgTUlUIExpY2Vuc2UgKHNlZSBMSUNFTlNFLnR4dClcblx0ICovXG5cblx0Lypqc2xpbnQgYnJvd3Nlcjp0cnVlLCBub2RlOnRydWUqL1xuXHQvKmdsb2JhbCBkZWZpbmUsIEV2ZW50LCBOb2RlKi9cblxuXG5cdC8qKlxuXHQgKiBJbnN0YW50aWF0ZSBmYXN0LWNsaWNraW5nIGxpc3RlbmVycyBvbiB0aGUgc3BlY2lmaWVkIGxheWVyLlxuXHQgKlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHtFbGVtZW50fSBsYXllciBUaGUgbGF5ZXIgdG8gbGlzdGVuIG9uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHRzXG5cdCAqL1xuXHRmdW5jdGlvbiBGYXN0Q2xpY2sobGF5ZXIsIG9wdGlvbnMpIHtcblx0XHR2YXIgb2xkT25DbGljaztcblxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cdFx0LyoqXG5cdFx0ICogV2hldGhlciBhIGNsaWNrIGlzIGN1cnJlbnRseSBiZWluZyB0cmFja2VkLlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgYm9vbGVhblxuXHRcdCAqL1xuXHRcdHRoaXMudHJhY2tpbmdDbGljayA9IGZhbHNlO1xuXG5cblx0XHQvKipcblx0XHQgKiBUaW1lc3RhbXAgZm9yIHdoZW4gY2xpY2sgdHJhY2tpbmcgc3RhcnRlZC5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMudHJhY2tpbmdDbGlja1N0YXJ0ID0gMDtcblxuXG5cdFx0LyoqXG5cdFx0ICogVGhlIGVsZW1lbnQgYmVpbmcgdHJhY2tlZCBmb3IgYSBjbGljay5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIEV2ZW50VGFyZ2V0XG5cdFx0ICovXG5cdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblxuXG5cdFx0LyoqXG5cdFx0ICogWC1jb29yZGluYXRlIG9mIHRvdWNoIHN0YXJ0IGV2ZW50LlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy50b3VjaFN0YXJ0WCA9IDA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFktY29vcmRpbmF0ZSBvZiB0b3VjaCBzdGFydCBldmVudC5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMudG91Y2hTdGFydFkgPSAwO1xuXG5cblx0XHQvKipcblx0XHQgKiBJRCBvZiB0aGUgbGFzdCB0b3VjaCwgcmV0cmlldmVkIGZyb20gVG91Y2guaWRlbnRpZmllci5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMubGFzdFRvdWNoSWRlbnRpZmllciA9IDA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFRvdWNobW92ZSBib3VuZGFyeSwgYmV5b25kIHdoaWNoIGEgY2xpY2sgd2lsbCBiZSBjYW5jZWxsZWQuXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBudW1iZXJcblx0XHQgKi9cblx0XHR0aGlzLnRvdWNoQm91bmRhcnkgPSBvcHRpb25zLnRvdWNoQm91bmRhcnkgfHwgMTA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBGYXN0Q2xpY2sgbGF5ZXIuXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBFbGVtZW50XG5cdFx0ICovXG5cdFx0dGhpcy5sYXllciA9IGxheWVyO1xuXG5cdFx0LyoqXG5cdFx0ICogVGhlIG1pbmltdW0gdGltZSBiZXR3ZWVuIHRhcCh0b3VjaHN0YXJ0IGFuZCB0b3VjaGVuZCkgZXZlbnRzXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBudW1iZXJcblx0XHQgKi9cblx0XHR0aGlzLnRhcERlbGF5ID0gb3B0aW9ucy50YXBEZWxheSB8fCAyMDA7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgbWF4aW11bSB0aW1lIGZvciBhIHRhcFxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy50YXBUaW1lb3V0ID0gb3B0aW9ucy50YXBUaW1lb3V0IHx8IDcwMDtcblxuXHRcdGlmIChGYXN0Q2xpY2subm90TmVlZGVkKGxheWVyKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFNvbWUgb2xkIHZlcnNpb25zIG9mIEFuZHJvaWQgZG9uJ3QgaGF2ZSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZFxuXHRcdGZ1bmN0aW9uIGJpbmQobWV0aG9kLCBjb250ZXh0KSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBtZXRob2QuYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTsgfTtcblx0XHR9XG5cblxuXHRcdHZhciBtZXRob2RzID0gWydvbk1vdXNlJywgJ29uQ2xpY2snLCAnb25Ub3VjaFN0YXJ0JywgJ29uVG91Y2hNb3ZlJywgJ29uVG91Y2hFbmQnLCAnb25Ub3VjaENhbmNlbCddO1xuXHRcdHZhciBjb250ZXh0ID0gdGhpcztcblx0XHRmb3IgKHZhciBpID0gMCwgbCA9IG1ldGhvZHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRjb250ZXh0W21ldGhvZHNbaV1dID0gYmluZChjb250ZXh0W21ldGhvZHNbaV1dLCBjb250ZXh0KTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdXAgZXZlbnQgaGFuZGxlcnMgYXMgcmVxdWlyZWRcblx0XHRpZiAoZGV2aWNlSXNBbmRyb2lkKSB7XG5cdFx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdH1cblxuXHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrLCB0cnVlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5vblRvdWNoU3RhcnQsIGZhbHNlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlLCBmYWxzZSk7XG5cdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLm9uVG91Y2hFbmQsIGZhbHNlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMub25Ub3VjaENhbmNlbCwgZmFsc2UpO1xuXG5cdFx0Ly8gSGFjayBpcyByZXF1aXJlZCBmb3IgYnJvd3NlcnMgdGhhdCBkb24ndCBzdXBwb3J0IEV2ZW50I3N0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiAoZS5nLiBBbmRyb2lkIDIpXG5cdFx0Ly8gd2hpY2ggaXMgaG93IEZhc3RDbGljayBub3JtYWxseSBzdG9wcyBjbGljayBldmVudHMgYnViYmxpbmcgdG8gY2FsbGJhY2tzIHJlZ2lzdGVyZWQgb24gdGhlIEZhc3RDbGlja1xuXHRcdC8vIGxheWVyIHdoZW4gdGhleSBhcmUgY2FuY2VsbGVkLlxuXHRcdGlmICghRXZlbnQucHJvdG90eXBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbikge1xuXHRcdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGNhbGxiYWNrLCBjYXB0dXJlKSB7XG5cdFx0XHRcdHZhciBybXYgPSBOb2RlLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyO1xuXHRcdFx0XHRpZiAodHlwZSA9PT0gJ2NsaWNrJykge1xuXHRcdFx0XHRcdHJtdi5jYWxsKGxheWVyLCB0eXBlLCBjYWxsYmFjay5oaWphY2tlZCB8fCBjYWxsYmFjaywgY2FwdHVyZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cm12LmNhbGwobGF5ZXIsIHR5cGUsIGNhbGxiYWNrLCBjYXB0dXJlKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGNhbGxiYWNrLCBjYXB0dXJlKSB7XG5cdFx0XHRcdHZhciBhZHYgPSBOb2RlLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyO1xuXHRcdFx0XHRpZiAodHlwZSA9PT0gJ2NsaWNrJykge1xuXHRcdFx0XHRcdGFkdi5jYWxsKGxheWVyLCB0eXBlLCBjYWxsYmFjay5oaWphY2tlZCB8fCAoY2FsbGJhY2suaGlqYWNrZWQgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdFx0XHRcdFx0aWYgKCFldmVudC5wcm9wYWdhdGlvblN0b3BwZWQpIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soZXZlbnQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pLCBjYXB0dXJlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRhZHYuY2FsbChsYXllciwgdHlwZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIElmIGEgaGFuZGxlciBpcyBhbHJlYWR5IGRlY2xhcmVkIGluIHRoZSBlbGVtZW50J3Mgb25jbGljayBhdHRyaWJ1dGUsIGl0IHdpbGwgYmUgZmlyZWQgYmVmb3JlXG5cdFx0Ly8gRmFzdENsaWNrJ3Mgb25DbGljayBoYW5kbGVyLiBGaXggdGhpcyBieSBwdWxsaW5nIG91dCB0aGUgdXNlci1kZWZpbmVkIGhhbmRsZXIgZnVuY3Rpb24gYW5kXG5cdFx0Ly8gYWRkaW5nIGl0IGFzIGxpc3RlbmVyLlxuXHRcdGlmICh0eXBlb2YgbGF5ZXIub25jbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuXG5cdFx0XHQvLyBBbmRyb2lkIGJyb3dzZXIgb24gYXQgbGVhc3QgMy4yIHJlcXVpcmVzIGEgbmV3IHJlZmVyZW5jZSB0byB0aGUgZnVuY3Rpb24gaW4gbGF5ZXIub25jbGlja1xuXHRcdFx0Ly8gLSB0aGUgb2xkIG9uZSB3b24ndCB3b3JrIGlmIHBhc3NlZCB0byBhZGRFdmVudExpc3RlbmVyIGRpcmVjdGx5LlxuXHRcdFx0b2xkT25DbGljayA9IGxheWVyLm9uY2xpY2s7XG5cdFx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdG9sZE9uQ2xpY2soZXZlbnQpO1xuXHRcdFx0fSwgZmFsc2UpO1xuXHRcdFx0bGF5ZXIub25jbGljayA9IG51bGw7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCogV2luZG93cyBQaG9uZSA4LjEgZmFrZXMgdXNlciBhZ2VudCBzdHJpbmcgdG8gbG9vayBsaWtlIEFuZHJvaWQgYW5kIGlQaG9uZS5cblx0KlxuXHQqIEB0eXBlIGJvb2xlYW5cblx0Ki9cblx0dmFyIGRldmljZUlzV2luZG93c1Bob25lID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKFwiV2luZG93cyBQaG9uZVwiKSA+PSAwO1xuXG5cdC8qKlxuXHQgKiBBbmRyb2lkIHJlcXVpcmVzIGV4Y2VwdGlvbnMuXG5cdCAqXG5cdCAqIEB0eXBlIGJvb2xlYW5cblx0ICovXG5cdHZhciBkZXZpY2VJc0FuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0FuZHJvaWQnKSA+IDAgJiYgIWRldmljZUlzV2luZG93c1Bob25lO1xuXG5cblx0LyoqXG5cdCAqIGlPUyByZXF1aXJlcyBleGNlcHRpb25zLlxuXHQgKlxuXHQgKiBAdHlwZSBib29sZWFuXG5cdCAqL1xuXHR2YXIgZGV2aWNlSXNJT1MgPSAvaVAoYWR8aG9uZXxvZCkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIWRldmljZUlzV2luZG93c1Bob25lO1xuXG5cblx0LyoqXG5cdCAqIGlPUyA0IHJlcXVpcmVzIGFuIGV4Y2VwdGlvbiBmb3Igc2VsZWN0IGVsZW1lbnRzLlxuXHQgKlxuXHQgKiBAdHlwZSBib29sZWFuXG5cdCAqL1xuXHR2YXIgZGV2aWNlSXNJT1M0ID0gZGV2aWNlSXNJT1MgJiYgKC9PUyA0X1xcZChfXFxkKT8vKS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG5cblx0LyoqXG5cdCAqIGlPUyA2LjAtNy4qIHJlcXVpcmVzIHRoZSB0YXJnZXQgZWxlbWVudCB0byBiZSBtYW51YWxseSBkZXJpdmVkXG5cdCAqXG5cdCAqIEB0eXBlIGJvb2xlYW5cblx0ICovXG5cdHZhciBkZXZpY2VJc0lPU1dpdGhCYWRUYXJnZXQgPSBkZXZpY2VJc0lPUyAmJiAoL09TIFs2LTddX1xcZC8pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cblx0LyoqXG5cdCAqIEJsYWNrQmVycnkgcmVxdWlyZXMgZXhjZXB0aW9ucy5cblx0ICpcblx0ICogQHR5cGUgYm9vbGVhblxuXHQgKi9cblx0dmFyIGRldmljZUlzQmxhY2tCZXJyeTEwID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdCQjEwJykgPiAwO1xuXG5cdC8qKlxuXHQgKiBWYWxpZCB0eXBlcyBmb3IgdGV4dCBpbnB1dHNcblx0ICpcblx0ICogQHR5cGUgYXJyYXlcblx0ICovXG5cdHZhciB0ZXh0RmllbGRzID0gWydlbWFpbCcsICdudW1iZXInLCAncGFzc3dvcmQnLCAnc2VhcmNoJywgJ3RlbCcsICd0ZXh0JywgJ3VybCddO1xuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmUgd2hldGhlciBhIGdpdmVuIGVsZW1lbnQgcmVxdWlyZXMgYSBuYXRpdmUgY2xpY2suXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8RWxlbWVudH0gdGFyZ2V0IFRhcmdldCBET00gZWxlbWVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBlbGVtZW50IG5lZWRzIGEgbmF0aXZlIGNsaWNrXG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm5lZWRzQ2xpY2sgPSBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHRzd2l0Y2ggKHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSB7XG5cblx0XHQvLyBEb24ndCBzZW5kIGEgc3ludGhldGljIGNsaWNrIHRvIGRpc2FibGVkIGlucHV0cyAoaXNzdWUgIzYyKVxuXHRcdGNhc2UgJ2J1dHRvbic6XG5cdFx0Y2FzZSAnc2VsZWN0Jzpcblx0XHRjYXNlICd0ZXh0YXJlYSc6XG5cdFx0XHRpZiAodGFyZ2V0LmRpc2FibGVkKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdpbnB1dCc6XG5cblx0XHRcdC8vIEZpbGUgaW5wdXRzIG5lZWQgcmVhbCBjbGlja3Mgb24gaU9TIDYgZHVlIHRvIGEgYnJvd3NlciBidWcgKGlzc3VlICM2OClcblx0XHRcdGlmICgoZGV2aWNlSXNJT1MgJiYgdGFyZ2V0LnR5cGUgPT09ICdmaWxlJykgfHwgdGFyZ2V0LmRpc2FibGVkKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRicmVhaztcblx0XHRjYXNlICdsYWJlbCc6XG5cdFx0Y2FzZSAnaWZyYW1lJzogLy8gaU9TOCBob21lc2NyZWVuIGFwcHMgY2FuIHByZXZlbnQgZXZlbnRzIGJ1YmJsaW5nIGludG8gZnJhbWVzXG5cdFx0Y2FzZSAndmlkZW8nOlxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICgvXFxibmVlZHNjbGlja1xcYi8pLnRlc3QodGFyZ2V0LmNsYXNzTmFtZSk7XG5cdH07XG5cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lIHdoZXRoZXIgYSBnaXZlbiBlbGVtZW50IHJlcXVpcmVzIGEgY2FsbCB0byBmb2N1cyB0byBzaW11bGF0ZSBjbGljayBpbnRvIGVsZW1lbnQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8RWxlbWVudH0gdGFyZ2V0IFRhcmdldCBET00gZWxlbWVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBlbGVtZW50IHJlcXVpcmVzIGEgY2FsbCB0byBmb2N1cyB0byBzaW11bGF0ZSBuYXRpdmUgY2xpY2suXG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm5lZWRzRm9jdXMgPSBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHRzd2l0Y2ggKHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSB7XG5cdFx0Y2FzZSAndGV4dGFyZWEnOlxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0Y2FzZSAnc2VsZWN0Jzpcblx0XHRcdHJldHVybiAhZGV2aWNlSXNBbmRyb2lkO1xuXHRcdGNhc2UgJ2lucHV0Jzpcblx0XHRcdHN3aXRjaCAodGFyZ2V0LnR5cGUpIHtcblx0XHRcdGNhc2UgJ2J1dHRvbic6XG5cdFx0XHRjYXNlICdjaGVja2JveCc6XG5cdFx0XHRjYXNlICdmaWxlJzpcblx0XHRcdGNhc2UgJ2ltYWdlJzpcblx0XHRcdGNhc2UgJ3JhZGlvJzpcblx0XHRcdGNhc2UgJ3N1Ym1pdCc6XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTm8gcG9pbnQgaW4gYXR0ZW1wdGluZyB0byBmb2N1cyBkaXNhYmxlZCBpbnB1dHNcblx0XHRcdHJldHVybiAhdGFyZ2V0LmRpc2FibGVkICYmICF0YXJnZXQucmVhZE9ubHk7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHJldHVybiAoL1xcYm5lZWRzZm9jdXNcXGIvKS50ZXN0KHRhcmdldC5jbGFzc05hbWUpO1xuXHRcdH1cblx0fTtcblxuXG5cdC8qKlxuXHQgKiBTZW5kIGEgY2xpY2sgZXZlbnQgdG8gdGhlIHNwZWNpZmllZCBlbGVtZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fEVsZW1lbnR9IHRhcmdldEVsZW1lbnRcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUuc2VuZENsaWNrID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCwgZXZlbnQpIHtcblx0XHR2YXIgY2xpY2tFdmVudCwgdG91Y2g7XG5cblx0XHQvLyBPbiBzb21lIEFuZHJvaWQgZGV2aWNlcyBhY3RpdmVFbGVtZW50IG5lZWRzIHRvIGJlIGJsdXJyZWQgb3RoZXJ3aXNlIHRoZSBzeW50aGV0aWMgY2xpY2sgd2lsbCBoYXZlIG5vIGVmZmVjdCAoIzI0KVxuXHRcdGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgIT09IHRhcmdldEVsZW1lbnQpIHtcblx0XHRcdGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuYmx1cigpO1xuXHRcdH1cblxuXHRcdHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG5cblx0XHQvLyBTeW50aGVzaXNlIGEgY2xpY2sgZXZlbnQsIHdpdGggYW4gZXh0cmEgYXR0cmlidXRlIHNvIGl0IGNhbiBiZSB0cmFja2VkXG5cdFx0Y2xpY2tFdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50cycpO1xuXHRcdGNsaWNrRXZlbnQuaW5pdE1vdXNlRXZlbnQodGhpcy5kZXRlcm1pbmVFdmVudFR5cGUodGFyZ2V0RWxlbWVudCksIHRydWUsIHRydWUsIHdpbmRvdywgMSwgdG91Y2guc2NyZWVuWCwgdG91Y2guc2NyZWVuWSwgdG91Y2guY2xpZW50WCwgdG91Y2guY2xpZW50WSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIDAsIG51bGwpO1xuXHRcdGNsaWNrRXZlbnQuZm9yd2FyZGVkVG91Y2hFdmVudCA9IHRydWU7XG5cdFx0dGFyZ2V0RWxlbWVudC5kaXNwYXRjaEV2ZW50KGNsaWNrRXZlbnQpO1xuXHR9O1xuXG5cdEZhc3RDbGljay5wcm90b3R5cGUuZGV0ZXJtaW5lRXZlbnRUeXBlID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXG5cdFx0Ly9Jc3N1ZSAjMTU5OiBBbmRyb2lkIENocm9tZSBTZWxlY3QgQm94IGRvZXMgbm90IG9wZW4gd2l0aCBhIHN5bnRoZXRpYyBjbGljayBldmVudFxuXHRcdGlmIChkZXZpY2VJc0FuZHJvaWQgJiYgdGFyZ2V0RWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdzZWxlY3QnKSB7XG5cdFx0XHRyZXR1cm4gJ21vdXNlZG93bic7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICdjbGljayc7XG5cdH07XG5cblxuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldHxFbGVtZW50fSB0YXJnZXRFbGVtZW50XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmZvY3VzID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXHRcdHZhciBsZW5ndGg7XG5cblx0XHQvLyBJc3N1ZSAjMTYwOiBvbiBpT1MgNywgc29tZSBpbnB1dCBlbGVtZW50cyAoZS5nLiBkYXRlIGRhdGV0aW1lIG1vbnRoKSB0aHJvdyBhIHZhZ3VlIFR5cGVFcnJvciBvbiBzZXRTZWxlY3Rpb25SYW5nZS4gVGhlc2UgZWxlbWVudHMgZG9uJ3QgaGF2ZSBhbiBpbnRlZ2VyIHZhbHVlIGZvciB0aGUgc2VsZWN0aW9uU3RhcnQgYW5kIHNlbGVjdGlvbkVuZCBwcm9wZXJ0aWVzLCBidXQgdW5mb3J0dW5hdGVseSB0aGF0IGNhbid0IGJlIHVzZWQgZm9yIGRldGVjdGlvbiBiZWNhdXNlIGFjY2Vzc2luZyB0aGUgcHJvcGVydGllcyBhbHNvIHRocm93cyBhIFR5cGVFcnJvci4gSnVzdCBjaGVjayB0aGUgdHlwZSBpbnN0ZWFkLiBGaWxlZCBhcyBBcHBsZSBidWcgIzE1MTIyNzI0LlxuXHRcdGlmIChkZXZpY2VJc0lPUyAmJiB0YXJnZXRFbGVtZW50LnNldFNlbGVjdGlvblJhbmdlICYmIHRhcmdldEVsZW1lbnQudHlwZS5pbmRleE9mKCdkYXRlJykgIT09IDAgJiYgdGFyZ2V0RWxlbWVudC50eXBlICE9PSAndGltZScgJiYgdGFyZ2V0RWxlbWVudC50eXBlICE9PSAnbW9udGgnICYmIHRhcmdldEVsZW1lbnQudHlwZSAhPT0gJ2VtYWlsJyAmJiB0YXJnZXRFbGVtZW50LnR5cGUgIT09ICdudW1iZXInKSB7XG5cdFx0XHRsZW5ndGggPSB0YXJnZXRFbGVtZW50LnZhbHVlLmxlbmd0aDtcblx0XHRcdHRhcmdldEVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobGVuZ3RoLCBsZW5ndGgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0YXJnZXRFbGVtZW50LmZvY3VzKCk7XG5cdFx0fVxuXHR9O1xuXG5cblx0LyoqXG5cdCAqIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIHRhcmdldCBlbGVtZW50IGlzIGEgY2hpbGQgb2YgYSBzY3JvbGxhYmxlIGxheWVyIGFuZCBpZiBzbywgc2V0IGEgZmxhZyBvbiBpdC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldHxFbGVtZW50fSB0YXJnZXRFbGVtZW50XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLnVwZGF0ZVNjcm9sbFBhcmVudCA9IGZ1bmN0aW9uKHRhcmdldEVsZW1lbnQpIHtcblx0XHR2YXIgc2Nyb2xsUGFyZW50LCBwYXJlbnRFbGVtZW50O1xuXG5cdFx0c2Nyb2xsUGFyZW50ID0gdGFyZ2V0RWxlbWVudC5mYXN0Q2xpY2tTY3JvbGxQYXJlbnQ7XG5cblx0XHQvLyBBdHRlbXB0IHRvIGRpc2NvdmVyIHdoZXRoZXIgdGhlIHRhcmdldCBlbGVtZW50IGlzIGNvbnRhaW5lZCB3aXRoaW4gYSBzY3JvbGxhYmxlIGxheWVyLiBSZS1jaGVjayBpZiB0aGVcblx0XHQvLyB0YXJnZXQgZWxlbWVudCB3YXMgbW92ZWQgdG8gYW5vdGhlciBwYXJlbnQuXG5cdFx0aWYgKCFzY3JvbGxQYXJlbnQgfHwgIXNjcm9sbFBhcmVudC5jb250YWlucyh0YXJnZXRFbGVtZW50KSkge1xuXHRcdFx0cGFyZW50RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdGlmIChwYXJlbnRFbGVtZW50LnNjcm9sbEhlaWdodCA+IHBhcmVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0KSB7XG5cdFx0XHRcdFx0c2Nyb2xsUGFyZW50ID0gcGFyZW50RWxlbWVudDtcblx0XHRcdFx0XHR0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudCA9IHBhcmVudEVsZW1lbnQ7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRwYXJlbnRFbGVtZW50ID0gcGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50O1xuXHRcdFx0fSB3aGlsZSAocGFyZW50RWxlbWVudCk7XG5cdFx0fVxuXG5cdFx0Ly8gQWx3YXlzIHVwZGF0ZSB0aGUgc2Nyb2xsIHRvcCB0cmFja2VyIGlmIHBvc3NpYmxlLlxuXHRcdGlmIChzY3JvbGxQYXJlbnQpIHtcblx0XHRcdHNjcm9sbFBhcmVudC5mYXN0Q2xpY2tMYXN0U2Nyb2xsVG9wID0gc2Nyb2xsUGFyZW50LnNjcm9sbFRvcDtcblx0XHR9XG5cdH07XG5cblxuXHQvKipcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldH0gdGFyZ2V0RWxlbWVudFxuXHQgKiBAcmV0dXJucyB7RWxlbWVudHxFdmVudFRhcmdldH1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldCA9IGZ1bmN0aW9uKGV2ZW50VGFyZ2V0KSB7XG5cblx0XHQvLyBPbiBzb21lIG9sZGVyIGJyb3dzZXJzIChub3RhYmx5IFNhZmFyaSBvbiBpT1MgNC4xIC0gc2VlIGlzc3VlICM1NikgdGhlIGV2ZW50IHRhcmdldCBtYXkgYmUgYSB0ZXh0IG5vZGUuXG5cdFx0aWYgKGV2ZW50VGFyZ2V0Lm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuXHRcdFx0cmV0dXJuIGV2ZW50VGFyZ2V0LnBhcmVudE5vZGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50VGFyZ2V0O1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR9IHRhcmdldEVsZW1lbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmlzVGV4dEZpZWxkID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHR0YXJnZXRFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3RleHRhcmVhJ1xuXHRcdFx0fHwgdGV4dEZpZWxkcy5pbmRleE9mKHRhcmdldEVsZW1lbnQudHlwZSkgIT09IC0xXG5cdFx0KTtcblx0fTtcblxuXHQvKipcblx0ICogT24gdG91Y2ggc3RhcnQsIHJlY29yZCB0aGUgcG9zaXRpb24gYW5kIHNjcm9sbCBvZmZzZXQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5vblRvdWNoU3RhcnQgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciB0YXJnZXRFbGVtZW50LCB0b3VjaCwgc2VsZWN0aW9uO1xuXG5cdFx0Ly8gSWdub3JlIG11bHRpcGxlIHRvdWNoZXMsIG90aGVyd2lzZSBwaW5jaC10by16b29tIGlzIHByZXZlbnRlZCBpZiBib3RoIGZpbmdlcnMgYXJlIG9uIHRoZSBGYXN0Q2xpY2sgZWxlbWVudCAoaXNzdWUgIzExMSkuXG5cdFx0aWYgKGV2ZW50LnRhcmdldFRvdWNoZXMubGVuZ3RoID4gMSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0RWxlbWVudCA9IHRoaXMuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldChldmVudC50YXJnZXQpO1xuXHRcdHRvdWNoID0gZXZlbnQudGFyZ2V0VG91Y2hlc1swXTtcblxuXHRcdC8vIElnbm9yZSB0b3VjaGVzIG9uIGNvbnRlbnRlZGl0YWJsZSBlbGVtZW50cyB0byBwcmV2ZW50IGNvbmZsaWN0IHdpdGggdGV4dCBzZWxlY3Rpb24uXG5cdFx0Ly8gKEZvciBkZXRhaWxzOiBodHRwczovL2dpdGh1Yi5jb20vZnRsYWJzL2Zhc3RjbGljay9wdWxsLzIxMSApXG5cdFx0aWYgKHRhcmdldEVsZW1lbnQuaXNDb250ZW50RWRpdGFibGUpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdGlmIChkZXZpY2VJc0lPUykge1xuXHRcdFx0Ly8gSWdub3JlIHRvdWNoc3RhcnQgaW4gZm9jdXNlZCB0ZXh0IGZpZWxkXG5cdFx0XHQvLyBBbGxvd3Mgbm9ybWFsIHRleHQgc2VsZWN0aW9uIGFuZCBjb21tYW5kcyAoc2VsZWN0L3Bhc3RlL2N1dCkgd2hlbiBhIGZpZWxkIGhhcyBmb2N1cywgd2hpbGUgc3RpbGwgYWxsb3dpbmcgZmFzdCB0YXAtdG8tZm9jdXMuXG5cdFx0XHQvLyBXaXRob3V0IHRoaXMgZml4LCB1c2VyIG5lZWRzIHRvIHRhcC1hbmQtaG9sZCBhIHRleHQgZmllbGQgZm9yIGNvbnRleHQgbWVudSwgYW5kIGRvdWJsZS10YXAgdG8gc2VsZWN0IHRleHQgZG9lc24ndCB3b3JrIGF0IGFsbC5cblx0XHRcdGlmICh0YXJnZXRFbGVtZW50ID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIHRoaXMuaXNUZXh0RmllbGQodGFyZ2V0RWxlbWVudCkpIHtcblx0XHRcdCAgcmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmICghZGV2aWNlSXNJT1M0KSB7XG5cblx0XHRcdFx0Ly8gV2VpcmQgdGhpbmdzIGhhcHBlbiBvbiBpT1Mgd2hlbiBhbiBhbGVydCBvciBjb25maXJtIGRpYWxvZyBpcyBvcGVuZWQgZnJvbSBhIGNsaWNrIGV2ZW50IGNhbGxiYWNrIChpc3N1ZSAjMjMpOlxuXHRcdFx0XHQvLyB3aGVuIHRoZSB1c2VyIG5leHQgdGFwcyBhbnl3aGVyZSBlbHNlIG9uIHRoZSBwYWdlLCBuZXcgdG91Y2hzdGFydCBhbmQgdG91Y2hlbmQgZXZlbnRzIGFyZSBkaXNwYXRjaGVkXG5cdFx0XHRcdC8vIHdpdGggdGhlIHNhbWUgaWRlbnRpZmllciBhcyB0aGUgdG91Y2ggZXZlbnQgdGhhdCBwcmV2aW91c2x5IHRyaWdnZXJlZCB0aGUgY2xpY2sgdGhhdCB0cmlnZ2VyZWQgdGhlIGFsZXJ0LlxuXHRcdFx0XHQvLyBTYWRseSwgdGhlcmUgaXMgYW4gaXNzdWUgb24gaU9TIDQgdGhhdCBjYXVzZXMgc29tZSBub3JtYWwgdG91Y2ggZXZlbnRzIHRvIGhhdmUgdGhlIHNhbWUgaWRlbnRpZmllciBhcyBhblxuXHRcdFx0XHQvLyBpbW1lZGlhdGVseSBwcmVjZWVkaW5nIHRvdWNoIGV2ZW50IChpc3N1ZSAjNTIpLCBzbyB0aGlzIGZpeCBpcyB1bmF2YWlsYWJsZSBvbiB0aGF0IHBsYXRmb3JtLlxuXHRcdFx0XHQvLyBJc3N1ZSAxMjA6IHRvdWNoLmlkZW50aWZpZXIgaXMgMCB3aGVuIENocm9tZSBkZXYgdG9vbHMgJ0VtdWxhdGUgdG91Y2ggZXZlbnRzJyBpcyBzZXQgd2l0aCBhbiBpT1MgZGV2aWNlIFVBIHN0cmluZyxcblx0XHRcdFx0Ly8gd2hpY2ggY2F1c2VzIGFsbCB0b3VjaCBldmVudHMgdG8gYmUgaWdub3JlZC4gQXMgdGhpcyBibG9jayBvbmx5IGFwcGxpZXMgdG8gaU9TLCBhbmQgaU9TIGlkZW50aWZpZXJzIGFyZSBhbHdheXMgbG9uZyxcblx0XHRcdFx0Ly8gcmFuZG9tIGludGVnZXJzLCBpdCdzIHNhZmUgdG8gdG8gY29udGludWUgaWYgdGhlIGlkZW50aWZpZXIgaXMgMCBoZXJlLlxuXHRcdFx0XHRpZiAodG91Y2guaWRlbnRpZmllciAmJiB0b3VjaC5pZGVudGlmaWVyID09PSB0aGlzLmxhc3RUb3VjaElkZW50aWZpZXIpIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMubGFzdFRvdWNoSWRlbnRpZmllciA9IHRvdWNoLmlkZW50aWZpZXI7XG5cblx0XHRcdFx0Ly8gSWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGEgY2hpbGQgb2YgYSBzY3JvbGxhYmxlIGxheWVyICh1c2luZyAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2gpIGFuZDpcblx0XHRcdFx0Ly8gMSkgdGhlIHVzZXIgZG9lcyBhIGZsaW5nIHNjcm9sbCBvbiB0aGUgc2Nyb2xsYWJsZSBsYXllclxuXHRcdFx0XHQvLyAyKSB0aGUgdXNlciBzdG9wcyB0aGUgZmxpbmcgc2Nyb2xsIHdpdGggYW5vdGhlciB0YXBcblx0XHRcdFx0Ly8gdGhlbiB0aGUgZXZlbnQudGFyZ2V0IG9mIHRoZSBsYXN0ICd0b3VjaGVuZCcgZXZlbnQgd2lsbCBiZSB0aGUgZWxlbWVudCB0aGF0IHdhcyB1bmRlciB0aGUgdXNlcidzIGZpbmdlclxuXHRcdFx0XHQvLyB3aGVuIHRoZSBmbGluZyBzY3JvbGwgd2FzIHN0YXJ0ZWQsIGNhdXNpbmcgRmFzdENsaWNrIHRvIHNlbmQgYSBjbGljayBldmVudCB0byB0aGF0IGxheWVyIC0gdW5sZXNzIGEgY2hlY2tcblx0XHRcdFx0Ly8gaXMgbWFkZSB0byBlbnN1cmUgdGhhdCBhIHBhcmVudCBsYXllciB3YXMgbm90IHNjcm9sbGVkIGJlZm9yZSBzZW5kaW5nIGEgc3ludGhldGljIGNsaWNrIChpc3N1ZSAjNDIpLlxuXHRcdFx0XHR0aGlzLnVwZGF0ZVNjcm9sbFBhcmVudCh0YXJnZXRFbGVtZW50KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLnRyYWNraW5nQ2xpY2sgPSB0cnVlO1xuXHRcdHRoaXMudHJhY2tpbmdDbGlja1N0YXJ0ID0gZXZlbnQudGltZVN0YW1wO1xuXHRcdHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdldEVsZW1lbnQ7XG5cblx0XHR0aGlzLnRvdWNoU3RhcnRYID0gdG91Y2gucGFnZVg7XG5cdFx0dGhpcy50b3VjaFN0YXJ0WSA9IHRvdWNoLnBhZ2VZO1xuXG5cdFx0Ly8gUHJldmVudCBwaGFudG9tIGNsaWNrcyBvbiBmYXN0IGRvdWJsZS10YXAgKGlzc3VlICMzNilcblx0XHRpZiAoKGV2ZW50LnRpbWVTdGFtcCAtIHRoaXMubGFzdENsaWNrVGltZSkgPCB0aGlzLnRhcERlbGF5ICYmIChldmVudC50aW1lU3RhbXAgLSB0aGlzLmxhc3RDbGlja1RpbWUpID4gLTEpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH07XG5cblxuXHQvKipcblx0ICogQmFzZWQgb24gYSB0b3VjaG1vdmUgZXZlbnQgb2JqZWN0LCBjaGVjayB3aGV0aGVyIHRoZSB0b3VjaCBoYXMgbW92ZWQgcGFzdCBhIGJvdW5kYXJ5IHNpbmNlIGl0IHN0YXJ0ZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS50b3VjaEhhc01vdmVkID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgdG91Y2ggPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSwgYm91bmRhcnkgPSB0aGlzLnRvdWNoQm91bmRhcnk7XG5cblx0XHRpZiAoTWF0aC5hYnModG91Y2gucGFnZVggLSB0aGlzLnRvdWNoU3RhcnRYKSA+IGJvdW5kYXJ5IHx8IE1hdGguYWJzKHRvdWNoLnBhZ2VZIC0gdGhpcy50b3VjaFN0YXJ0WSkgPiBib3VuZGFyeSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIFVwZGF0ZSB0aGUgbGFzdCBwb3NpdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uVG91Y2hNb3ZlID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMudHJhY2tpbmdDbGljaykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIHRvdWNoIGhhcyBtb3ZlZCwgY2FuY2VsIHRoZSBjbGljayB0cmFja2luZ1xuXHRcdGlmICh0aGlzLnRhcmdldEVsZW1lbnQgIT09IHRoaXMuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldChldmVudC50YXJnZXQpIHx8IHRoaXMudG91Y2hIYXNNb3ZlZChldmVudCkpIHtcblx0XHRcdHRoaXMudHJhY2tpbmdDbGljayA9IGZhbHNlO1xuXHRcdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBBdHRlbXB0IHRvIGZpbmQgdGhlIGxhYmVsbGVkIGNvbnRyb2wgZm9yIHRoZSBnaXZlbiBsYWJlbCBlbGVtZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fEhUTUxMYWJlbEVsZW1lbnR9IGxhYmVsRWxlbWVudFxuXHQgKiBAcmV0dXJucyB7RWxlbWVudHxudWxsfVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5maW5kQ29udHJvbCA9IGZ1bmN0aW9uKGxhYmVsRWxlbWVudCkge1xuXG5cdFx0Ly8gRmFzdCBwYXRoIGZvciBuZXdlciBicm93c2VycyBzdXBwb3J0aW5nIHRoZSBIVE1MNSBjb250cm9sIGF0dHJpYnV0ZVxuXHRcdGlmIChsYWJlbEVsZW1lbnQuY29udHJvbCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gbGFiZWxFbGVtZW50LmNvbnRyb2w7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsIGJyb3dzZXJzIHVuZGVyIHRlc3QgdGhhdCBzdXBwb3J0IHRvdWNoIGV2ZW50cyBhbHNvIHN1cHBvcnQgdGhlIEhUTUw1IGh0bWxGb3IgYXR0cmlidXRlXG5cdFx0aWYgKGxhYmVsRWxlbWVudC5odG1sRm9yKSB7XG5cdFx0XHRyZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobGFiZWxFbGVtZW50Lmh0bWxGb3IpO1xuXHRcdH1cblxuXHRcdC8vIElmIG5vIGZvciBhdHRyaWJ1dGUgZXhpc3RzLCBhdHRlbXB0IHRvIHJldHJpZXZlIHRoZSBmaXJzdCBsYWJlbGxhYmxlIGRlc2NlbmRhbnQgZWxlbWVudFxuXHRcdC8vIHRoZSBsaXN0IG9mIHdoaWNoIGlzIGRlZmluZWQgaGVyZTogaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCNjYXRlZ29yeS1sYWJlbFxuXHRcdHJldHVybiBsYWJlbEVsZW1lbnQucXVlcnlTZWxlY3RvcignYnV0dG9uLCBpbnB1dDpub3QoW3R5cGU9aGlkZGVuXSksIGtleWdlbiwgbWV0ZXIsIG91dHB1dCwgcHJvZ3Jlc3MsIHNlbGVjdCwgdGV4dGFyZWEnKTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBPbiB0b3VjaCBlbmQsIGRldGVybWluZSB3aGV0aGVyIHRvIHNlbmQgYSBjbGljayBldmVudCBhdCBvbmNlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUub25Ub3VjaEVuZCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0dmFyIGZvckVsZW1lbnQsIHRyYWNraW5nQ2xpY2tTdGFydCwgdGFyZ2V0VGFnTmFtZSwgc2Nyb2xsUGFyZW50LCB0b3VjaCwgdGFyZ2V0RWxlbWVudCA9IHRoaXMudGFyZ2V0RWxlbWVudDtcblxuXHRcdGlmICghdGhpcy50cmFja2luZ0NsaWNrKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBQcmV2ZW50IHBoYW50b20gY2xpY2tzIG9uIGZhc3QgZG91YmxlLXRhcCAoaXNzdWUgIzM2KVxuXHRcdGlmICgoZXZlbnQudGltZVN0YW1wIC0gdGhpcy5sYXN0Q2xpY2tUaW1lKSA8IHRoaXMudGFwRGVsYXkgJiYgKGV2ZW50LnRpbWVTdGFtcCAtIHRoaXMubGFzdENsaWNrVGltZSkgPiAtMSkge1xuXHRcdFx0dGhpcy5jYW5jZWxOZXh0Q2xpY2sgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKChldmVudC50aW1lU3RhbXAgLSB0aGlzLnRyYWNraW5nQ2xpY2tTdGFydCkgPiB0aGlzLnRhcFRpbWVvdXQpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFJlc2V0IHRvIHByZXZlbnQgd3JvbmcgY2xpY2sgY2FuY2VsIG9uIGlucHV0IChpc3N1ZSAjMTU2KS5cblx0XHR0aGlzLmNhbmNlbE5leHRDbGljayA9IGZhbHNlO1xuXG5cdFx0dGhpcy5sYXN0Q2xpY2tUaW1lID0gZXZlbnQudGltZVN0YW1wO1xuXG5cdFx0dHJhY2tpbmdDbGlja1N0YXJ0ID0gdGhpcy50cmFja2luZ0NsaWNrU3RhcnQ7XG5cdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cdFx0dGhpcy50cmFja2luZ0NsaWNrU3RhcnQgPSAwO1xuXG5cdFx0Ly8gT24gc29tZSBpT1MgZGV2aWNlcywgdGhlIHRhcmdldEVsZW1lbnQgc3VwcGxpZWQgd2l0aCB0aGUgZXZlbnQgaXMgaW52YWxpZCBpZiB0aGUgbGF5ZXJcblx0XHQvLyBpcyBwZXJmb3JtaW5nIGEgdHJhbnNpdGlvbiBvciBzY3JvbGwsIGFuZCBoYXMgdG8gYmUgcmUtZGV0ZWN0ZWQgbWFudWFsbHkuIE5vdGUgdGhhdFxuXHRcdC8vIGZvciB0aGlzIHRvIGZ1bmN0aW9uIGNvcnJlY3RseSwgaXQgbXVzdCBiZSBjYWxsZWQgKmFmdGVyKiB0aGUgZXZlbnQgdGFyZ2V0IGlzIGNoZWNrZWQhXG5cdFx0Ly8gU2VlIGlzc3VlICM1NzsgYWxzbyBmaWxlZCBhcyByZGFyOi8vMTMwNDg1ODkgLlxuXHRcdGlmIChkZXZpY2VJc0lPU1dpdGhCYWRUYXJnZXQpIHtcblx0XHRcdHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG5cblx0XHRcdC8vIEluIGNlcnRhaW4gY2FzZXMgYXJndW1lbnRzIG9mIGVsZW1lbnRGcm9tUG9pbnQgY2FuIGJlIG5lZ2F0aXZlLCBzbyBwcmV2ZW50IHNldHRpbmcgdGFyZ2V0RWxlbWVudCB0byBudWxsXG5cdFx0XHR0YXJnZXRFbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh0b3VjaC5wYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldCwgdG91Y2gucGFnZVkgLSB3aW5kb3cucGFnZVlPZmZzZXQpIHx8IHRhcmdldEVsZW1lbnQ7XG5cdFx0XHR0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudCA9IHRoaXMudGFyZ2V0RWxlbWVudC5mYXN0Q2xpY2tTY3JvbGxQYXJlbnQ7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0VGFnTmFtZSA9IHRhcmdldEVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmICh0YXJnZXRUYWdOYW1lID09PSAnbGFiZWwnKSB7XG5cdFx0XHRmb3JFbGVtZW50ID0gdGhpcy5maW5kQ29udHJvbCh0YXJnZXRFbGVtZW50KTtcblx0XHRcdGlmIChmb3JFbGVtZW50KSB7XG5cdFx0XHRcdHRoaXMuZm9jdXModGFyZ2V0RWxlbWVudCk7XG5cdFx0XHRcdGlmIChkZXZpY2VJc0FuZHJvaWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0YXJnZXRFbGVtZW50ID0gZm9yRWxlbWVudDtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHRoaXMubmVlZHNGb2N1cyh0YXJnZXRFbGVtZW50KSkge1xuXG5cdFx0XHQvLyBDYXNlIDE6IElmIHRoZSB0b3VjaCBzdGFydGVkIGEgd2hpbGUgYWdvIChiZXN0IGd1ZXNzIGlzIDEwMG1zIGJhc2VkIG9uIHRlc3RzIGZvciBpc3N1ZSAjMzYpIHRoZW4gZm9jdXMgd2lsbCBiZSB0cmlnZ2VyZWQgYW55d2F5LiBSZXR1cm4gZWFybHkgYW5kIHVuc2V0IHRoZSB0YXJnZXQgZWxlbWVudCByZWZlcmVuY2Ugc28gdGhhdCB0aGUgc3Vic2VxdWVudCBjbGljayB3aWxsIGJlIGFsbG93ZWQgdGhyb3VnaC5cblx0XHRcdC8vIENhc2UgMjogV2l0aG91dCB0aGlzIGV4Y2VwdGlvbiBmb3IgaW5wdXQgZWxlbWVudHMgdGFwcGVkIHdoZW4gdGhlIGRvY3VtZW50IGlzIGNvbnRhaW5lZCBpbiBhbiBpZnJhbWUsIHRoZW4gYW55IGlucHV0dGVkIHRleHQgd29uJ3QgYmUgdmlzaWJsZSBldmVuIHRob3VnaCB0aGUgdmFsdWUgYXR0cmlidXRlIGlzIHVwZGF0ZWQgYXMgdGhlIHVzZXIgdHlwZXMgKGlzc3VlICMzNykuXG5cdFx0XHRpZiAoKGV2ZW50LnRpbWVTdGFtcCAtIHRyYWNraW5nQ2xpY2tTdGFydCkgPiAxMDAgfHwgKGRldmljZUlzSU9TICYmIHdpbmRvdy50b3AgIT09IHdpbmRvdyAmJiB0YXJnZXRUYWdOYW1lID09PSAnaW5wdXQnKSkge1xuXHRcdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuZm9jdXModGFyZ2V0RWxlbWVudCk7XG5cdFx0XHR0aGlzLnNlbmRDbGljayh0YXJnZXRFbGVtZW50LCBldmVudCk7XG5cblx0XHRcdC8vIFNlbGVjdCBlbGVtZW50cyBuZWVkIHRoZSBldmVudCB0byBnbyB0aHJvdWdoIG9uIGlPUyA0LCBvdGhlcndpc2UgdGhlIHNlbGVjdG9yIG1lbnUgd29uJ3Qgb3Blbi5cblx0XHRcdC8vIEFsc28gdGhpcyBicmVha3Mgb3BlbmluZyBzZWxlY3RzIHdoZW4gVm9pY2VPdmVyIGlzIGFjdGl2ZSBvbiBpT1M2LCBpT1M3IChhbmQgcG9zc2libHkgb3RoZXJzKVxuXHRcdFx0aWYgKCFkZXZpY2VJc0lPUzQgfHwgdGFyZ2V0VGFnTmFtZSAhPT0gJ3NlbGVjdCcpIHtcblx0XHRcdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmIChkZXZpY2VJc0lPUyAmJiAhZGV2aWNlSXNJT1M0KSB7XG5cblx0XHRcdC8vIERvbid0IHNlbmQgYSBzeW50aGV0aWMgY2xpY2sgZXZlbnQgaWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGNvbnRhaW5lZCB3aXRoaW4gYSBwYXJlbnQgbGF5ZXIgdGhhdCB3YXMgc2Nyb2xsZWRcblx0XHRcdC8vIGFuZCB0aGlzIHRhcCBpcyBiZWluZyB1c2VkIHRvIHN0b3AgdGhlIHNjcm9sbGluZyAodXN1YWxseSBpbml0aWF0ZWQgYnkgYSBmbGluZyAtIGlzc3VlICM0MikuXG5cdFx0XHRzY3JvbGxQYXJlbnQgPSB0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudDtcblx0XHRcdGlmIChzY3JvbGxQYXJlbnQgJiYgc2Nyb2xsUGFyZW50LmZhc3RDbGlja0xhc3RTY3JvbGxUb3AgIT09IHNjcm9sbFBhcmVudC5zY3JvbGxUb3ApIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJldmVudCB0aGUgYWN0dWFsIGNsaWNrIGZyb20gZ29pbmcgdGhvdWdoIC0gdW5sZXNzIHRoZSB0YXJnZXQgbm9kZSBpcyBtYXJrZWQgYXMgcmVxdWlyaW5nXG5cdFx0Ly8gcmVhbCBjbGlja3Mgb3IgaWYgaXQgaXMgaW4gdGhlIHdoaXRlbGlzdCBpbiB3aGljaCBjYXNlIG9ubHkgbm9uLXByb2dyYW1tYXRpYyBjbGlja3MgYXJlIHBlcm1pdHRlZC5cblx0XHRpZiAoIXRoaXMubmVlZHNDbGljayh0YXJnZXRFbGVtZW50KSkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHRoaXMuc2VuZENsaWNrKHRhcmdldEVsZW1lbnQsIGV2ZW50KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH07XG5cblxuXHQvKipcblx0ICogT24gdG91Y2ggY2FuY2VsLCBzdG9wIHRyYWNraW5nIHRoZSBjbGljay5cblx0ICpcblx0ICogQHJldHVybnMge3ZvaWR9XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uVG91Y2hDYW5jZWwgPSBmdW5jdGlvbigpIHtcblx0XHR0aGlzLnRyYWNraW5nQ2xpY2sgPSBmYWxzZTtcblx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIERldGVybWluZSBtb3VzZSBldmVudHMgd2hpY2ggc2hvdWxkIGJlIHBlcm1pdHRlZC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uTW91c2UgPSBmdW5jdGlvbihldmVudCkge1xuXG5cdFx0Ly8gSWYgYSB0YXJnZXQgZWxlbWVudCB3YXMgbmV2ZXIgc2V0IChiZWNhdXNlIGEgdG91Y2ggZXZlbnQgd2FzIG5ldmVyIGZpcmVkKSBhbGxvdyB0aGUgZXZlbnRcblx0XHRpZiAoIXRoaXMudGFyZ2V0RWxlbWVudCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKGV2ZW50LmZvcndhcmRlZFRvdWNoRXZlbnQpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFByb2dyYW1tYXRpY2FsbHkgZ2VuZXJhdGVkIGV2ZW50cyB0YXJnZXRpbmcgYSBzcGVjaWZpYyBlbGVtZW50IHNob3VsZCBiZSBwZXJtaXR0ZWRcblx0XHRpZiAoIWV2ZW50LmNhbmNlbGFibGUpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIERlcml2ZSBhbmQgY2hlY2sgdGhlIHRhcmdldCBlbGVtZW50IHRvIHNlZSB3aGV0aGVyIHRoZSBtb3VzZSBldmVudCBuZWVkcyB0byBiZSBwZXJtaXR0ZWQ7XG5cdFx0Ly8gdW5sZXNzIGV4cGxpY2l0bHkgZW5hYmxlZCwgcHJldmVudCBub24tdG91Y2ggY2xpY2sgZXZlbnRzIGZyb20gdHJpZ2dlcmluZyBhY3Rpb25zLFxuXHRcdC8vIHRvIHByZXZlbnQgZ2hvc3QvZG91YmxlY2xpY2tzLlxuXHRcdGlmICghdGhpcy5uZWVkc0NsaWNrKHRoaXMudGFyZ2V0RWxlbWVudCkgfHwgdGhpcy5jYW5jZWxOZXh0Q2xpY2spIHtcblxuXHRcdFx0Ly8gUHJldmVudCBhbnkgdXNlci1hZGRlZCBsaXN0ZW5lcnMgZGVjbGFyZWQgb24gRmFzdENsaWNrIGVsZW1lbnQgZnJvbSBiZWluZyBmaXJlZC5cblx0XHRcdGlmIChldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24pIHtcblx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIFBhcnQgb2YgdGhlIGhhY2sgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBFdmVudCNzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gKGUuZy4gQW5kcm9pZCAyKVxuXHRcdFx0XHRldmVudC5wcm9wYWdhdGlvblN0b3BwZWQgPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYW5jZWwgdGhlIGV2ZW50XG5cdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgbW91c2UgZXZlbnQgaXMgcGVybWl0dGVkLCByZXR1cm4gdHJ1ZSBmb3IgdGhlIGFjdGlvbiB0byBnbyB0aHJvdWdoLlxuXHRcdHJldHVybiB0cnVlO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIE9uIGFjdHVhbCBjbGlja3MsIGRldGVybWluZSB3aGV0aGVyIHRoaXMgaXMgYSB0b3VjaC1nZW5lcmF0ZWQgY2xpY2ssIGEgY2xpY2sgYWN0aW9uIG9jY3VycmluZ1xuXHQgKiBuYXR1cmFsbHkgYWZ0ZXIgYSBkZWxheSBhZnRlciBhIHRvdWNoICh3aGljaCBuZWVkcyB0byBiZSBjYW5jZWxsZWQgdG8gYXZvaWQgZHVwbGljYXRpb24pLCBvclxuXHQgKiBhbiBhY3R1YWwgY2xpY2sgd2hpY2ggc2hvdWxkIGJlIHBlcm1pdHRlZC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLm9uQ2xpY2sgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciBwZXJtaXR0ZWQ7XG5cblx0XHQvLyBJdCdzIHBvc3NpYmxlIGZvciBhbm90aGVyIEZhc3RDbGljay1saWtlIGxpYnJhcnkgZGVsaXZlcmVkIHdpdGggdGhpcmQtcGFydHkgY29kZSB0byBmaXJlIGEgY2xpY2sgZXZlbnQgYmVmb3JlIEZhc3RDbGljayBkb2VzIChpc3N1ZSAjNDQpLiBJbiB0aGF0IGNhc2UsIHNldCB0aGUgY2xpY2stdHJhY2tpbmcgZmxhZyBiYWNrIHRvIGZhbHNlIGFuZCByZXR1cm4gZWFybHkuIFRoaXMgd2lsbCBjYXVzZSBvblRvdWNoRW5kIHRvIHJldHVybiBlYXJseS5cblx0XHRpZiAodGhpcy50cmFja2luZ0NsaWNrKSB7XG5cdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBWZXJ5IG9kZCBiZWhhdmlvdXIgb24gaU9TIChpc3N1ZSAjMTgpOiBpZiBhIHN1Ym1pdCBlbGVtZW50IGlzIHByZXNlbnQgaW5zaWRlIGEgZm9ybSBhbmQgdGhlIHVzZXIgaGl0cyBlbnRlciBpbiB0aGUgaU9TIHNpbXVsYXRvciBvciBjbGlja3MgdGhlIEdvIGJ1dHRvbiBvbiB0aGUgcG9wLXVwIE9TIGtleWJvYXJkIHRoZSBhIGtpbmQgb2YgJ2Zha2UnIGNsaWNrIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkIHdpdGggdGhlIHN1Ym1pdC10eXBlIGlucHV0IGVsZW1lbnQgYXMgdGhlIHRhcmdldC5cblx0XHRpZiAoZXZlbnQudGFyZ2V0LnR5cGUgPT09ICdzdWJtaXQnICYmIGV2ZW50LmRldGFpbCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cGVybWl0dGVkID0gdGhpcy5vbk1vdXNlKGV2ZW50KTtcblxuXHRcdC8vIE9ubHkgdW5zZXQgdGFyZ2V0RWxlbWVudCBpZiB0aGUgY2xpY2sgaXMgbm90IHBlcm1pdHRlZC4gVGhpcyB3aWxsIGVuc3VyZSB0aGF0IHRoZSBjaGVjayBmb3IgIXRhcmdldEVsZW1lbnQgaW4gb25Nb3VzZSBmYWlscyBhbmQgdGhlIGJyb3dzZXIncyBjbGljayBkb2Vzbid0IGdvIHRocm91Z2guXG5cdFx0aWYgKCFwZXJtaXR0ZWQpIHtcblx0XHRcdHRoaXMudGFyZ2V0RWxlbWVudCA9IG51bGw7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgY2xpY2tzIGFyZSBwZXJtaXR0ZWQsIHJldHVybiB0cnVlIGZvciB0aGUgYWN0aW9uIHRvIGdvIHRocm91Z2guXG5cdFx0cmV0dXJuIHBlcm1pdHRlZDtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYWxsIEZhc3RDbGljaydzIGV2ZW50IGxpc3RlbmVycy5cblx0ICpcblx0ICogQHJldHVybnMge3ZvaWR9XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgbGF5ZXIgPSB0aGlzLmxheWVyO1xuXG5cdFx0aWYgKGRldmljZUlzQW5kcm9pZCkge1xuXHRcdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHRcdGxheWVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMub25Nb3VzZSwgdHJ1ZSk7XG5cdFx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHR9XG5cblx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25DbGljaywgdHJ1ZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMub25Ub3VjaFN0YXJ0LCBmYWxzZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGhpcy5vblRvdWNoTW92ZSwgZmFsc2UpO1xuXHRcdGxheWVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5vblRvdWNoRW5kLCBmYWxzZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hjYW5jZWwnLCB0aGlzLm9uVG91Y2hDYW5jZWwsIGZhbHNlKTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBDaGVjayB3aGV0aGVyIEZhc3RDbGljayBpcyBuZWVkZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGF5ZXIgVGhlIGxheWVyIHRvIGxpc3RlbiBvblxuXHQgKi9cblx0RmFzdENsaWNrLm5vdE5lZWRlZCA9IGZ1bmN0aW9uKGxheWVyKSB7XG5cdFx0dmFyIG1ldGFWaWV3cG9ydDtcblx0XHR2YXIgY2hyb21lVmVyc2lvbjtcblx0XHR2YXIgYmxhY2tiZXJyeVZlcnNpb247XG5cdFx0dmFyIGZpcmVmb3hWZXJzaW9uO1xuXG5cdFx0Ly8gRGV2aWNlcyB0aGF0IGRvbid0IHN1cHBvcnQgdG91Y2ggZG9uJ3QgbmVlZCBGYXN0Q2xpY2tcblx0XHRpZiAodHlwZW9mIHdpbmRvdy5vbnRvdWNoc3RhcnQgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBDaHJvbWUgdmVyc2lvbiAtIHplcm8gZm9yIG90aGVyIGJyb3dzZXJzXG5cdFx0Y2hyb21lVmVyc2lvbiA9ICsoL0Nocm9tZVxcLyhbMC05XSspLy5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpIHx8IFssMF0pWzFdO1xuXG5cdFx0aWYgKGNocm9tZVZlcnNpb24pIHtcblxuXHRcdFx0aWYgKGRldmljZUlzQW5kcm9pZCkge1xuXHRcdFx0XHRtZXRhVmlld3BvcnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9dmlld3BvcnRdJyk7XG5cblx0XHRcdFx0aWYgKG1ldGFWaWV3cG9ydCkge1xuXHRcdFx0XHRcdC8vIENocm9tZSBvbiBBbmRyb2lkIHdpdGggdXNlci1zY2FsYWJsZT1cIm5vXCIgZG9lc24ndCBuZWVkIEZhc3RDbGljayAoaXNzdWUgIzg5KVxuXHRcdFx0XHRcdGlmIChtZXRhVmlld3BvcnQuY29udGVudC5pbmRleE9mKCd1c2VyLXNjYWxhYmxlPW5vJykgIT09IC0xKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gQ2hyb21lIDMyIGFuZCBhYm92ZSB3aXRoIHdpZHRoPWRldmljZS13aWR0aCBvciBsZXNzIGRvbid0IG5lZWQgRmFzdENsaWNrXG5cdFx0XHRcdFx0aWYgKGNocm9tZVZlcnNpb24gPiAzMSAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsV2lkdGggPD0gd2luZG93Lm91dGVyV2lkdGgpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBDaHJvbWUgZGVza3RvcCBkb2Vzbid0IG5lZWQgRmFzdENsaWNrIChpc3N1ZSAjMTUpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZGV2aWNlSXNCbGFja0JlcnJ5MTApIHtcblx0XHRcdGJsYWNrYmVycnlWZXJzaW9uID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvVmVyc2lvblxcLyhbMC05XSopXFwuKFswLTldKikvKTtcblxuXHRcdFx0Ly8gQmxhY2tCZXJyeSAxMC4zKyBkb2VzIG5vdCByZXF1aXJlIEZhc3RjbGljayBsaWJyYXJ5LlxuXHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2Z0bGFicy9mYXN0Y2xpY2svaXNzdWVzLzI1MVxuXHRcdFx0aWYgKGJsYWNrYmVycnlWZXJzaW9uWzFdID49IDEwICYmIGJsYWNrYmVycnlWZXJzaW9uWzJdID49IDMpIHtcblx0XHRcdFx0bWV0YVZpZXdwb3J0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbWV0YVtuYW1lPXZpZXdwb3J0XScpO1xuXG5cdFx0XHRcdGlmIChtZXRhVmlld3BvcnQpIHtcblx0XHRcdFx0XHQvLyB1c2VyLXNjYWxhYmxlPW5vIGVsaW1pbmF0ZXMgY2xpY2sgZGVsYXkuXG5cdFx0XHRcdFx0aWYgKG1ldGFWaWV3cG9ydC5jb250ZW50LmluZGV4T2YoJ3VzZXItc2NhbGFibGU9bm8nKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyB3aWR0aD1kZXZpY2Utd2lkdGggKG9yIGxlc3MgdGhhbiBkZXZpY2Utd2lkdGgpIGVsaW1pbmF0ZXMgY2xpY2sgZGVsYXkuXG5cdFx0XHRcdFx0aWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxXaWR0aCA8PSB3aW5kb3cub3V0ZXJXaWR0aCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gSUUxMCB3aXRoIC1tcy10b3VjaC1hY3Rpb246IG5vbmUgb3IgbWFuaXB1bGF0aW9uLCB3aGljaCBkaXNhYmxlcyBkb3VibGUtdGFwLXRvLXpvb20gKGlzc3VlICM5Nylcblx0XHRpZiAobGF5ZXIuc3R5bGUubXNUb3VjaEFjdGlvbiA9PT0gJ25vbmUnIHx8IGxheWVyLnN0eWxlLnRvdWNoQWN0aW9uID09PSAnbWFuaXB1bGF0aW9uJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gRmlyZWZveCB2ZXJzaW9uIC0gemVybyBmb3Igb3RoZXIgYnJvd3NlcnNcblx0XHRmaXJlZm94VmVyc2lvbiA9ICsoL0ZpcmVmb3hcXC8oWzAtOV0rKS8uZXhlYyhuYXZpZ2F0b3IudXNlckFnZW50KSB8fCBbLDBdKVsxXTtcblxuXHRcdGlmIChmaXJlZm94VmVyc2lvbiA+PSAyNykge1xuXHRcdFx0Ly8gRmlyZWZveCAyNysgZG9lcyBub3QgaGF2ZSB0YXAgZGVsYXkgaWYgdGhlIGNvbnRlbnQgaXMgbm90IHpvb21hYmxlIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9OTIyODk2XG5cblx0XHRcdG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21ldGFbbmFtZT12aWV3cG9ydF0nKTtcblx0XHRcdGlmIChtZXRhVmlld3BvcnQgJiYgKG1ldGFWaWV3cG9ydC5jb250ZW50LmluZGV4T2YoJ3VzZXItc2NhbGFibGU9bm8nKSAhPT0gLTEgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFdpZHRoIDw9IHdpbmRvdy5vdXRlcldpZHRoKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBJRTExOiBwcmVmaXhlZCAtbXMtdG91Y2gtYWN0aW9uIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQgYW5kIGl0J3MgcmVjb21lbmRlZCB0byB1c2Ugbm9uLXByZWZpeGVkIHZlcnNpb25cblx0XHQvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvd2luZG93cy9hcHBzL0hoNzY3MzEzLmFzcHhcblx0XHRpZiAobGF5ZXIuc3R5bGUudG91Y2hBY3Rpb24gPT09ICdub25lJyB8fCBsYXllci5zdHlsZS50b3VjaEFjdGlvbiA9PT0gJ21hbmlwdWxhdGlvbicpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBGYWN0b3J5IG1ldGhvZCBmb3IgY3JlYXRpbmcgYSBGYXN0Q2xpY2sgb2JqZWN0XG5cdCAqXG5cdCAqIEBwYXJhbSB7RWxlbWVudH0gbGF5ZXIgVGhlIGxheWVyIHRvIGxpc3RlbiBvblxuXHQgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0c1xuXHQgKi9cblx0RmFzdENsaWNrLmF0dGFjaCA9IGZ1bmN0aW9uKGxheWVyLCBvcHRpb25zKSB7XG5cdFx0cmV0dXJuIG5ldyBGYXN0Q2xpY2sobGF5ZXIsIG9wdGlvbnMpO1xuXHR9O1xuXG5cblx0aWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT09ICdvYmplY3QnICYmIGRlZmluZS5hbWQpIHtcblxuXHRcdC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cblx0XHRkZWZpbmUoZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gRmFzdENsaWNrO1xuXHRcdH0pO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBGYXN0Q2xpY2suYXR0YWNoO1xuXHRcdG1vZHVsZS5leHBvcnRzLkZhc3RDbGljayA9IEZhc3RDbGljaztcblx0fSBlbHNlIHtcblx0XHR3aW5kb3cuRmFzdENsaWNrID0gRmFzdENsaWNrO1xuXHR9XG59KCkpO1xuIiwiLy8gRm9yIEBvbnNlbnVpL2N1c3RvbS1lbGVtZW50c1xuaWYgKHdpbmRvdy5jdXN0b21FbGVtZW50cykgeyAvLyBldmVuIGlmIG5hdGl2ZSBDRTEgaW1wbCBleGlzdHMsIHVzZSBwb2x5ZmlsbFxuICAgIHdpbmRvdy5jdXN0b21FbGVtZW50cy5mb3JjZVBvbHlmaWxsID0gdHJ1ZTtcbn1cbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGZcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbmlmICh0eXBlb2YgX19nID09ICdudW1iZXInKSBfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7IHZlcnNpb246ICcyLjUuMScgfTtcbmlmICh0eXBlb2YgX19lID09ICdudW1iZXInKSBfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGFuIG9iamVjdCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gISFleGVjKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcbiIsIi8vIFRoYW5rJ3MgSUU4IGZvciBoaXMgZnVubnkgZGVmaW5lUHJvcGVydHlcbm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnYScsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9IH0pLmEgIT0gNztcbn0pO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZG9jdW1lbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudDtcbi8vIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnIGluIG9sZCBJRVxudmFyIGlzID0gaXNPYmplY3QoZG9jdW1lbnQpICYmIGlzT2JqZWN0KGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpdCkgOiB7fTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2RpdicpLCAnYScsIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9IH0pLmEgIT0gNztcbn0pO1xuIiwiLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFMpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmIChTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuIiwidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgSUU4X0RPTV9ERUZJTkUgPSByZXF1aXJlKCcuL19pZTgtZG9tLWRlZmluZScpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZFAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEF0dHJpYnV0ZXMpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgaWYgKCdnZXQnIGluIEF0dHJpYnV0ZXMgfHwgJ3NldCcgaW4gQXR0cmlidXRlcykgdGhyb3cgVHlwZUVycm9yKCdBY2Nlc3NvcnMgbm90IHN1cHBvcnRlZCEnKTtcbiAgaWYgKCd2YWx1ZScgaW4gQXR0cmlidXRlcykgT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gIHJldHVybiBPO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdG1hcCwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZTogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn07XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICByZXR1cm4gZFAuZihvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG4iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIiwidmFyIGlkID0gMDtcbnZhciBweCA9IE1hdGgucmFuZG9tKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuICdTeW1ib2woJy5jb25jYXQoa2V5ID09PSB1bmRlZmluZWQgPyAnJyA6IGtleSwgJylfJywgKCsraWQgKyBweCkudG9TdHJpbmcoMzYpKTtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBTUkMgPSByZXF1aXJlKCcuL191aWQnKSgnc3JjJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciAkdG9TdHJpbmcgPSBGdW5jdGlvbltUT19TVFJJTkddO1xudmFyIFRQTCA9ICgnJyArICR0b1N0cmluZykuc3BsaXQoVE9fU1RSSU5HKTtcblxucmVxdWlyZSgnLi9fY29yZScpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuICR0b1N0cmluZy5jYWxsKGl0KTtcbn07XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBrZXksIHZhbCwgc2FmZSkge1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcbiAgaWYgKE9ba2V5XSA9PT0gdmFsKSByZXR1cm47XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYgKE8gPT09IGdsb2JhbCkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIGlmICghc2FmZSkge1xuICAgIGRlbGV0ZSBPW2tleV07XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH0gZWxzZSBpZiAoT1trZXldKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9XG4vLyBhZGQgZmFrZSBGdW5jdGlvbiN0b1N0cmluZyBmb3IgY29ycmVjdCB3b3JrIHdyYXBwZWQgbWV0aG9kcyAvIGNvbnN0cnVjdG9ycyB3aXRoIG1ldGhvZHMgbGlrZSBMb0Rhc2ggaXNOYXRpdmVcbn0pKEZ1bmN0aW9uLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgJiYgdGhpc1tTUkNdIHx8ICR0b1N0cmluZy5jYWxsKHRoaXMpO1xufSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgdGhhdCwgbGVuZ3RoKSB7XG4gIGFGdW5jdGlvbihmbik7XG4gIGlmICh0aGF0ID09PSB1bmRlZmluZWQpIHJldHVybiBmbjtcbiAgc3dpdGNoIChsZW5ndGgpIHtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG4gICAgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLmFyZ3MgKi8pIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY29yZSA9IHJlcXVpcmUoJy4vX2NvcmUnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxudmFyICRleHBvcnQgPSBmdW5jdGlvbiAodHlwZSwgbmFtZSwgc291cmNlKSB7XG4gIHZhciBJU19GT1JDRUQgPSB0eXBlICYgJGV4cG9ydC5GO1xuICB2YXIgSVNfR0xPQkFMID0gdHlwZSAmICRleHBvcnQuRztcbiAgdmFyIElTX1NUQVRJQyA9IHR5cGUgJiAkZXhwb3J0LlM7XG4gIHZhciBJU19QUk9UTyA9IHR5cGUgJiAkZXhwb3J0LlA7XG4gIHZhciBJU19CSU5EID0gdHlwZSAmICRleHBvcnQuQjtcbiAgdmFyIHRhcmdldCA9IElTX0dMT0JBTCA/IGdsb2JhbCA6IElTX1NUQVRJQyA/IGdsb2JhbFtuYW1lXSB8fCAoZ2xvYmFsW25hbWVdID0ge30pIDogKGdsb2JhbFtuYW1lXSB8fCB7fSlbUFJPVE9UWVBFXTtcbiAgdmFyIGV4cG9ydHMgPSBJU19HTE9CQUwgPyBjb3JlIDogY29yZVtuYW1lXSB8fCAoY29yZVtuYW1lXSA9IHt9KTtcbiAgdmFyIGV4cFByb3RvID0gZXhwb3J0c1tQUk9UT1RZUEVdIHx8IChleHBvcnRzW1BST1RPVFlQRV0gPSB7fSk7XG4gIHZhciBrZXksIG93biwgb3V0LCBleHA7XG4gIGlmIChJU19HTE9CQUwpIHNvdXJjZSA9IG5hbWU7XG4gIGZvciAoa2V5IGluIHNvdXJjZSkge1xuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxuICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIHRhcmdldFtrZXldICE9PSB1bmRlZmluZWQ7XG4gICAgLy8gZXhwb3J0IG5hdGl2ZSBvciBwYXNzZWRcbiAgICBvdXQgPSAob3duID8gdGFyZ2V0IDogc291cmNlKVtrZXldO1xuICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG4gICAgZXhwID0gSVNfQklORCAmJiBvd24gPyBjdHgob3V0LCBnbG9iYWwpIDogSVNfUFJPVE8gJiYgdHlwZW9mIG91dCA9PSAnZnVuY3Rpb24nID8gY3R4KEZ1bmN0aW9uLmNhbGwsIG91dCkgOiBvdXQ7XG4gICAgLy8gZXh0ZW5kIGdsb2JhbFxuICAgIGlmICh0YXJnZXQpIHJlZGVmaW5lKHRhcmdldCwga2V5LCBvdXQsIHR5cGUgJiAkZXhwb3J0LlUpO1xuICAgIC8vIGV4cG9ydFxuICAgIGlmIChleHBvcnRzW2tleV0gIT0gb3V0KSBoaWRlKGV4cG9ydHMsIGtleSwgZXhwKTtcbiAgICBpZiAoSVNfUFJPVE8gJiYgZXhwUHJvdG9ba2V5XSAhPSBvdXQpIGV4cFByb3RvW2tleV0gPSBvdXQ7XG4gIH1cbn07XG5nbG9iYWwuY29yZSA9IGNvcmU7XG4vLyB0eXBlIGJpdG1hcFxuJGV4cG9ydC5GID0gMTsgICAvLyBmb3JjZWRcbiRleHBvcnQuRyA9IDI7ICAgLy8gZ2xvYmFsXG4kZXhwb3J0LlMgPSA0OyAgIC8vIHN0YXRpY1xuJGV4cG9ydC5QID0gODsgICAvLyBwcm90b1xuJGV4cG9ydC5CID0gMTY7ICAvLyBiaW5kXG4kZXhwb3J0LlcgPSAzMjsgIC8vIHdyYXBcbiRleHBvcnQuVSA9IDY0OyAgLy8gc2FmZVxuJGV4cG9ydC5SID0gMTI4OyAvLyByZWFsIHByb3RvIG1ldGhvZCBmb3IgYGxpYnJhcnlgXG5tb2R1bGUuZXhwb3J0cyA9ICRleHBvcnQ7XG4iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiIsIi8vIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgYW5kIG5vbi1lbnVtZXJhYmxlIG9sZCBWOCBzdHJpbmdzXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdCgneicpLnByb3BlcnR5SXNFbnVtZXJhYmxlKDApID8gT2JqZWN0IDogZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBjb2YoaXQpID09ICdTdHJpbmcnID8gaXQuc3BsaXQoJycpIDogT2JqZWN0KGl0KTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsInZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgZ09QRCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BEIDogZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApIHtcbiAgTyA9IHRvSU9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBpZiAoSUU4X0RPTV9ERUZJTkUpIHRyeSB7XG4gICAgcmV0dXJuIGdPUEQoTywgUCk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoaGFzKE8sIFApKSByZXR1cm4gY3JlYXRlRGVzYyghcElFLmYuY2FsbChPLCBQKSwgT1tQXSk7XG59O1xuIiwiLy8gV29ya3Mgd2l0aCBfX3Byb3RvX18gb25seS4gT2xkIHY4IGNhbid0IHdvcmsgd2l0aCBudWxsIHByb3RvIG9iamVjdHMuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBjaGVjayA9IGZ1bmN0aW9uIChPLCBwcm90bykge1xuICBhbk9iamVjdChPKTtcbiAgaWYgKCFpc09iamVjdChwcm90bykgJiYgcHJvdG8gIT09IG51bGwpIHRocm93IFR5cGVFcnJvcihwcm90byArIFwiOiBjYW4ndCBzZXQgYXMgcHJvdG90eXBlIVwiKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwgKCdfX3Byb3RvX18nIGluIHt9ID8gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICAgIGZ1bmN0aW9uICh0ZXN0LCBidWdneSwgc2V0KSB7XG4gICAgICB0cnkge1xuICAgICAgICBzZXQgPSByZXF1aXJlKCcuL19jdHgnKShGdW5jdGlvbi5jYWxsLCByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmYoT2JqZWN0LnByb3RvdHlwZSwgJ19fcHJvdG9fXycpLnNldCwgMik7XG4gICAgICAgIHNldCh0ZXN0LCBbXSk7XG4gICAgICAgIGJ1Z2d5ID0gISh0ZXN0IGluc3RhbmNlb2YgQXJyYXkpO1xuICAgICAgfSBjYXRjaCAoZSkgeyBidWdneSA9IHRydWU7IH1cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZihPLCBwcm90bykge1xuICAgICAgICBjaGVjayhPLCBwcm90byk7XG4gICAgICAgIGlmIChidWdneSkgTy5fX3Byb3RvX18gPSBwcm90bztcbiAgICAgICAgZWxzZSBzZXQoTywgcHJvdG8pO1xuICAgICAgICByZXR1cm4gTztcbiAgICAgIH07XG4gICAgfSh7fSwgZmFsc2UpIDogdW5kZWZpbmVkKSxcbiAgY2hlY2s6IGNoZWNrXG59O1xuIiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgc2V0UHJvdG90eXBlT2Y6IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldCB9KTtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3Quc2V0UHJvdG90eXBlT2Y7XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXyc7XG52YXIgc3RvcmUgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB7fSk7XG59O1xuIiwidmFyIHN0b3JlID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ3drcycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLlN5bWJvbDtcbnZhciBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xuXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG4kZXhwb3J0cy5zdG9yZSA9IHN0b3JlO1xuIiwiLy8gZ2V0dGluZyB0YWcgZnJvbSAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcbi8vIEVTMyB3cm9uZyBoZXJlXG52YXIgQVJHID0gY29mKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA9PSAnQXJndW1lbnRzJztcblxuLy8gZmFsbGJhY2sgZm9yIElFMTEgU2NyaXB0IEFjY2VzcyBEZW5pZWQgZXJyb3JcbnZhciB0cnlHZXQgPSBmdW5jdGlvbiAoaXQsIGtleSkge1xuICB0cnkge1xuICAgIHJldHVybiBpdFtrZXldO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHZhciBPLCBULCBCO1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCA/ICdVbmRlZmluZWQnIDogaXQgPT09IG51bGwgPyAnTnVsbCdcbiAgICAvLyBAQHRvU3RyaW5nVGFnIGNhc2VcbiAgICA6IHR5cGVvZiAoVCA9IHRyeUdldChPID0gT2JqZWN0KGl0KSwgVEFHKSkgPT0gJ3N0cmluZycgPyBUXG4gICAgLy8gYnVpbHRpblRhZyBjYXNlXG4gICAgOiBBUkcgPyBjb2YoTylcbiAgICAvLyBFUzMgYXJndW1lbnRzIGZhbGxiYWNrXG4gICAgOiAoQiA9IGNvZihPKSkgPT0gJ09iamVjdCcgJiYgdHlwZW9mIE8uY2FsbGVlID09ICdmdW5jdGlvbicgPyAnQXJndW1lbnRzJyA6IEI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciB0ZXN0ID0ge307XG50ZXN0W3JlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpXSA9ICd6JztcbmlmICh0ZXN0ICsgJycgIT0gJ1tvYmplY3Qgel0nKSB7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoT2JqZWN0LnByb3RvdHlwZSwgJ3RvU3RyaW5nJywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuICdbb2JqZWN0ICcgKyBjbGFzc29mKHRoaXMpICsgJ10nO1xuICB9LCB0cnVlKTtcbn1cbiIsIi8vIDcuMS40IFRvSW50ZWdlclxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuLy8gdHJ1ZSAgLT4gU3RyaW5nI2F0XG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRPX1NUUklORykge1xuICByZXR1cm4gZnVuY3Rpb24gKHRoYXQsIHBvcykge1xuICAgIHZhciBzID0gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xuICAgIHZhciBpID0gdG9JbnRlZ2VyKHBvcyk7XG4gICAgdmFyIGwgPSBzLmxlbmd0aDtcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAoaSA8IDAgfHwgaSA+PSBsKSByZXR1cm4gVE9fU1RSSU5HID8gJycgOiB1bmRlZmluZWQ7XG4gICAgYSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuICAgICAgPyBUT19TVFJJTkcgPyBzLmNoYXJBdChpKSA6IGFcbiAgICAgIDogVE9fU1RSSU5HID8gcy5zbGljZShpLCBpICsgMikgOiAoYSAtIDB4ZDgwMCA8PCAxMCkgKyAoYiAtIDB4ZGMwMCkgKyAweDEwMDAwO1xuICB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZmFsc2U7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwiLy8gNy4xLjE1IFRvTGVuZ3RoXG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIG1pbiA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID4gMCA/IG1pbih0b0ludGVnZXIoaXQpLCAweDFmZmZmZmZmZmZmZmZmKSA6IDA7IC8vIHBvdygyLCA1MykgLSAxID09IDkwMDcxOTkyNTQ3NDA5OTFcbn07XG4iLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIG1heCA9IE1hdGgubWF4O1xudmFyIG1pbiA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaW5kZXgsIGxlbmd0aCkge1xuICBpbmRleCA9IHRvSW50ZWdlcihpbmRleCk7XG4gIHJldHVybiBpbmRleCA8IDAgPyBtYXgoaW5kZXggKyBsZW5ndGgsIDApIDogbWluKGluZGV4LCBsZW5ndGgpO1xufTtcbiIsIi8vIGZhbHNlIC0+IEFycmF5I2luZGV4T2Zcbi8vIHRydWUgIC0+IEFycmF5I2luY2x1ZGVzXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKElTX0lOQ0xVREVTKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGVsLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCgkdGhpcyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSB0b0Fic29sdXRlSW5kZXgoZnJvbUluZGV4LCBsZW5ndGgpO1xuICAgIHZhciB2YWx1ZTtcbiAgICAvLyBBcnJheSNpbmNsdWRlcyB1c2VzIFNhbWVWYWx1ZVplcm8gZXF1YWxpdHkgYWxnb3JpdGhtXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIGlmIChJU19JTkNMVURFUyAmJiBlbCAhPSBlbCkgd2hpbGUgKGxlbmd0aCA+IGluZGV4KSB7XG4gICAgICB2YWx1ZSA9IE9baW5kZXgrK107XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICBpZiAodmFsdWUgIT0gdmFsdWUpIHJldHVybiB0cnVlO1xuICAgIC8vIEFycmF5I2luZGV4T2YgaWdub3JlcyBob2xlcywgQXJyYXkjaW5jbHVkZXMgLSBub3RcbiAgICB9IGVsc2UgZm9yICg7bGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIGlmIChJU19JTkNMVURFUyB8fCBpbmRleCBpbiBPKSB7XG4gICAgICBpZiAoT1tpbmRleF0gPT09IGVsKSByZXR1cm4gSVNfSU5DTFVERVMgfHwgaW5kZXggfHwgMDtcbiAgICB9IHJldHVybiAhSVNfSU5DTFVERVMgJiYgLTE7XG4gIH07XG59O1xuIiwidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdrZXlzJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi9fdWlkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIHNoYXJlZFtrZXldIHx8IChzaGFyZWRba2V5XSA9IHVpZChrZXkpKTtcbn07XG4iLCJ2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSBpZiAoa2V5ICE9IElFX1BST1RPKSBoYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSBpZiAoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKSB7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwiLy8gMTkuMS4yLjE0IC8gMTUuMi4zLjE0IE9iamVjdC5rZXlzKE8pXG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cy1pbnRlcm5hbCcpO1xudmFyIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIGtleXMoTykge1xuICByZXR1cm4gJGtleXMoTywgZW51bUJ1Z0tleXMpO1xufTtcbiIsInZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzIDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKSB7XG4gIGFuT2JqZWN0KE8pO1xuICB2YXIga2V5cyA9IGdldEtleXMoUHJvcGVydGllcyk7XG4gIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgdmFyIGkgPSAwO1xuICB2YXIgUDtcbiAgd2hpbGUgKGxlbmd0aCA+IGkpIGRQLmYoTywgUCA9IGtleXNbaSsrXSwgUHJvcGVydGllc1tQXSk7XG4gIHJldHVybiBPO1xufTtcbiIsInZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xubW9kdWxlLmV4cG9ydHMgPSBkb2N1bWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4iLCIvLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGRQcyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpO1xuICB2YXIgaSA9IGVudW1CdWdLZXlzLmxlbmd0aDtcbiAgdmFyIGx0ID0gJzwnO1xuICB2YXIgZ3QgPSAnPic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZSAoaS0tKSBkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoTyAhPT0gbnVsbCkge1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHkoKTtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG4iLCJ2YXIgZGVmID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIHRhZywgc3RhdCkge1xuICBpZiAoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSkgZGVmKGl0LCBUQUcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnIH0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGUgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJyk7XG52YXIgZGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2hpZGUnKShJdGVyYXRvclByb3RvdHlwZSwgcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCkge1xuICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHsgbmV4dDogZGVzY3JpcHRvcigxLCBuZXh0KSB9KTtcbiAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG59O1xuIiwiLy8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyAxOS4xLjIuOSAvIDE1LjIuMy4yIE9iamVjdC5nZXRQcm90b3R5cGVPZihPKVxudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSUVfUFJPVE8gPSByZXF1aXJlKCcuL19zaGFyZWQta2V5JykoJ0lFX1BST1RPJyk7XG52YXIgT2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiAoTykge1xuICBPID0gdG9PYmplY3QoTyk7XG4gIGlmIChoYXMoTywgSUVfUFJPVE8pKSByZXR1cm4gT1tJRV9QUk9UT107XG4gIGlmICh0eXBlb2YgTy5jb25zdHJ1Y3RvciA9PSAnZnVuY3Rpb24nICYmIE8gaW5zdGFuY2VvZiBPLmNvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIE8uY29uc3RydWN0b3IucHJvdG90eXBlO1xuICB9IHJldHVybiBPIGluc3RhbmNlb2YgT2JqZWN0ID8gT2JqZWN0UHJvdG8gOiBudWxsO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciAkaXRlckNyZWF0ZSA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQlVHR1kgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSk7IC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbnZhciBGRl9JVEVSQVRPUiA9ICdAQGl0ZXJhdG9yJztcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCkge1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoa2luZCkge1xuICAgIGlmICghQlVHR1kgJiYga2luZCBpbiBwcm90bykgcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgPSBOQU1FICsgJyBJdGVyYXRvcic7XG4gIHZhciBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVM7XG4gIHZhciBWQUxVRVNfQlVHID0gZmFsc2U7XG4gIHZhciBwcm90byA9IEJhc2UucHJvdG90eXBlO1xuICB2YXIgJG5hdGl2ZSA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXTtcbiAgdmFyICRkZWZhdWx0ID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVCk7XG4gIHZhciAkZW50cmllcyA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWQ7XG4gIHZhciAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZTtcbiAgdmFyIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYgKCRhbnlOYXRpdmUpIHtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSgpKSk7XG4gICAgaWYgKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlICYmIEl0ZXJhdG9yUHJvdG90eXBlLm5leHQpIHtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZiAoIUxJQlJBUlkgJiYgIWhhcyhJdGVyYXRvclByb3RvdHlwZSwgSVRFUkFUT1IpKSBoaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYgKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUykge1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZiAoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpIHtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddID0gcmV0dXJuVGhpcztcbiAgaWYgKERFRkFVTFQpIHtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6IElTX1NFVCA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoa2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIGlmICghKGtleSBpbiBwcm90bykpIHJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24gKGl0ZXJhdGVkKSB7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIgaW5kZXggPSB0aGlzLl9pO1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBPLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4geyB2YWx1ZTogcG9pbnQsIGRvbmU6IGZhbHNlIH07XG59KTtcbiIsIi8vIDIyLjEuMy4zMSBBcnJheS5wcm90b3R5cGVbQEB1bnNjb3BhYmxlc11cbnZhciBVTlNDT1BBQkxFUyA9IHJlcXVpcmUoJy4vX3drcycpKCd1bnNjb3BhYmxlcycpO1xudmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5pZiAoQXJyYXlQcm90b1tVTlNDT1BBQkxFU10gPT0gdW5kZWZpbmVkKSByZXF1aXJlKCcuL19oaWRlJykoQXJyYXlQcm90bywgVU5TQ09QQUJMRVMsIHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICBBcnJheVByb3RvW1VOU0NPUEFCTEVTXVtrZXldID0gdHJ1ZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChkb25lLCB2YWx1ZSkge1xuICByZXR1cm4geyB2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZSB9O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhZGRUb1Vuc2NvcGFibGVzID0gcmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJyk7XG52YXIgc3RlcCA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKEFycmF5LCAnQXJyYXknLCBmdW5jdGlvbiAoaXRlcmF0ZWQsIGtpbmQpIHtcbiAgdGhpcy5fdCA9IHRvSU9iamVjdChpdGVyYXRlZCk7IC8vIHRhcmdldFxuICB0aGlzLl9pID0gMDsgICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgLy8ga2luZFxuLy8gMjIuMS41LjIuMSAlQXJyYXlJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbiAoKSB7XG4gIHZhciBPID0gdGhpcy5fdDtcbiAgdmFyIGtpbmQgPSB0aGlzLl9rO1xuICB2YXIgaW5kZXggPSB0aGlzLl9pKys7XG4gIGlmICghTyB8fCBpbmRleCA+PSBPLmxlbmd0aCkge1xuICAgIHRoaXMuX3QgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHN0ZXAoMSk7XG4gIH1cbiAgaWYgKGtpbmQgPT0gJ2tleXMnKSByZXR1cm4gc3RlcCgwLCBpbmRleCk7XG4gIGlmIChraW5kID09ICd2YWx1ZXMnKSByZXR1cm4gc3RlcCgwLCBPW2luZGV4XSk7XG4gIHJldHVybiBzdGVwKDAsIFtpbmRleCwgT1tpbmRleF1dKTtcbn0sICd2YWx1ZXMnKTtcblxuLy8gYXJndW1lbnRzTGlzdFtAQGl0ZXJhdG9yXSBpcyAlQXJyYXlQcm90b192YWx1ZXMlICg5LjQuNC42LCA5LjQuNC43KVxuSXRlcmF0b3JzLkFyZ3VtZW50cyA9IEl0ZXJhdG9ycy5BcnJheTtcblxuYWRkVG9VbnNjb3BhYmxlcygna2V5cycpO1xuYWRkVG9VbnNjb3BhYmxlcygndmFsdWVzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCdlbnRyaWVzJyk7XG4iLCJ2YXIgJGl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vZXM2LmFycmF5Lml0ZXJhdG9yJyk7XG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgd2tzID0gcmVxdWlyZSgnLi9fd2tzJyk7XG52YXIgSVRFUkFUT1IgPSB3a3MoJ2l0ZXJhdG9yJyk7XG52YXIgVE9fU1RSSU5HX1RBRyA9IHdrcygndG9TdHJpbmdUYWcnKTtcbnZhciBBcnJheVZhbHVlcyA9IEl0ZXJhdG9ycy5BcnJheTtcblxudmFyIERPTUl0ZXJhYmxlcyA9IHtcbiAgQ1NTUnVsZUxpc3Q6IHRydWUsIC8vIFRPRE86IE5vdCBzcGVjIGNvbXBsaWFudCwgc2hvdWxkIGJlIGZhbHNlLlxuICBDU1NTdHlsZURlY2xhcmF0aW9uOiBmYWxzZSxcbiAgQ1NTVmFsdWVMaXN0OiBmYWxzZSxcbiAgQ2xpZW50UmVjdExpc3Q6IGZhbHNlLFxuICBET01SZWN0TGlzdDogZmFsc2UsXG4gIERPTVN0cmluZ0xpc3Q6IGZhbHNlLFxuICBET01Ub2tlbkxpc3Q6IHRydWUsXG4gIERhdGFUcmFuc2Zlckl0ZW1MaXN0OiBmYWxzZSxcbiAgRmlsZUxpc3Q6IGZhbHNlLFxuICBIVE1MQWxsQ29sbGVjdGlvbjogZmFsc2UsXG4gIEhUTUxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTEZvcm1FbGVtZW50OiBmYWxzZSxcbiAgSFRNTFNlbGVjdEVsZW1lbnQ6IGZhbHNlLFxuICBNZWRpYUxpc3Q6IHRydWUsIC8vIFRPRE86IE5vdCBzcGVjIGNvbXBsaWFudCwgc2hvdWxkIGJlIGZhbHNlLlxuICBNaW1lVHlwZUFycmF5OiBmYWxzZSxcbiAgTmFtZWROb2RlTWFwOiBmYWxzZSxcbiAgTm9kZUxpc3Q6IHRydWUsXG4gIFBhaW50UmVxdWVzdExpc3Q6IGZhbHNlLFxuICBQbHVnaW46IGZhbHNlLFxuICBQbHVnaW5BcnJheTogZmFsc2UsXG4gIFNWR0xlbmd0aExpc3Q6IGZhbHNlLFxuICBTVkdOdW1iZXJMaXN0OiBmYWxzZSxcbiAgU1ZHUGF0aFNlZ0xpc3Q6IGZhbHNlLFxuICBTVkdQb2ludExpc3Q6IGZhbHNlLFxuICBTVkdTdHJpbmdMaXN0OiBmYWxzZSxcbiAgU1ZHVHJhbnNmb3JtTGlzdDogZmFsc2UsXG4gIFNvdXJjZUJ1ZmZlckxpc3Q6IGZhbHNlLFxuICBTdHlsZVNoZWV0TGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIFRleHRUcmFja0N1ZUxpc3Q6IGZhbHNlLFxuICBUZXh0VHJhY2tMaXN0OiBmYWxzZSxcbiAgVG91Y2hMaXN0OiBmYWxzZVxufTtcblxuZm9yICh2YXIgY29sbGVjdGlvbnMgPSBnZXRLZXlzKERPTUl0ZXJhYmxlcyksIGkgPSAwOyBpIDwgY29sbGVjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgdmFyIE5BTUUgPSBjb2xsZWN0aW9uc1tpXTtcbiAgdmFyIGV4cGxpY2l0ID0gRE9NSXRlcmFibGVzW05BTUVdO1xuICB2YXIgQ29sbGVjdGlvbiA9IGdsb2JhbFtOQU1FXTtcbiAgdmFyIHByb3RvID0gQ29sbGVjdGlvbiAmJiBDb2xsZWN0aW9uLnByb3RvdHlwZTtcbiAgdmFyIGtleTtcbiAgaWYgKHByb3RvKSB7XG4gICAgaWYgKCFwcm90b1tJVEVSQVRPUl0pIGhpZGUocHJvdG8sIElURVJBVE9SLCBBcnJheVZhbHVlcyk7XG4gICAgaWYgKCFwcm90b1tUT19TVFJJTkdfVEFHXSkgaGlkZShwcm90bywgVE9fU1RSSU5HX1RBRywgTkFNRSk7XG4gICAgSXRlcmF0b3JzW05BTUVdID0gQXJyYXlWYWx1ZXM7XG4gICAgaWYgKGV4cGxpY2l0KSBmb3IgKGtleSBpbiAkaXRlcmF0b3JzKSBpZiAoIXByb3RvW2tleV0pIHJlZGVmaW5lKHByb3RvLCBrZXksICRpdGVyYXRvcnNba2V5XSwgdHJ1ZSk7XG4gIH1cbn1cbiIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHNyYywgc2FmZSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSByZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpIHtcbiAgaWYgKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkKSBhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIvLyBjaGVjayBvbiBkZWZhdWx0IEFycmF5IGl0ZXJhdG9yXG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgIT09IHVuZGVmaW5lZCAmJiAoSXRlcmF0b3JzLkFycmF5ID09PSBpdCB8fCBBcnJheVByb3RvW0lURVJBVE9SXSA9PT0gaXQpO1xufTtcbiIsInZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvcmUnKS5nZXRJdGVyYXRvck1ldGhvZCA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXQgIT0gdW5kZWZpbmVkKSByZXR1cm4gaXRbSVRFUkFUT1JdXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxuICAgIHx8IEl0ZXJhdG9yc1tjbGFzc29mKGl0KV07XG59O1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbnZhciBCUkVBSyA9IHt9O1xudmFyIFJFVFVSTiA9IHt9O1xudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgZW50cmllcywgZm4sIHRoYXQsIElURVJBVE9SKSB7XG4gIHZhciBpdGVyRm4gPSBJVEVSQVRPUiA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXJhYmxlOyB9IDogZ2V0SXRlckZuKGl0ZXJhYmxlKTtcbiAgdmFyIGYgPSBjdHgoZm4sIHRoYXQsIGVudHJpZXMgPyAyIDogMSk7XG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsZW5ndGgsIHN0ZXAsIGl0ZXJhdG9yLCByZXN1bHQ7XG4gIGlmICh0eXBlb2YgaXRlckZuICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYgKGlzQXJyYXlJdGVyKGl0ZXJGbikpIGZvciAobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICByZXN1bHQgPSBlbnRyaWVzID8gZihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBmKGl0ZXJhYmxlW2luZGV4XSk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoaXRlcmFibGUpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7KSB7XG4gICAgcmVzdWx0ID0gY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5leHBvcnRzLkJSRUFLID0gQlJFQUs7XG5leHBvcnRzLlJFVFVSTiA9IFJFVFVSTjtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XG4gIGlmIChERVNDUklQVE9SUyAmJiBDICYmICFDW1NQRUNJRVNdKSBkUC5mKEMsIFNQRUNJRVMsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTtcbiIsInZhciBNRVRBID0gcmVxdWlyZSgnLi9fdWlkJykoJ21ldGEnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHNldERlc2MgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGlkID0gMDtcbnZhciBpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlIHx8IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xudmFyIEZSRUVaRSA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGlzRXh0ZW5zaWJsZShPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pKTtcbn0pO1xudmFyIHNldE1ldGEgPSBmdW5jdGlvbiAoaXQpIHtcbiAgc2V0RGVzYyhpdCwgTUVUQSwgeyB2YWx1ZToge1xuICAgIGk6ICdPJyArICsraWQsIC8vIG9iamVjdCBJRFxuICAgIHc6IHt9ICAgICAgICAgIC8vIHdlYWsgY29sbGVjdGlvbnMgSURzXG4gIH0gfSk7XG59O1xudmFyIGZhc3RLZXkgPSBmdW5jdGlvbiAoaXQsIGNyZWF0ZSkge1xuICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG4gIGlmICghaXNPYmplY3QoaXQpKSByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnID8gaXQgOiAodHlwZW9mIGl0ID09ICdzdHJpbmcnID8gJ1MnIDogJ1AnKSArIGl0O1xuICBpZiAoIWhhcyhpdCwgTUVUQSkpIHtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmICghaXNFeHRlbnNpYmxlKGl0KSkgcmV0dXJuICdGJztcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gJ0UnO1xuICAgIC8vIGFkZCBtaXNzaW5nIG1ldGFkYXRhXG4gICAgc2V0TWV0YShpdCk7XG4gIC8vIHJldHVybiBvYmplY3QgSURcbiAgfSByZXR1cm4gaXRbTUVUQV0uaTtcbn07XG52YXIgZ2V0V2VhayA9IGZ1bmN0aW9uIChpdCwgY3JlYXRlKSB7XG4gIGlmICghaGFzKGl0LCBNRVRBKSkge1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYgKCFpc0V4dGVuc2libGUoaXQpKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIGhhc2ggd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSByZXR1cm4gaXRbTUVUQV0udztcbn07XG4vLyBhZGQgbWV0YWRhdGEgb24gZnJlZXplLWZhbWlseSBtZXRob2RzIGNhbGxpbmdcbnZhciBvbkZyZWV6ZSA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoRlJFRVpFICYmIG1ldGEuTkVFRCAmJiBpc0V4dGVuc2libGUoaXQpICYmICFoYXMoaXQsIE1FVEEpKSBzZXRNZXRhKGl0KTtcbiAgcmV0dXJuIGl0O1xufTtcbnZhciBtZXRhID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gIEtFWTogTUVUQSxcbiAgTkVFRDogZmFsc2UsXG4gIGZhc3RLZXk6IGZhc3RLZXksXG4gIGdldFdlYWs6IGdldFdlYWssXG4gIG9uRnJlZXplOiBvbkZyZWV6ZVxufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFRZUEUpIHtcbiAgaWYgKCFpc09iamVjdChpdCkgfHwgaXQuX3QgIT09IFRZUEUpIHRocm93IFR5cGVFcnJvcignSW5jb21wYXRpYmxlIHJlY2VpdmVyLCAnICsgVFlQRSArICcgcmVxdWlyZWQhJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgJGl0ZXJEZWZpbmUgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpO1xudmFyIHN0ZXAgPSByZXF1aXJlKCcuL19pdGVyLXN0ZXAnKTtcbnZhciBzZXRTcGVjaWVzID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgZmFzdEtleSA9IHJlcXVpcmUoJy4vX21ldGEnKS5mYXN0S2V5O1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIFNJWkUgPSBERVNDUklQVE9SUyA/ICdfcycgOiAnc2l6ZSc7XG5cbnZhciBnZXRFbnRyeSA9IGZ1bmN0aW9uICh0aGF0LCBrZXkpIHtcbiAgLy8gZmFzdCBjYXNlXG4gIHZhciBpbmRleCA9IGZhc3RLZXkoa2V5KTtcbiAgdmFyIGVudHJ5O1xuICBpZiAoaW5kZXggIT09ICdGJykgcmV0dXJuIHRoYXQuX2lbaW5kZXhdO1xuICAvLyBmcm96ZW4gb2JqZWN0IGNhc2VcbiAgZm9yIChlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICBpZiAoZW50cnkuayA9PSBrZXkpIHJldHVybiBlbnRyeTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbiAod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUikge1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgaXRlcmFibGUpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XG4gICAgICB0aGF0Ll90ID0gTkFNRTsgICAgICAgICAvLyBjb2xsZWN0aW9uIHR5cGVcbiAgICAgIHRoYXQuX2kgPSBjcmVhdGUobnVsbCk7IC8vIGluZGV4XG4gICAgICB0aGF0Ll9mID0gdW5kZWZpbmVkOyAgICAvLyBmaXJzdCBlbnRyeVxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgICAgLy8gbGFzdCBlbnRyeVxuICAgICAgdGhhdFtTSVpFXSA9IDA7ICAgICAgICAgLy8gc2l6ZVxuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4xLjMuMSBNYXAucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIC8vIDIzLjIuMy4yIFNldC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgICAgICBmb3IgKHZhciB0aGF0ID0gdmFsaWRhdGUodGhpcywgTkFNRSksIGRhdGEgPSB0aGF0Ll9pLCBlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICAgICAgICBlbnRyeS5yID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoZW50cnkucCkgZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgZGF0YVtlbnRyeS5pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhhdFtTSVpFXSA9IDA7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuMi4zLjQgU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgdGhhdCA9IHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICB2YXIgbmV4dCA9IGVudHJ5Lm47XG4gICAgICAgICAgdmFyIHByZXYgPSBlbnRyeS5wO1xuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll9pW2VudHJ5LmldO1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmIChwcmV2KSBwcmV2Lm4gPSBuZXh0O1xuICAgICAgICAgIGlmIChuZXh0KSBuZXh0LnAgPSBwcmV2O1xuICAgICAgICAgIGlmICh0aGF0Ll9mID09IGVudHJ5KSB0aGF0Ll9mID0gbmV4dDtcbiAgICAgICAgICBpZiAodGhhdC5fbCA9PSBlbnRyeSkgdGhhdC5fbCA9IHByZXY7XG4gICAgICAgICAgdGhhdFtTSVpFXS0tO1xuICAgICAgICB9IHJldHVybiAhIWVudHJ5O1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjIuMy42IFNldC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgLy8gMjMuMS4zLjUgTWFwLnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gICAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGF0ID0gdW5kZWZpbmVkICovKSB7XG4gICAgICAgIHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgMyk7XG4gICAgICAgIHZhciBlbnRyeTtcbiAgICAgICAgd2hpbGUgKGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhpcy5fZikge1xuICAgICAgICAgIGYoZW50cnkudiwgZW50cnkuaywgdGhpcyk7XG4gICAgICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICAgICAgd2hpbGUgKGVudHJ5ICYmIGVudHJ5LnIpIGVudHJ5ID0gZW50cnkucDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIDIzLjEuMy43IE1hcC5wcm90b3R5cGUuaGFzKGtleSlcbiAgICAgIC8vIDIzLjIuMy43IFNldC5wcm90b3R5cGUuaGFzKHZhbHVlKVxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KSB7XG4gICAgICAgIHJldHVybiAhIWdldEVudHJ5KHZhbGlkYXRlKHRoaXMsIE5BTUUpLCBrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChERVNDUklQVE9SUykgZFAoQy5wcm90b3R5cGUsICdzaXplJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZSh0aGlzLCBOQU1FKVtTSVpFXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbiAodGhhdCwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XG4gICAgdmFyIHByZXYsIGluZGV4O1xuICAgIC8vIGNoYW5nZSBleGlzdGluZyBlbnRyeVxuICAgIGlmIChlbnRyeSkge1xuICAgICAgZW50cnkudiA9IHZhbHVlO1xuICAgIC8vIGNyZWF0ZSBuZXcgZW50cnlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhhdC5fbCA9IGVudHJ5ID0ge1xuICAgICAgICBpOiBpbmRleCA9IGZhc3RLZXkoa2V5LCB0cnVlKSwgLy8gPC0gaW5kZXhcbiAgICAgICAgazoga2V5LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIGtleVxuICAgICAgICB2OiB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gdmFsdWVcbiAgICAgICAgcDogcHJldiA9IHRoYXQuX2wsICAgICAgICAgICAgIC8vIDwtIHByZXZpb3VzIGVudHJ5XG4gICAgICAgIG46IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAvLyA8LSBuZXh0IGVudHJ5XG4gICAgICAgIHI6IGZhbHNlICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSByZW1vdmVkXG4gICAgICB9O1xuICAgICAgaWYgKCF0aGF0Ll9mKSB0aGF0Ll9mID0gZW50cnk7XG4gICAgICBpZiAocHJldikgcHJldi5uID0gZW50cnk7XG4gICAgICB0aGF0W1NJWkVdKys7XG4gICAgICAvLyBhZGQgdG8gaW5kZXhcbiAgICAgIGlmIChpbmRleCAhPT0gJ0YnKSB0aGF0Ll9pW2luZGV4XSA9IGVudHJ5O1xuICAgIH0gcmV0dXJuIHRoYXQ7XG4gIH0sXG4gIGdldEVudHJ5OiBnZXRFbnRyeSxcbiAgc2V0U3Ryb25nOiBmdW5jdGlvbiAoQywgTkFNRSwgSVNfTUFQKSB7XG4gICAgLy8gYWRkIC5rZXlzLCAudmFsdWVzLCAuZW50cmllcywgW0BAaXRlcmF0b3JdXG4gICAgLy8gMjMuMS4zLjQsIDIzLjEuMy44LCAyMy4xLjMuMTEsIDIzLjEuMy4xMiwgMjMuMi4zLjUsIDIzLjIuMy44LCAyMy4yLjMuMTAsIDIzLjIuMy4xMVxuICAgICRpdGVyRGVmaW5lKEMsIE5BTUUsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICAgICAgdGhpcy5fdCA9IHZhbGlkYXRlKGl0ZXJhdGVkLCBOQU1FKTsgLy8gdGFyZ2V0XG4gICAgICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgICAgICAvLyBraW5kXG4gICAgICB0aGlzLl9sID0gdW5kZWZpbmVkOyAgICAgICAgICAgICAgICAvLyBwcmV2aW91c1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBraW5kID0gdGhhdC5faztcbiAgICAgIHZhciBlbnRyeSA9IHRoYXQuX2w7XG4gICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgIHdoaWxlIChlbnRyeSAmJiBlbnRyeS5yKSBlbnRyeSA9IGVudHJ5LnA7XG4gICAgICAvLyBnZXQgbmV4dCBlbnRyeVxuICAgICAgaWYgKCF0aGF0Ll90IHx8ICEodGhhdC5fbCA9IGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhhdC5fdC5fZikpIHtcbiAgICAgICAgLy8gb3IgZmluaXNoIHRoZSBpdGVyYXRpb25cbiAgICAgICAgdGhhdC5fdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHN0ZXAoMSk7XG4gICAgICB9XG4gICAgICAvLyByZXR1cm4gc3RlcCBieSBraW5kXG4gICAgICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGVudHJ5LmspO1xuICAgICAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIGVudHJ5LnYpO1xuICAgICAgcmV0dXJuIHN0ZXAoMCwgW2VudHJ5LmssIGVudHJ5LnZdKTtcbiAgICB9LCBJU19NQVAgPyAnZW50cmllcycgOiAndmFsdWVzJywgIUlTX01BUCwgdHJ1ZSk7XG5cbiAgICAvLyBhZGQgW0BAc3BlY2llc10sIDIzLjEuMi4yLCAyMy4yLjIuMlxuICAgIHNldFNwZWNpZXMoTkFNRSk7XG4gIH1cbn07XG4iLCJ2YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbiAoKSB7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYywgc2tpcENsb3NpbmcpIHtcbiAgaWYgKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IFs3XTtcbiAgICB2YXIgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB7IGRvbmU6IHNhZmUgPSB0cnVlIH07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKS5zZXQ7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0aGF0LCB0YXJnZXQsIEMpIHtcbiAgdmFyIFMgPSB0YXJnZXQuY29uc3RydWN0b3I7XG4gIHZhciBQO1xuICBpZiAoUyAhPT0gQyAmJiB0eXBlb2YgUyA9PSAnZnVuY3Rpb24nICYmIChQID0gUy5wcm90b3R5cGUpICE9PSBDLnByb3RvdHlwZSAmJiBpc09iamVjdChQKSAmJiBzZXRQcm90b3R5cGVPZikge1xuICAgIHNldFByb3RvdHlwZU9mKHRoYXQsIFApO1xuICB9IHJldHVybiB0aGF0O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyICRpdGVyRGV0ZWN0ID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKSB7XG4gIHZhciBCYXNlID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgQyA9IEJhc2U7XG4gIHZhciBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCc7XG4gIHZhciBwcm90byA9IEMgJiYgQy5wcm90b3R5cGU7XG4gIHZhciBPID0ge307XG4gIHZhciBmaXhNZXRob2QgPSBmdW5jdGlvbiAoS0VZKSB7XG4gICAgdmFyIGZuID0gcHJvdG9bS0VZXTtcbiAgICByZWRlZmluZShwcm90bywgS0VZLFxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdnZXQnID8gZnVuY3Rpb24gZ2V0KGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnYWRkJyA/IGZ1bmN0aW9uIGFkZChhKSB7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYikgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSwgYik7IHJldHVybiB0aGlzOyB9XG4gICAgKTtcbiAgfTtcbiAgaWYgKHR5cGVvZiBDICE9ICdmdW5jdGlvbicgfHwgIShJU19XRUFLIHx8IHByb3RvLmZvckVhY2ggJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgQygpLmVudHJpZXMoKS5uZXh0KCk7XG4gIH0pKSkge1xuICAgIC8vIGNyZWF0ZSBjb2xsZWN0aW9uIGNvbnN0cnVjdG9yXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gICAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICB2YXIgSEFTTlRfQ0hBSU5JTkcgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlO1xuICAgIC8vIFY4IH4gIENocm9taXVtIDQwLSB3ZWFrLWNvbGxlY3Rpb25zIHRocm93cyBvbiBwcmltaXRpdmVzLCBidXQgc2hvdWxkIHJldHVybiBmYWxzZVxuICAgIHZhciBUSFJPV1NfT05fUFJJTUlUSVZFUyA9IGZhaWxzKGZ1bmN0aW9uICgpIHsgaW5zdGFuY2UuaGFzKDEpOyB9KTtcbiAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgdmFyIEFDQ0VQVF9JVEVSQUJMRVMgPSAkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikgeyBuZXcgQyhpdGVyKTsgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgdmFyIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgIHZhciAkaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgICAgdmFyIGluZGV4ID0gNTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSAkaW5zdGFuY2VbQURERVJdKGluZGV4LCBpbmRleCk7XG4gICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgIH0pO1xuICAgIGlmICghQUNDRVBUX0lURVJBQkxFUykge1xuICAgICAgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRhcmdldCwgaXRlcmFibGUpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0YXJnZXQsIEMsIE5BTUUpO1xuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlKCksIHRhcmdldCwgQyk7XG4gICAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgICB9KTtcbiAgICAgIEMucHJvdG90eXBlID0gcHJvdG87XG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XG4gICAgfVxuICAgIGlmIChUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKSB7XG4gICAgICBmaXhNZXRob2QoJ2RlbGV0ZScpO1xuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcbiAgICAgIElTX01BUCAmJiBmaXhNZXRob2QoJ2dldCcpO1xuICAgIH1cbiAgICBpZiAoQlVHR1lfWkVSTyB8fCBIQVNOVF9DSEFJTklORykgZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmIChJU19XRUFLICYmIHByb3RvLmNsZWFyKSBkZWxldGUgcHJvdG8uY2xlYXI7XG4gIH1cblxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcblxuICBPW05BTUVdID0gQztcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XG5cbiAgaWYgKCFJU19XRUFLKSBjb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0VUID0gJ1NldCc7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFNFVCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuMi4zLjEgU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgU0VUKSwgdmFsdWUgPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcpO1xuIiwidmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXIsIElURVJBVE9SKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yT2YoaXRlciwgZmFsc2UsIHJlc3VsdC5wdXNoLCByZXN1bHQsIElURVJBVE9SKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciBmcm9tID0gcmVxdWlyZSgnLi9fYXJyYXktZnJvbS1pdGVyYWJsZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTkFNRSkge1xuICByZXR1cm4gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgIGlmIChjbGFzc29mKHRoaXMpICE9IE5BTUUpIHRocm93IFR5cGVFcnJvcihOQU1FICsgXCIjdG9KU09OIGlzbid0IGdlbmVyaWNcIik7XG4gICAgcmV0dXJuIGZyb20odGhpcyk7XG4gIH07XG59O1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdTZXQnLCB7IHRvSlNPTjogcmVxdWlyZSgnLi9fY29sbGVjdGlvbi10by1qc29uJykoJ1NldCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ09MTEVDVElPTikge1xuICAkZXhwb3J0KCRleHBvcnQuUywgQ09MTEVDVElPTiwgeyBvZjogZnVuY3Rpb24gb2YoKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIEEgPSBBcnJheShsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGgtLSkgQVtsZW5ndGhdID0gYXJndW1lbnRzW2xlbmd0aF07XG4gICAgcmV0dXJuIG5ldyB0aGlzKEEpO1xuICB9IH0pO1xufTtcbiIsIi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS8jc2VjLXNldC5vZlxucmVxdWlyZSgnLi9fc2V0LWNvbGxlY3Rpb24tb2YnKSgnU2V0Jyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDT0xMRUNUSU9OKSB7XG4gICRleHBvcnQoJGV4cG9ydC5TLCBDT0xMRUNUSU9OLCB7IGZyb206IGZ1bmN0aW9uIGZyb20oc291cmNlIC8qICwgbWFwRm4sIHRoaXNBcmcgKi8pIHtcbiAgICB2YXIgbWFwRm4gPSBhcmd1bWVudHNbMV07XG4gICAgdmFyIG1hcHBpbmcsIEEsIG4sIGNiO1xuICAgIGFGdW5jdGlvbih0aGlzKTtcbiAgICBtYXBwaW5nID0gbWFwRm4gIT09IHVuZGVmaW5lZDtcbiAgICBpZiAobWFwcGluZykgYUZ1bmN0aW9uKG1hcEZuKTtcbiAgICBpZiAoc291cmNlID09IHVuZGVmaW5lZCkgcmV0dXJuIG5ldyB0aGlzKCk7XG4gICAgQSA9IFtdO1xuICAgIGlmIChtYXBwaW5nKSB7XG4gICAgICBuID0gMDtcbiAgICAgIGNiID0gY3R4KG1hcEZuLCBhcmd1bWVudHNbMl0sIDIpO1xuICAgICAgZm9yT2Yoc291cmNlLCBmYWxzZSwgZnVuY3Rpb24gKG5leHRJdGVtKSB7XG4gICAgICAgIEEucHVzaChjYihuZXh0SXRlbSwgbisrKSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yT2Yoc291cmNlLCBmYWxzZSwgQS5wdXNoLCBBKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyB0aGlzKEEpO1xuICB9IH0pO1xufTtcbiIsIi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS8jc2VjLXNldC5mcm9tXG5yZXF1aXJlKCcuL19zZXQtY29sbGVjdGlvbi1mcm9tJykoJ1NldCcpO1xuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnNldCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcuc2V0LnRvLWpzb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM3LnNldC5vZicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcuc2V0LmZyb20nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpLlNldDtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBzdHJvbmcgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXN0cm9uZycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIE1BUCA9ICdNYXAnO1xuXG4vLyAyMy4xIE1hcCBPYmplY3RzXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24nKShNQVAsIGZ1bmN0aW9uIChnZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIE1hcCgpIHsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XG59LCB7XG4gIC8vIDIzLjEuMy42IE1hcC5wcm90b3R5cGUuZ2V0KGtleSlcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoa2V5KSB7XG4gICAgdmFyIGVudHJ5ID0gc3Ryb25nLmdldEVudHJ5KHZhbGlkYXRlKHRoaXMsIE1BUCksIGtleSk7XG4gICAgcmV0dXJuIGVudHJ5ICYmIGVudHJ5LnY7XG4gIH0sXG4gIC8vIDIzLjEuMy45IE1hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gc3Ryb25nLmRlZih2YWxpZGF0ZSh0aGlzLCBNQVApLCBrZXkgPT09IDAgPyAwIDoga2V5LCB2YWx1ZSk7XG4gIH1cbn0sIHN0cm9uZywgdHJ1ZSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuUiwgJ01hcCcsIHsgdG9KU09OOiByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXRvLWpzb24nKSgnTWFwJykgfSk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy1tYXAub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ01hcCcpO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnTWFwJyk7XG4iLCJyZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNy5tYXAudG8tanNvbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcubWFwLm9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNy5tYXAuZnJvbScpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi9tb2R1bGVzL19jb3JlJykuTWFwO1xuIiwiLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICByZXR1cm4gY29mKGFyZykgPT0gJ0FycmF5Jztcbn07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3JpZ2luYWwpIHtcbiAgdmFyIEM7XG4gIGlmIChpc0FycmF5KG9yaWdpbmFsKSkge1xuICAgIEMgPSBvcmlnaW5hbC5jb25zdHJ1Y3RvcjtcbiAgICAvLyBjcm9zcy1yZWFsbSBmYWxsYmFja1xuICAgIGlmICh0eXBlb2YgQyA9PSAnZnVuY3Rpb24nICYmIChDID09PSBBcnJheSB8fCBpc0FycmF5KEMucHJvdG90eXBlKSkpIEMgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGlzT2JqZWN0KEMpKSB7XG4gICAgICBDID0gQ1tTUEVDSUVTXTtcbiAgICAgIGlmIChDID09PSBudWxsKSBDID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSByZXR1cm4gQyA9PT0gdW5kZWZpbmVkID8gQXJyYXkgOiBDO1xufTtcbiIsIi8vIDkuNC4yLjMgQXJyYXlTcGVjaWVzQ3JlYXRlKG9yaWdpbmFsQXJyYXksIGxlbmd0aClcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsLCBsZW5ndGgpIHtcbiAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKG9yaWdpbmFsKSkobGVuZ3RoKTtcbn07XG4iLCIvLyAwIC0+IEFycmF5I2ZvckVhY2hcbi8vIDEgLT4gQXJyYXkjbWFwXG4vLyAyIC0+IEFycmF5I2ZpbHRlclxuLy8gMyAtPiBBcnJheSNzb21lXG4vLyA0IC0+IEFycmF5I2V2ZXJ5XG4vLyA1IC0+IEFycmF5I2ZpbmRcbi8vIDYgLT4gQXJyYXkjZmluZEluZGV4XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXNjID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jcmVhdGUnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRZUEUsICRjcmVhdGUpIHtcbiAgdmFyIElTX01BUCA9IFRZUEUgPT0gMTtcbiAgdmFyIElTX0ZJTFRFUiA9IFRZUEUgPT0gMjtcbiAgdmFyIElTX1NPTUUgPSBUWVBFID09IDM7XG4gIHZhciBJU19FVkVSWSA9IFRZUEUgPT0gNDtcbiAgdmFyIElTX0ZJTkRfSU5ERVggPSBUWVBFID09IDY7XG4gIHZhciBOT19IT0xFUyA9IFRZUEUgPT0gNSB8fCBJU19GSU5EX0lOREVYO1xuICB2YXIgY3JlYXRlID0gJGNyZWF0ZSB8fCBhc2M7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGNhbGxiYWNrZm4sIHRoYXQpIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KCR0aGlzKTtcbiAgICB2YXIgc2VsZiA9IElPYmplY3QoTyk7XG4gICAgdmFyIGYgPSBjdHgoY2FsbGJhY2tmbiwgdGhhdCwgMyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKHNlbGYubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciByZXN1bHQgPSBJU19NQVAgPyBjcmVhdGUoJHRoaXMsIGxlbmd0aCkgOiBJU19GSUxURVIgPyBjcmVhdGUoJHRoaXMsIDApIDogdW5kZWZpbmVkO1xuICAgIHZhciB2YWwsIHJlcztcbiAgICBmb3IgKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKykgaWYgKE5PX0hPTEVTIHx8IGluZGV4IGluIHNlbGYpIHtcbiAgICAgIHZhbCA9IHNlbGZbaW5kZXhdO1xuICAgICAgcmVzID0gZih2YWwsIGluZGV4LCBPKTtcbiAgICAgIGlmIChUWVBFKSB7XG4gICAgICAgIGlmIChJU19NQVApIHJlc3VsdFtpbmRleF0gPSByZXM7ICAgLy8gbWFwXG4gICAgICAgIGVsc2UgaWYgKHJlcykgc3dpdGNoIChUWVBFKSB7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgLy8gc29tZVxuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIHZhbDsgICAgICAgICAgICAgIC8vIGZpbmRcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBpbmRleDsgICAgICAgICAgICAvLyBmaW5kSW5kZXhcbiAgICAgICAgICBjYXNlIDI6IHJlc3VsdC5wdXNoKHZhbCk7ICAgICAgICAvLyBmaWx0ZXJcbiAgICAgICAgfSBlbHNlIGlmIChJU19FVkVSWSkgcmV0dXJuIGZhbHNlOyAvLyBldmVyeVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gSVNfRklORF9JTkRFWCA/IC0xIDogSVNfU09NRSB8fCBJU19FVkVSWSA/IElTX0VWRVJZIDogcmVzdWx0O1xuICB9O1xufTtcbiIsImV4cG9ydHMuZiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgZ09QUyA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJyk7XG52YXIgcElFID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciAkYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxuLy8gc2hvdWxkIHdvcmsgd2l0aCBzeW1ib2xzIGFuZCBzaG91bGQgaGF2ZSBkZXRlcm1pbmlzdGljIHByb3BlcnR5IG9yZGVyIChWOCBidWcpXG5tb2R1bGUuZXhwb3J0cyA9ICEkYXNzaWduIHx8IHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICB2YXIgQSA9IHt9O1xuICB2YXIgQiA9IHt9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgdmFyIFMgPSBTeW1ib2woKTtcbiAgdmFyIEsgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3QnO1xuICBBW1NdID0gNztcbiAgSy5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAoaykgeyBCW2tdID0gazsgfSk7XG4gIHJldHVybiAkYXNzaWduKHt9LCBBKVtTXSAhPSA3IHx8IE9iamVjdC5rZXlzKCRhc3NpZ24oe30sIEIpKS5qb2luKCcnKSAhPSBLO1xufSkgPyBmdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzb3VyY2UpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICB2YXIgVCA9IHRvT2JqZWN0KHRhcmdldCk7XG4gIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGluZGV4ID0gMTtcbiAgdmFyIGdldFN5bWJvbHMgPSBnT1BTLmY7XG4gIHZhciBpc0VudW0gPSBwSUUuZjtcbiAgd2hpbGUgKGFMZW4gPiBpbmRleCkge1xuICAgIHZhciBTID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pO1xuICAgIHZhciBrZXlzID0gZ2V0U3ltYm9scyA/IGdldEtleXMoUykuY29uY2F0KGdldFN5bWJvbHMoUykpIDogZ2V0S2V5cyhTKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBrZXk7XG4gICAgd2hpbGUgKGxlbmd0aCA+IGopIGlmIChpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKSBUW2tleV0gPSBTW2tleV07XG4gIH0gcmV0dXJuIFQ7XG59IDogJGFzc2lnbjtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGdldFdlYWsgPSByZXF1aXJlKCcuL19tZXRhJykuZ2V0V2VhaztcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBjcmVhdGVBcnJheU1ldGhvZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKTtcbnZhciAkaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgYXJyYXlGaW5kID0gY3JlYXRlQXJyYXlNZXRob2QoNSk7XG52YXIgYXJyYXlGaW5kSW5kZXggPSBjcmVhdGVBcnJheU1ldGhvZCg2KTtcbnZhciBpZCA9IDA7XG5cbi8vIGZhbGxiYWNrIGZvciB1bmNhdWdodCBmcm96ZW4ga2V5c1xudmFyIHVuY2F1Z2h0RnJvemVuU3RvcmUgPSBmdW5jdGlvbiAodGhhdCkge1xuICByZXR1cm4gdGhhdC5fbCB8fCAodGhhdC5fbCA9IG5ldyBVbmNhdWdodEZyb3plblN0b3JlKCkpO1xufTtcbnZhciBVbmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmEgPSBbXTtcbn07XG52YXIgZmluZFVuY2F1Z2h0RnJvemVuID0gZnVuY3Rpb24gKHN0b3JlLCBrZXkpIHtcbiAgcmV0dXJuIGFycmF5RmluZChzdG9yZS5hLCBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgfSk7XG59O1xuVW5jYXVnaHRGcm96ZW5TdG9yZS5wcm90b3R5cGUgPSB7XG4gIGdldDogZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBlbnRyeSA9IGZpbmRVbmNhdWdodEZyb3plbih0aGlzLCBrZXkpO1xuICAgIGlmIChlbnRyeSkgcmV0dXJuIGVudHJ5WzFdO1xuICB9LFxuICBoYXM6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gISFmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgIHZhciBlbnRyeSA9IGZpbmRVbmNhdWdodEZyb3plbih0aGlzLCBrZXkpO1xuICAgIGlmIChlbnRyeSkgZW50cnlbMV0gPSB2YWx1ZTtcbiAgICBlbHNlIHRoaXMuYS5wdXNoKFtrZXksIHZhbHVlXSk7XG4gIH0sXG4gICdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIGluZGV4ID0gYXJyYXlGaW5kSW5kZXgodGhpcy5hLCBmdW5jdGlvbiAoaXQpIHtcbiAgICAgIHJldHVybiBpdFswXSA9PT0ga2V5O1xuICAgIH0pO1xuICAgIGlmICh+aW5kZXgpIHRoaXMuYS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHJldHVybiAhIX5pbmRleDtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbiAod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUikge1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgaXRlcmFibGUpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XG4gICAgICB0aGF0Ll90ID0gTkFNRTsgICAgICAvLyBjb2xsZWN0aW9uIHR5cGVcbiAgICAgIHRoYXQuX2kgPSBpZCsrOyAgICAgIC8vIGNvbGxlY3Rpb24gaWRcbiAgICAgIHRoYXQuX2wgPSB1bmRlZmluZWQ7IC8vIGxlYWsgc3RvcmUgZm9yIHVuY2F1Z2h0IGZyb3plbiBvYmplY3RzXG4gICAgICBpZiAoaXRlcmFibGUgIT0gdW5kZWZpbmVkKSBmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgfSk7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIHtcbiAgICAgIC8vIDIzLjMuMy4yIFdlYWtNYXAucHJvdG90eXBlLmRlbGV0ZShrZXkpXG4gICAgICAvLyAyMy40LjMuMyBXZWFrU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdmFyIGRhdGEgPSBnZXRXZWFrKGtleSk7XG4gICAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBOQU1FKSlbJ2RlbGV0ZSddKGtleSk7XG4gICAgICAgIHJldHVybiBkYXRhICYmICRoYXMoZGF0YSwgdGhpcy5faSkgJiYgZGVsZXRlIGRhdGFbdGhpcy5faV07XG4gICAgICB9LFxuICAgICAgLy8gMjMuMy4zLjQgV2Vha01hcC5wcm90b3R5cGUuaGFzKGtleSlcbiAgICAgIC8vIDIzLjQuMy40IFdlYWtTZXQucHJvdG90eXBlLmhhcyh2YWx1ZSlcbiAgICAgIGhhczogZnVuY3Rpb24gaGFzKGtleSkge1xuICAgICAgICBpZiAoIWlzT2JqZWN0KGtleSkpIHJldHVybiBmYWxzZTtcbiAgICAgICAgdmFyIGRhdGEgPSBnZXRXZWFrKGtleSk7XG4gICAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBOQU1FKSkuaGFzKGtleSk7XG4gICAgICAgIHJldHVybiBkYXRhICYmICRoYXMoZGF0YSwgdGhpcy5faSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIEM7XG4gIH0sXG4gIGRlZjogZnVuY3Rpb24gKHRoYXQsIGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZGF0YSA9IGdldFdlYWsoYW5PYmplY3Qoa2V5KSwgdHJ1ZSk7XG4gICAgaWYgKGRhdGEgPT09IHRydWUpIHVuY2F1Z2h0RnJvemVuU3RvcmUodGhhdCkuc2V0KGtleSwgdmFsdWUpO1xuICAgIGVsc2UgZGF0YVt0aGF0Ll9pXSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGF0O1xuICB9LFxuICB1ZnN0b3JlOiB1bmNhdWdodEZyb3plblN0b3JlXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGVhY2ggPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMCk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpO1xudmFyIHdlYWsgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBXRUFLX01BUCA9ICdXZWFrTWFwJztcbnZhciBnZXRXZWFrID0gbWV0YS5nZXRXZWFrO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG52YXIgdW5jYXVnaHRGcm96ZW5TdG9yZSA9IHdlYWsudWZzdG9yZTtcbnZhciB0bXAgPSB7fTtcbnZhciBJbnRlcm5hbE1hcDtcblxudmFyIHdyYXBwZXIgPSBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrTWFwKCkge1xuICAgIHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICB9O1xufTtcblxudmFyIG1ldGhvZHMgPSB7XG4gIC8vIDIzLjMuMy4zIFdlYWtNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIGlmIChpc09iamVjdChrZXkpKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBXRUFLX01BUCkpLmdldChrZXkpO1xuICAgICAgcmV0dXJuIGRhdGEgPyBkYXRhW3RoaXMuX2ldIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfSxcbiAgLy8gMjMuMy4zLjUgV2Vha01hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gd2Vhay5kZWYodmFsaWRhdGUodGhpcywgV0VBS19NQVApLCBrZXksIHZhbHVlKTtcbiAgfVxufTtcblxuLy8gMjMuMyBXZWFrTWFwIE9iamVjdHNcbnZhciAkV2Vha01hcCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFdFQUtfTUFQLCB3cmFwcGVyLCBtZXRob2RzLCB3ZWFrLCB0cnVlLCB0cnVlKTtcblxuLy8gSUUxMSBXZWFrTWFwIGZyb3plbiBrZXlzIGZpeFxuaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyAkV2Vha01hcCgpLnNldCgoT2JqZWN0LmZyZWV6ZSB8fCBPYmplY3QpKHRtcCksIDcpLmdldCh0bXApICE9IDc7IH0pKSB7XG4gIEludGVybmFsTWFwID0gd2Vhay5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBXRUFLX01BUCk7XG4gIGFzc2lnbihJbnRlcm5hbE1hcC5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICBtZXRhLk5FRUQgPSB0cnVlO1xuICBlYWNoKFsnZGVsZXRlJywgJ2hhcycsICdnZXQnLCAnc2V0J10sIGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgcHJvdG8gPSAkV2Vha01hcC5wcm90b3R5cGU7XG4gICAgdmFyIG1ldGhvZCA9IHByb3RvW2tleV07XG4gICAgcmVkZWZpbmUocHJvdG8sIGtleSwgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIC8vIHN0b3JlIGZyb3plbiBvYmplY3RzIG9uIGludGVybmFsIHdlYWttYXAgc2hpbVxuICAgICAgaWYgKGlzT2JqZWN0KGEpICYmICFpc0V4dGVuc2libGUoYSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9mKSB0aGlzLl9mID0gbmV3IEludGVybmFsTWFwKCk7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9mW2tleV0oYSwgYik7XG4gICAgICAgIHJldHVybiBrZXkgPT0gJ3NldCcgPyB0aGlzIDogcmVzdWx0O1xuICAgICAgLy8gc3RvcmUgYWxsIHRoZSByZXN0IG9uIG5hdGl2ZSB3ZWFrbWFwXG4gICAgICB9IHJldHVybiBtZXRob2QuY2FsbCh0aGlzLCBhLCBiKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy13ZWFrbWFwLm9mXG5yZXF1aXJlKCcuL19zZXQtY29sbGVjdGlvbi1vZicpKCdXZWFrTWFwJyk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy13ZWFrbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnV2Vha01hcCcpO1xuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi53ZWFrLW1hcCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczcud2Vhay1tYXAub2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM3LndlYWstbWFwLmZyb20nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpLldlYWtNYXA7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBpbmRleCwgdmFsdWUpIHtcbiAgaWYgKGluZGV4IGluIG9iamVjdCkgJGRlZmluZVByb3BlcnR5LmYob2JqZWN0LCBpbmRleCwgY3JlYXRlRGVzYygwLCB2YWx1ZSkpO1xuICBlbHNlIG9iamVjdFtpbmRleF0gPSB2YWx1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgY2FsbCA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpO1xudmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY3JlYXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL19jcmVhdGUtcHJvcGVydHknKTtcbnZhciBnZXRJdGVyRm4gPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpKGZ1bmN0aW9uIChpdGVyKSB7IEFycmF5LmZyb20oaXRlcik7IH0pLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMi4xIEFycmF5LmZyb20oYXJyYXlMaWtlLCBtYXBmbiA9IHVuZGVmaW5lZCwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgZnJvbTogZnVuY3Rpb24gZnJvbShhcnJheUxpa2UgLyogLCBtYXBmbiA9IHVuZGVmaW5lZCwgdGhpc0FyZyA9IHVuZGVmaW5lZCAqLykge1xuICAgIHZhciBPID0gdG9PYmplY3QoYXJyYXlMaWtlKTtcbiAgICB2YXIgQyA9IHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgPyB0aGlzIDogQXJyYXk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBtYXBmbiA9IGFMZW4gPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBtYXBwaW5nID0gbWFwZm4gIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBpdGVyRm4gPSBnZXRJdGVyRm4oTyk7XG4gICAgdmFyIGxlbmd0aCwgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZiAobWFwcGluZykgbWFwZm4gPSBjdHgobWFwZm4sIGFMZW4gPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkLCAyKTtcbiAgICAvLyBpZiBvYmplY3QgaXNuJ3QgaXRlcmFibGUgb3IgaXQncyBhcnJheSB3aXRoIGRlZmF1bHQgaXRlcmF0b3IgLSB1c2Ugc2ltcGxlIGNhc2VcbiAgICBpZiAoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhKEMgPT0gQXJyYXkgJiYgaXNBcnJheUl0ZXIoaXRlckZuKSkpIHtcbiAgICAgIGZvciAoaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChPKSwgcmVzdWx0ID0gbmV3IEMoKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyBpbmRleCsrKSB7XG4gICAgICAgIGNyZWF0ZVByb3BlcnR5KHJlc3VsdCwgaW5kZXgsIG1hcHBpbmcgPyBjYWxsKGl0ZXJhdG9yLCBtYXBmbiwgW3N0ZXAudmFsdWUsIGluZGV4XSwgdHJ1ZSkgOiBzdGVwLnZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgICAgZm9yIChyZXN1bHQgPSBuZXcgQyhsZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKykge1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gbWFwZm4oT1tpbmRleF0sIGluZGV4KSA6IE9baW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVzdWx0Lmxlbmd0aCA9IGluZGV4O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5mcm9tJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5mcm9tO1xuIiwiY29uc3QgcmVzZXJ2ZWRUYWdMaXN0ID0gbmV3IFNldChbXG4gICdhbm5vdGF0aW9uLXhtbCcsXG4gICdjb2xvci1wcm9maWxlJyxcbiAgJ2ZvbnQtZmFjZScsXG4gICdmb250LWZhY2Utc3JjJyxcbiAgJ2ZvbnQtZmFjZS11cmknLFxuICAnZm9udC1mYWNlLWZvcm1hdCcsXG4gICdmb250LWZhY2UtbmFtZScsXG4gICdtaXNzaW5nLWdseXBoJyxcbl0pO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbE5hbWVcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEN1c3RvbUVsZW1lbnROYW1lKGxvY2FsTmFtZSkge1xuICBjb25zdCByZXNlcnZlZCA9IHJlc2VydmVkVGFnTGlzdC5oYXMobG9jYWxOYW1lKTtcbiAgY29uc3QgdmFsaWRGb3JtID0gL15bYS16XVsuMC05X2Etel0qLVtcXC0uMC05X2Etel0qJC8udGVzdChsb2NhbE5hbWUpO1xuICByZXR1cm4gIXJlc2VydmVkICYmIHZhbGlkRm9ybTtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHshTm9kZX0gbm9kZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29ubmVjdGVkKG5vZGUpIHtcbiAgLy8gVXNlIGBOb2RlI2lzQ29ubmVjdGVkYCwgaWYgZGVmaW5lZC5cbiAgY29uc3QgbmF0aXZlVmFsdWUgPSBub2RlLmlzQ29ubmVjdGVkO1xuICBpZiAobmF0aXZlVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBuYXRpdmVWYWx1ZTtcbiAgfVxuXG4gIC8qKiBAdHlwZSB7P05vZGV8dW5kZWZpbmVkfSAqL1xuICBsZXQgY3VycmVudCA9IG5vZGU7XG4gIHdoaWxlIChjdXJyZW50ICYmICEoY3VycmVudC5fX0NFX2lzSW1wb3J0RG9jdW1lbnQgfHwgY3VycmVudCBpbnN0YW5jZW9mIERvY3VtZW50KSkge1xuICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudE5vZGUgfHwgKHdpbmRvdy5TaGFkb3dSb290ICYmIGN1cnJlbnQgaW5zdGFuY2VvZiBTaGFkb3dSb290ID8gY3VycmVudC5ob3N0IDogdW5kZWZpbmVkKTtcbiAgfVxuICByZXR1cm4gISEoY3VycmVudCAmJiAoY3VycmVudC5fX0NFX2lzSW1wb3J0RG9jdW1lbnQgfHwgY3VycmVudCBpbnN0YW5jZW9mIERvY3VtZW50KSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHshTm9kZX0gcm9vdFxuICogQHBhcmFtIHshTm9kZX0gc3RhcnRcbiAqIEByZXR1cm4gez9Ob2RlfVxuICovXG5mdW5jdGlvbiBuZXh0U2libGluZ09yQW5jZXN0b3JTaWJsaW5nKHJvb3QsIHN0YXJ0KSB7XG4gIGxldCBub2RlID0gc3RhcnQ7XG4gIHdoaWxlIChub2RlICYmIG5vZGUgIT09IHJvb3QgJiYgIW5vZGUubmV4dFNpYmxpbmcpIHtcbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiAoIW5vZGUgfHwgbm9kZSA9PT0gcm9vdCkgPyBudWxsIDogbm9kZS5uZXh0U2libGluZztcbn1cblxuLyoqXG4gKiBAcGFyYW0geyFOb2RlfSByb290XG4gKiBAcGFyYW0geyFOb2RlfSBzdGFydFxuICogQHJldHVybiB7P05vZGV9XG4gKi9cbmZ1bmN0aW9uIG5leHROb2RlKHJvb3QsIHN0YXJ0KSB7XG4gIHJldHVybiBzdGFydC5maXJzdENoaWxkID8gc3RhcnQuZmlyc3RDaGlsZCA6IG5leHRTaWJsaW5nT3JBbmNlc3RvclNpYmxpbmcocm9vdCwgc3RhcnQpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7IU5vZGV9IHJvb3RcbiAqIEBwYXJhbSB7IWZ1bmN0aW9uKCFFbGVtZW50KX0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7IVNldDxOb2RlPj19IHZpc2l0ZWRJbXBvcnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhyb290LCBjYWxsYmFjaywgdmlzaXRlZEltcG9ydHMgPSBuZXcgU2V0KCkpIHtcbiAgbGV0IG5vZGUgPSByb290O1xuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IC8qKiBAdHlwZSB7IUVsZW1lbnR9ICovKG5vZGUpO1xuXG4gICAgICBjYWxsYmFjayhlbGVtZW50KTtcblxuICAgICAgY29uc3QgbG9jYWxOYW1lID0gZWxlbWVudC5sb2NhbE5hbWU7XG4gICAgICBpZiAobG9jYWxOYW1lID09PSAnbGluaycgJiYgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3JlbCcpID09PSAnaW1wb3J0Jykge1xuICAgICAgICAvLyBJZiB0aGlzIGltcG9ydCAocG9seWZpbGxlZCBvciBub3QpIGhhcyBpdCdzIHJvb3Qgbm9kZSBhdmFpbGFibGUsXG4gICAgICAgIC8vIHdhbGsgaXQuXG4gICAgICAgIGNvbnN0IGltcG9ydE5vZGUgPSAvKiogQHR5cGUgeyFOb2RlfSAqLyAoZWxlbWVudC5pbXBvcnQpO1xuICAgICAgICBpZiAoaW1wb3J0Tm9kZSBpbnN0YW5jZW9mIE5vZGUgJiYgIXZpc2l0ZWRJbXBvcnRzLmhhcyhpbXBvcnROb2RlKSkge1xuICAgICAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgd2Fsa3Mgb2YgdGhlIHNhbWUgaW1wb3J0IHJvb3QuXG4gICAgICAgICAgdmlzaXRlZEltcG9ydHMuYWRkKGltcG9ydE5vZGUpO1xuXG4gICAgICAgICAgZm9yIChsZXQgY2hpbGQgPSBpbXBvcnROb2RlLmZpcnN0Q2hpbGQ7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgICB3YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhjaGlsZCwgY2FsbGJhY2ssIHZpc2l0ZWRJbXBvcnRzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZ25vcmUgZGVzY2VuZGFudHMgb2YgaW1wb3J0IGxpbmtzIHRvIHByZXZlbnQgYXR0ZW1wdGluZyB0byB3YWxrIHRoZVxuICAgICAgICAvLyBlbGVtZW50cyBjcmVhdGVkIGJ5IHRoZSBIVE1MIEltcG9ydHMgcG9seWZpbGwgdGhhdCB3ZSBqdXN0IHdhbGtlZFxuICAgICAgICAvLyBhYm92ZS5cbiAgICAgICAgbm9kZSA9IG5leHRTaWJsaW5nT3JBbmNlc3RvclNpYmxpbmcocm9vdCwgZWxlbWVudCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIGlmIChsb2NhbE5hbWUgPT09ICd0ZW1wbGF0ZScpIHtcbiAgICAgICAgLy8gSWdub3JlIGRlc2NlbmRhbnRzIG9mIHRlbXBsYXRlcy4gVGhlcmUgc2hvdWxkbid0IGJlIGFueSBkZXNjZW5kYW50c1xuICAgICAgICAvLyBiZWNhdXNlIHRoZXkgd2lsbCBiZSBtb3ZlZCBpbnRvIGAuY29udGVudGAgZHVyaW5nIGNvbnN0cnVjdGlvbiBpblxuICAgICAgICAvLyBicm93c2VycyB0aGF0IHN1cHBvcnQgdGVtcGxhdGUgYnV0LCBpbiBjYXNlIHRoZXkgZXhpc3QgYW5kIGFyZSBzdGlsbFxuICAgICAgICAvLyB3YWl0aW5nIHRvIGJlIG1vdmVkIGJ5IGEgcG9seWZpbGwsIHRoZXkgd2lsbCBiZSBpZ25vcmVkLlxuICAgICAgICBub2RlID0gbmV4dFNpYmxpbmdPckFuY2VzdG9yU2libGluZyhyb290LCBlbGVtZW50KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFdhbGsgc2hhZG93IHJvb3RzLlxuICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IGVsZW1lbnQuX19DRV9zaGFkb3dSb290O1xuICAgICAgaWYgKHNoYWRvd1Jvb3QpIHtcbiAgICAgICAgZm9yIChsZXQgY2hpbGQgPSBzaGFkb3dSb290LmZpcnN0Q2hpbGQ7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgd2Fsa0RlZXBEZXNjZW5kYW50RWxlbWVudHMoY2hpbGQsIGNhbGxiYWNrLCB2aXNpdGVkSW1wb3J0cyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gbmV4dE5vZGUocm9vdCwgbm9kZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBVc2VkIHRvIHN1cHByZXNzIENsb3N1cmUncyBcIk1vZGlmeWluZyB0aGUgcHJvdG90eXBlIGlzIG9ubHkgYWxsb3dlZCBpZiB0aGVcbiAqIGNvbnN0cnVjdG9yIGlzIGluIHRoZSBzYW1lIHNjb3BlXCIgd2FybmluZyB3aXRob3V0IHVzaW5nXG4gKiBgQHN1cHByZXNzIHtuZXdDaGVja1R5cGVzLCBkdXBsaWNhdGV9YCBiZWNhdXNlIGBuZXdDaGVja1R5cGVzYCBpcyB0b28gYnJvYWQuXG4gKlxuICogQHBhcmFtIHshT2JqZWN0fSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFByb3BlcnR5VW5jaGVja2VkKGRlc3RpbmF0aW9uLCBuYW1lLCB2YWx1ZSkge1xuICBkZXN0aW5hdGlvbltuYW1lXSA9IHZhbHVlO1xufVxuIiwiLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5jb25zdCBDdXN0b21FbGVtZW50U3RhdGUgPSB7XG4gIGN1c3RvbTogMSxcbiAgZmFpbGVkOiAyLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgQ3VzdG9tRWxlbWVudFN0YXRlO1xuIiwiaW1wb3J0ICogYXMgVXRpbGl0aWVzIGZyb20gJy4vVXRpbGl0aWVzLmpzJztcbmltcG9ydCBDRVN0YXRlIGZyb20gJy4vQ3VzdG9tRWxlbWVudFN0YXRlLmpzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3VzdG9tRWxlbWVudEludGVybmFscyB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8qKiBAdHlwZSB7IU1hcDxzdHJpbmcsICFDdXN0b21FbGVtZW50RGVmaW5pdGlvbj59ICovXG4gICAgdGhpcy5fbG9jYWxOYW1lVG9EZWZpbml0aW9uID0gbmV3IE1hcCgpO1xuXG4gICAgLyoqIEB0eXBlIHshTWFwPCFGdW5jdGlvbiwgIUN1c3RvbUVsZW1lbnREZWZpbml0aW9uPn0gKi9cbiAgICB0aGlzLl9jb25zdHJ1Y3RvclRvRGVmaW5pdGlvbiA9IG5ldyBNYXAoKTtcblxuICAgIC8qKiBAdHlwZSB7IUFycmF5PCFmdW5jdGlvbighTm9kZSk+fSAqL1xuICAgIHRoaXMuX3BhdGNoZXMgPSBbXTtcblxuICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICB0aGlzLl9oYXNQYXRjaGVzID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsTmFtZVxuICAgKiBAcGFyYW0geyFDdXN0b21FbGVtZW50RGVmaW5pdGlvbn0gZGVmaW5pdGlvblxuICAgKi9cbiAgc2V0RGVmaW5pdGlvbihsb2NhbE5hbWUsIGRlZmluaXRpb24pIHtcbiAgICB0aGlzLl9sb2NhbE5hbWVUb0RlZmluaXRpb24uc2V0KGxvY2FsTmFtZSwgZGVmaW5pdGlvbik7XG4gICAgdGhpcy5fY29uc3RydWN0b3JUb0RlZmluaXRpb24uc2V0KGRlZmluaXRpb24uY29uc3RydWN0b3IsIGRlZmluaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbE5hbWVcbiAgICogQHJldHVybiB7IUN1c3RvbUVsZW1lbnREZWZpbml0aW9ufHVuZGVmaW5lZH1cbiAgICovXG4gIGxvY2FsTmFtZVRvRGVmaW5pdGlvbihsb2NhbE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9jYWxOYW1lVG9EZWZpbml0aW9uLmdldChsb2NhbE5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBjb25zdHJ1Y3RvclxuICAgKiBAcmV0dXJuIHshQ3VzdG9tRWxlbWVudERlZmluaXRpb258dW5kZWZpbmVkfVxuICAgKi9cbiAgY29uc3RydWN0b3JUb0RlZmluaXRpb24oY29uc3RydWN0b3IpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uc3RydWN0b3JUb0RlZmluaXRpb24uZ2V0KGNvbnN0cnVjdG9yKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFmdW5jdGlvbighTm9kZSl9IGxpc3RlbmVyXG4gICAqL1xuICBhZGRQYXRjaChsaXN0ZW5lcikge1xuICAgIHRoaXMuX2hhc1BhdGNoZXMgPSB0cnVlO1xuICAgIHRoaXMuX3BhdGNoZXMucHVzaChsaXN0ZW5lcik7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHshTm9kZX0gbm9kZVxuICAgKi9cbiAgcGF0Y2hUcmVlKG5vZGUpIHtcbiAgICBpZiAoIXRoaXMuX2hhc1BhdGNoZXMpIHJldHVybjtcblxuICAgIFV0aWxpdGllcy53YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhub2RlLCBlbGVtZW50ID0+IHRoaXMucGF0Y2goZWxlbWVudCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICovXG4gIHBhdGNoKG5vZGUpIHtcbiAgICBpZiAoIXRoaXMuX2hhc1BhdGNoZXMpIHJldHVybjtcblxuICAgIGlmIChub2RlLl9fQ0VfcGF0Y2hlZCkgcmV0dXJuO1xuICAgIG5vZGUuX19DRV9wYXRjaGVkID0gdHJ1ZTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fcGF0Y2hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5fcGF0Y2hlc1tpXShub2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHshTm9kZX0gcm9vdFxuICAgKi9cbiAgY29ubmVjdFRyZWUocm9vdCkge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gW107XG5cbiAgICBVdGlsaXRpZXMud2Fsa0RlZXBEZXNjZW5kYW50RWxlbWVudHMocm9vdCwgZWxlbWVudCA9PiBlbGVtZW50cy5wdXNoKGVsZW1lbnQpKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1tpXTtcbiAgICAgIGlmIChlbGVtZW50Ll9fQ0Vfc3RhdGUgPT09IENFU3RhdGUuY3VzdG9tKSB7XG4gICAgICAgIGlmIChVdGlsaXRpZXMuaXNDb25uZWN0ZWQoZWxlbWVudCkpIHtcbiAgICAgICAgICB0aGlzLmNvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnVwZ3JhZGVFbGVtZW50KGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFOb2RlfSByb290XG4gICAqL1xuICBkaXNjb25uZWN0VHJlZShyb290KSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSBbXTtcblxuICAgIFV0aWxpdGllcy53YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyhyb290LCBlbGVtZW50ID0+IGVsZW1lbnRzLnB1c2goZWxlbWVudCkpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRzW2ldO1xuICAgICAgaWYgKGVsZW1lbnQuX19DRV9zdGF0ZSA9PT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0ZWRDYWxsYmFjayhlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVXBncmFkZXMgYWxsIHVuY3VzdG9taXplZCBjdXN0b20gZWxlbWVudHMgYXQgYW5kIGJlbG93IGEgcm9vdCBub2RlIGZvclxuICAgKiB3aGljaCB0aGVyZSBpcyBhIGRlZmluaXRpb24uIFdoZW4gY3VzdG9tIGVsZW1lbnQgcmVhY3Rpb24gY2FsbGJhY2tzIGFyZVxuICAgKiBhc3N1bWVkIHRvIGJlIGNhbGxlZCBzeW5jaHJvbm91c2x5ICh3aGljaCwgYnkgdGhlIGN1cnJlbnQgRE9NIC8gSFRNTCBzcGVjXG4gICAqIGRlZmluaXRpb25zLCB0aGV5IGFyZSAqbm90KiksIGNhbGxiYWNrcyBmb3IgYm90aCBlbGVtZW50cyBjdXN0b21pemVkXG4gICAqIHN5bmNocm9ub3VzbHkgYnkgdGhlIHBhcnNlciBhbmQgZWxlbWVudHMgYmVpbmcgdXBncmFkZWQgb2NjdXIgaW4gdGhlIHNhbWVcbiAgICogcmVsYXRpdmUgb3JkZXIuXG4gICAqXG4gICAqIE5PVEU6IFRoaXMgZnVuY3Rpb24sIHdoZW4gdXNlZCB0byBzaW11bGF0ZSB0aGUgY29uc3RydWN0aW9uIG9mIGEgdHJlZSB0aGF0XG4gICAqIGlzIGFscmVhZHkgY3JlYXRlZCBidXQgbm90IGN1c3RvbWl6ZWQgKGkuZS4gYnkgdGhlIHBhcnNlciksIGRvZXMgKm5vdCpcbiAgICogcHJldmVudCB0aGUgZWxlbWVudCBmcm9tIHJlYWRpbmcgdGhlICdmaW5hbCcgKHRydWUpIHN0YXRlIG9mIHRoZSB0cmVlLiBGb3JcbiAgICogZXhhbXBsZSwgdGhlIGVsZW1lbnQsIGR1cmluZyB0cnVseSBzeW5jaHJvbm91cyBwYXJzaW5nIC8gY29uc3RydWN0aW9uIHdvdWxkXG4gICAqIHNlZSB0aGF0IGl0IGNvbnRhaW5zIG5vIGNoaWxkcmVuIGFzIHRoZXkgaGF2ZSBub3QgeWV0IGJlZW4gaW5zZXJ0ZWQuXG4gICAqIEhvd2V2ZXIsIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgbW9kaWZ5IHRoZSB0cmVlLCB0aGUgZWxlbWVudCB3aWxsXG4gICAqIChpbmNvcnJlY3RseSkgaGF2ZSBjaGlsZHJlbi4gQWRkaXRpb25hbGx5LCBzZWxmLW1vZGlmaWNhdGlvbiByZXN0cmljdGlvbnNcbiAgICogZm9yIGN1c3RvbSBlbGVtZW50IGNvbnN0cnVjdG9ycyBpbXBvc2VkIGJ5IHRoZSBET00gc3BlYyBhcmUgKm5vdCogZW5mb3JjZWQuXG4gICAqXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgbmVzdGVkIGxpc3Qgc2hvd3MgdGhlIHN0ZXBzIGV4dGVuZGluZyBkb3duIGZyb20gdGhlIEhUTUxcbiAgICogc3BlYydzIHBhcnNpbmcgc2VjdGlvbiB0aGF0IGNhdXNlIGVsZW1lbnRzIHRvIGJlIHN5bmNocm9ub3VzbHkgY3JlYXRlZCBhbmRcbiAgICogdXBncmFkZWQ6XG4gICAqXG4gICAqIFRoZSBcImluIGJvZHlcIiBpbnNlcnRpb24gbW9kZTpcbiAgICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWluYm9keVxuICAgKiAtIFN3aXRjaCBvbiB0b2tlbjpcbiAgICogICAuLiBvdGhlciBjYXNlcyAuLlxuICAgKiAgIC0+IEFueSBvdGhlciBzdGFydCB0YWdcbiAgICogICAgICAtIFtJbnNlcnQgYW4gSFRNTCBlbGVtZW50XShiZWxvdykgZm9yIHRoZSB0b2tlbi5cbiAgICpcbiAgICogSW5zZXJ0IGFuIEhUTUwgZWxlbWVudDpcbiAgICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjaW5zZXJ0LWFuLWh0bWwtZWxlbWVudFxuICAgKiAtIEluc2VydCBhIGZvcmVpZ24gZWxlbWVudCBmb3IgdGhlIHRva2VuIGluIHRoZSBIVE1MIG5hbWVzcGFjZTpcbiAgICogICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNpbnNlcnQtYS1mb3JlaWduLWVsZW1lbnRcbiAgICogICAtIENyZWF0ZSBhbiBlbGVtZW50IGZvciBhIHRva2VuOlxuICAgKiAgICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjY3JlYXRlLWFuLWVsZW1lbnQtZm9yLXRoZS10b2tlblxuICAgKiAgICAgLSBXaWxsIGV4ZWN1dGUgc2NyaXB0IGZsYWcgaXMgdHJ1ZT9cbiAgICogICAgICAgLSAoRWxlbWVudCBxdWV1ZSBwdXNoZWQgdG8gdGhlIGN1c3RvbSBlbGVtZW50IHJlYWN0aW9ucyBzdGFjay4pXG4gICAqICAgICAtIENyZWF0ZSBhbiBlbGVtZW50OlxuICAgKiAgICAgICBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtY3JlYXRlLWVsZW1lbnRcbiAgICogICAgICAgLSBTeW5jIENFIGZsYWcgaXMgdHJ1ZT9cbiAgICogICAgICAgICAtIENvbnN0cnVjdG9yIGNhbGxlZC5cbiAgICogICAgICAgICAtIFNlbGYtbW9kaWZpY2F0aW9uIHJlc3RyaWN0aW9ucyBlbmZvcmNlZC5cbiAgICogICAgICAgLSBTeW5jIENFIGZsYWcgaXMgZmFsc2U/XG4gICAqICAgICAgICAgLSAoVXBncmFkZSByZWFjdGlvbiBlbnF1ZXVlZC4pXG4gICAqICAgICAtIEF0dHJpYnV0ZXMgYXBwZW5kZWQgdG8gZWxlbWVudC5cbiAgICogICAgICAgKGBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2tgIHJlYWN0aW9ucyBlbnF1ZXVlZC4pXG4gICAqICAgICAtIFdpbGwgZXhlY3V0ZSBzY3JpcHQgZmxhZyBpcyB0cnVlP1xuICAgKiAgICAgICAtIChFbGVtZW50IHF1ZXVlIHBvcHBlZCBmcm9tIHRoZSBjdXN0b20gZWxlbWVudCByZWFjdGlvbnMgc3RhY2suXG4gICAqICAgICAgICAgUmVhY3Rpb25zIGluIHRoZSBwb3BwZWQgc3RhY2sgYXJlIGludm9rZWQuKVxuICAgKiAgIC0gKEVsZW1lbnQgcXVldWUgcHVzaGVkIHRvIHRoZSBjdXN0b20gZWxlbWVudCByZWFjdGlvbnMgc3RhY2suKVxuICAgKiAgIC0gSW5zZXJ0IHRoZSBlbGVtZW50OlxuICAgKiAgICAgaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNjb25jZXB0LW5vZGUtaW5zZXJ0XG4gICAqICAgICAtIFNoYWRvdy1pbmNsdWRpbmcgZGVzY2VuZGFudHMgYXJlIGNvbm5lY3RlZC4gRHVyaW5nIHBhcnNpbmdcbiAgICogICAgICAgY29uc3RydWN0aW9uLCB0aGVyZSBhcmUgbm8gc2hhZG93LSpleGNsdWRpbmcqIGRlc2NlbmRhbnRzLlxuICAgKiAgICAgICBIb3dldmVyLCB0aGUgY29uc3RydWN0b3IgbWF5IGhhdmUgdmFsaWRseSBhdHRhY2hlZCBhIHNoYWRvd1xuICAgKiAgICAgICB0cmVlIHRvIGl0c2VsZiBhbmQgYWRkZWQgZGVzY2VuZGFudHMgdG8gdGhhdCBzaGFkb3cgdHJlZS5cbiAgICogICAgICAgKGBjb25uZWN0ZWRDYWxsYmFja2AgcmVhY3Rpb25zIGVucXVldWVkLilcbiAgICogICAtIChFbGVtZW50IHF1ZXVlIHBvcHBlZCBmcm9tIHRoZSBjdXN0b20gZWxlbWVudCByZWFjdGlvbnMgc3RhY2suXG4gICAqICAgICBSZWFjdGlvbnMgaW4gdGhlIHBvcHBlZCBzdGFjayBhcmUgaW52b2tlZC4pXG4gICAqXG4gICAqIEBwYXJhbSB7IU5vZGV9IHJvb3RcbiAgICogQHBhcmFtIHshU2V0PE5vZGU+PX0gdmlzaXRlZEltcG9ydHNcbiAgICovXG4gIHBhdGNoQW5kVXBncmFkZVRyZWUocm9vdCwgdmlzaXRlZEltcG9ydHMgPSBuZXcgU2V0KCkpIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IFtdO1xuXG4gICAgY29uc3QgZ2F0aGVyRWxlbWVudHMgPSBlbGVtZW50ID0+IHtcbiAgICAgIGlmIChlbGVtZW50LmxvY2FsTmFtZSA9PT0gJ2xpbmsnICYmIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdyZWwnKSA9PT0gJ2ltcG9ydCcpIHtcbiAgICAgICAgLy8gVGhlIEhUTUwgSW1wb3J0cyBwb2x5ZmlsbCBzZXRzIGEgZGVzY2VuZGFudCBlbGVtZW50IG9mIHRoZSBsaW5rIHRvXG4gICAgICAgIC8vIHRoZSBgaW1wb3J0YCBwcm9wZXJ0eSwgc3BlY2lmaWNhbGx5IHRoaXMgaXMgKm5vdCogYSBEb2N1bWVudC5cbiAgICAgICAgY29uc3QgaW1wb3J0Tm9kZSA9IC8qKiBAdHlwZSB7P05vZGV9ICovIChlbGVtZW50LmltcG9ydCk7XG5cbiAgICAgICAgaWYgKGltcG9ydE5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIGltcG9ydE5vZGUucmVhZHlTdGF0ZSA9PT0gJ2NvbXBsZXRlJykge1xuICAgICAgICAgIGltcG9ydE5vZGUuX19DRV9pc0ltcG9ydERvY3VtZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIC8vIENvbm5lY3RlZCBsaW5rcyBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeS5cbiAgICAgICAgICBpbXBvcnROb2RlLl9fQ0VfaGFzUmVnaXN0cnkgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIElmIHRoaXMgbGluaydzIGltcG9ydCByb290IGlzIG5vdCBhdmFpbGFibGUsIGl0cyBjb250ZW50cyBjYW4ndCBiZVxuICAgICAgICAgIC8vIHdhbGtlZC4gV2FpdCBmb3IgJ2xvYWQnIGFuZCB3YWxrIGl0IHdoZW4gaXQncyByZWFkeS5cbiAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbXBvcnROb2RlID0gLyoqIEB0eXBlIHshTm9kZX0gKi8gKGVsZW1lbnQuaW1wb3J0KTtcblxuICAgICAgICAgICAgaWYgKGltcG9ydE5vZGUuX19DRV9kb2N1bWVudExvYWRIYW5kbGVkKSByZXR1cm47XG4gICAgICAgICAgICBpbXBvcnROb2RlLl9fQ0VfZG9jdW1lbnRMb2FkSGFuZGxlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGltcG9ydE5vZGUuX19DRV9pc0ltcG9ydERvY3VtZW50ID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ29ubmVjdGVkIGxpbmtzIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5LlxuICAgICAgICAgICAgaW1wb3J0Tm9kZS5fX0NFX2hhc1JlZ2lzdHJ5ID0gdHJ1ZTtcblxuICAgICAgICAgICAgLy8gQ2xvbmUgdGhlIGB2aXNpdGVkSW1wb3J0c2Agc2V0IHRoYXQgd2FzIHBvcHVsYXRlZCBzeW5jIGR1cmluZ1xuICAgICAgICAgICAgLy8gdGhlIGBwYXRjaEFuZFVwZ3JhZGVUcmVlYCBjYWxsIHRoYXQgY2F1c2VkIHRoaXMgJ2xvYWQnIGhhbmRsZXIgdG9cbiAgICAgICAgICAgIC8vIGJlIGFkZGVkLiBUaGVuLCByZW1vdmUgKnRoaXMqIGxpbmsncyBpbXBvcnQgbm9kZSBzbyB0aGF0IHdlIGNhblxuICAgICAgICAgICAgLy8gd2FsayB0aGF0IGltcG9ydCBhZ2FpbiwgZXZlbiBpZiBpdCB3YXMgcGFydGlhbGx5IHdhbGtlZCBsYXRlclxuICAgICAgICAgICAgLy8gZHVyaW5nIHRoZSBzYW1lIGBwYXRjaEFuZFVwZ3JhZGVUcmVlYCBjYWxsLlxuICAgICAgICAgICAgY29uc3QgY2xvbmVkVmlzaXRlZEltcG9ydHMgPSBuZXcgU2V0KHZpc2l0ZWRJbXBvcnRzKTtcbiAgICAgICAgICAgIHZpc2l0ZWRJbXBvcnRzLmRlbGV0ZShpbXBvcnROb2RlKTtcblxuICAgICAgICAgICAgdGhpcy5wYXRjaEFuZFVwZ3JhZGVUcmVlKGltcG9ydE5vZGUsIHZpc2l0ZWRJbXBvcnRzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gYHdhbGtEZWVwRGVzY2VuZGFudEVsZW1lbnRzYCBwb3B1bGF0ZXMgKGFuZCBpbnRlcm5hbGx5IGNoZWNrcyBhZ2FpbnN0KVxuICAgIC8vIGB2aXNpdGVkSW1wb3J0c2Agd2hlbiB0cmF2ZXJzaW5nIGEgbG9hZGVkIGltcG9ydC5cbiAgICBVdGlsaXRpZXMud2Fsa0RlZXBEZXNjZW5kYW50RWxlbWVudHMocm9vdCwgZ2F0aGVyRWxlbWVudHMsIHZpc2l0ZWRJbXBvcnRzKTtcblxuICAgIGlmICh0aGlzLl9oYXNQYXRjaGVzKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMucGF0Y2goZWxlbWVudHNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMudXBncmFkZUVsZW1lbnQoZWxlbWVudHNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICB1cGdyYWRlRWxlbWVudChlbGVtZW50KSB7XG4gICAgY29uc3QgY3VycmVudFN0YXRlID0gZWxlbWVudC5fX0NFX3N0YXRlO1xuICAgIGlmIChjdXJyZW50U3RhdGUgIT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IHRoaXMubG9jYWxOYW1lVG9EZWZpbml0aW9uKGVsZW1lbnQubG9jYWxOYW1lKTtcbiAgICBpZiAoIWRlZmluaXRpb24pIHJldHVybjtcblxuICAgIGRlZmluaXRpb24uY29uc3RydWN0aW9uU3RhY2sucHVzaChlbGVtZW50KTtcblxuICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gZGVmaW5pdGlvbi5jb25zdHJ1Y3RvcjtcbiAgICB0cnkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ldyAoY29uc3RydWN0b3IpKCk7XG4gICAgICAgIGlmIChyZXN1bHQgIT09IGVsZW1lbnQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXN0b20gZWxlbWVudCBjb25zdHJ1Y3RvciBkaWQgbm90IHByb2R1Y2UgdGhlIGVsZW1lbnQgYmVpbmcgdXBncmFkZWQuJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGRlZmluaXRpb24uY29uc3RydWN0aW9uU3RhY2sucG9wKCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZWxlbWVudC5fX0NFX3N0YXRlID0gQ0VTdGF0ZS5mYWlsZWQ7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIGVsZW1lbnQuX19DRV9zdGF0ZSA9IENFU3RhdGUuY3VzdG9tO1xuICAgIGVsZW1lbnQuX19DRV9kZWZpbml0aW9uID0gZGVmaW5pdGlvbjtcblxuICAgIGlmIChkZWZpbml0aW9uLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaykge1xuICAgICAgY29uc3Qgb2JzZXJ2ZWRBdHRyaWJ1dGVzID0gZGVmaW5pdGlvbi5vYnNlcnZlZEF0dHJpYnV0ZXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ic2VydmVkQXR0cmlidXRlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuYW1lID0gb2JzZXJ2ZWRBdHRyaWJ1dGVzW2ldO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhlbGVtZW50LCBuYW1lLCBudWxsLCB2YWx1ZSwgbnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKGVsZW1lbnQpKSB7XG4gICAgICB0aGlzLmNvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICBjb25uZWN0ZWRDYWxsYmFjayhlbGVtZW50KSB7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IGVsZW1lbnQuX19DRV9kZWZpbml0aW9uO1xuICAgIGlmIChkZWZpbml0aW9uLmNvbm5lY3RlZENhbGxiYWNrKSB7XG4gICAgICBkZWZpbml0aW9uLmNvbm5lY3RlZENhbGxiYWNrLmNhbGwoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgZWxlbWVudC5fX0NFX2lzQ29ubmVjdGVkQ2FsbGJhY2tDYWxsZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAgICovXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpIHtcbiAgICBpZiAoIWVsZW1lbnQuX19DRV9pc0Nvbm5lY3RlZENhbGxiYWNrQ2FsbGVkKSB7XG4gICAgICB0aGlzLmNvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmluaXRpb24gPSBlbGVtZW50Ll9fQ0VfZGVmaW5pdGlvbjtcbiAgICBpZiAoZGVmaW5pdGlvbi5kaXNjb25uZWN0ZWRDYWxsYmFjaykge1xuICAgICAgZGVmaW5pdGlvbi5kaXNjb25uZWN0ZWRDYWxsYmFjay5jYWxsKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGVsZW1lbnQuX19DRV9pc0Nvbm5lY3RlZENhbGxiYWNrQ2FsbGVkID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUVsZW1lbnR9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHs/c3RyaW5nfSBvbGRWYWx1ZVxuICAgKiBAcGFyYW0gez9zdHJpbmd9IG5ld1ZhbHVlXG4gICAqIEBwYXJhbSB7P3N0cmluZ30gbmFtZXNwYWNlXG4gICAqL1xuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soZWxlbWVudCwgbmFtZSwgb2xkVmFsdWUsIG5ld1ZhbHVlLCBuYW1lc3BhY2UpIHtcbiAgICBjb25zdCBkZWZpbml0aW9uID0gZWxlbWVudC5fX0NFX2RlZmluaXRpb247XG4gICAgaWYgKFxuICAgICAgZGVmaW5pdGlvbi5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sgJiZcbiAgICAgIGRlZmluaXRpb24ub2JzZXJ2ZWRBdHRyaWJ1dGVzLmluZGV4T2YobmFtZSkgPiAtMVxuICAgICkge1xuICAgICAgZGVmaW5pdGlvbi5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2suY2FsbChlbGVtZW50LCBuYW1lLCBvbGRWYWx1ZSwgbmV3VmFsdWUsIG5hbWVzcGFjZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuL0N1c3RvbUVsZW1lbnRJbnRlcm5hbHMuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyIHtcbiAgY29uc3RydWN0b3IoaW50ZXJuYWxzLCBkb2MpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9XG4gICAgICovXG4gICAgdGhpcy5faW50ZXJuYWxzID0gaW50ZXJuYWxzO1xuXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFEb2N1bWVudH1cbiAgICAgKi9cbiAgICB0aGlzLl9kb2N1bWVudCA9IGRvYztcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtNdXRhdGlvbk9ic2VydmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cbiAgICB0aGlzLl9vYnNlcnZlciA9IHVuZGVmaW5lZDtcblxuXG4gICAgLy8gU2ltdWxhdGUgdHJlZSBjb25zdHJ1Y3Rpb24gZm9yIGFsbCBjdXJyZW50bHkgYWNjZXNzaWJsZSBub2RlcyBpbiB0aGVcbiAgICAvLyBkb2N1bWVudC5cbiAgICB0aGlzLl9pbnRlcm5hbHMucGF0Y2hBbmRVcGdyYWRlVHJlZSh0aGlzLl9kb2N1bWVudCk7XG5cbiAgICBpZiAodGhpcy5fZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7XG4gICAgICB0aGlzLl9vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKHRoaXMuX2hhbmRsZU11dGF0aW9ucy5iaW5kKHRoaXMpKTtcblxuICAgICAgLy8gTm9kZXMgY3JlYXRlZCBieSB0aGUgcGFyc2VyIGFyZSBnaXZlbiB0byB0aGUgb2JzZXJ2ZXIgKmJlZm9yZSogdGhlIG5leHRcbiAgICAgIC8vIHRhc2sgcnVucy4gSW5saW5lIHNjcmlwdHMgYXJlIHJ1biBpbiBhIG5ldyB0YXNrLiBUaGlzIG1lYW5zIHRoYXQgdGhlXG4gICAgICAvLyBvYnNlcnZlciB3aWxsIGJlIGFibGUgdG8gaGFuZGxlIHRoZSBuZXdseSBwYXJzZWQgbm9kZXMgYmVmb3JlIHRoZSBpbmxpbmVcbiAgICAgIC8vIHNjcmlwdCBpcyBydW4uXG4gICAgICB0aGlzLl9vYnNlcnZlci5vYnNlcnZlKHRoaXMuX2RvY3VtZW50LCB7XG4gICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgc3VidHJlZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGRpc2Nvbm5lY3QoKSB7XG4gICAgaWYgKHRoaXMuX29ic2VydmVyKSB7XG4gICAgICB0aGlzLl9vYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7IUFycmF5PCFNdXRhdGlvblJlY29yZD59IG11dGF0aW9uc1xuICAgKi9cbiAgX2hhbmRsZU11dGF0aW9ucyhtdXRhdGlvbnMpIHtcbiAgICAvLyBPbmNlIHRoZSBkb2N1bWVudCdzIGByZWFkeVN0YXRlYCBpcyAnaW50ZXJhY3RpdmUnIG9yICdjb21wbGV0ZScsIGFsbCBuZXdcbiAgICAvLyBub2RlcyBjcmVhdGVkIHdpdGhpbiB0aGF0IGRvY3VtZW50IHdpbGwgYmUgdGhlIHJlc3VsdCBvZiBzY3JpcHQgYW5kXG4gICAgLy8gc2hvdWxkIGJlIGhhbmRsZWQgYnkgcGF0Y2hpbmcuXG4gICAgY29uc3QgcmVhZHlTdGF0ZSA9IHRoaXMuX2RvY3VtZW50LnJlYWR5U3RhdGU7XG4gICAgaWYgKHJlYWR5U3RhdGUgPT09ICdpbnRlcmFjdGl2ZScgfHwgcmVhZHlTdGF0ZSA9PT0gJ2NvbXBsZXRlJykge1xuICAgICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdXRhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGFkZGVkTm9kZXMgPSBtdXRhdGlvbnNbaV0uYWRkZWROb2RlcztcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYWRkZWROb2Rlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBjb25zdCBub2RlID0gYWRkZWROb2Rlc1tqXTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxzLnBhdGNoQW5kVXBncmFkZVRyZWUobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERlZmVycmVkIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7VHx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5fdmFsdWUgPSB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5fcmVzb2x2ZSA9IHVuZGVmaW5lZDtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFQcm9taXNlPFQ+fVxuICAgICAqL1xuICAgIHRoaXMuX3Byb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHRoaXMuX3Jlc29sdmUgPSByZXNvbHZlO1xuXG4gICAgICBpZiAodGhpcy5fdmFsdWUpIHtcbiAgICAgICAgcmVzb2x2ZSh0aGlzLl92YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUfSB2YWx1ZVxuICAgKi9cbiAgcmVzb2x2ZSh2YWx1ZSkge1xuICAgIGlmICh0aGlzLl92YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBbHJlYWR5IHJlc29sdmVkLicpO1xuICAgIH1cblxuICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XG5cbiAgICBpZiAodGhpcy5fcmVzb2x2ZSkge1xuICAgICAgdGhpcy5fcmVzb2x2ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4geyFQcm9taXNlPFQ+fVxuICAgKi9cbiAgdG9Qcm9taXNlKCkge1xuICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xuICB9XG59XG4iLCJpbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuL0N1c3RvbUVsZW1lbnRJbnRlcm5hbHMuanMnO1xuaW1wb3J0IERvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIgZnJvbSAnLi9Eb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyLmpzJztcbmltcG9ydCBEZWZlcnJlZCBmcm9tICcuL0RlZmVycmVkLmpzJztcbmltcG9ydCAqIGFzIFV0aWxpdGllcyBmcm9tICcuL1V0aWxpdGllcy5qcyc7XG5cbi8qKlxuICogQHVucmVzdHJpY3RlZFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDdXN0b21FbGVtZW50UmVnaXN0cnkge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0geyFDdXN0b21FbGVtZW50SW50ZXJuYWxzfSBpbnRlcm5hbHNcbiAgICovXG4gIGNvbnN0cnVjdG9yKGludGVybmFscykge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5fZWxlbWVudERlZmluaXRpb25Jc1J1bm5pbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFDdXN0b21FbGVtZW50SW50ZXJuYWxzfVxuICAgICAqL1xuICAgIHRoaXMuX2ludGVybmFscyA9IGludGVybmFscztcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFNYXA8c3RyaW5nLCAhRGVmZXJyZWQ8dW5kZWZpbmVkPj59XG4gICAgICovXG4gICAgdGhpcy5fd2hlbkRlZmluZWREZWZlcnJlZCA9IG5ldyBNYXAoKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IGZsdXNoIGNhbGxiYWNrIHRyaWdnZXJzIHRoZSBkb2N1bWVudCB3YWxrIHN5bmNocm9ub3VzbHkuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUZ1bmN0aW9ufVxuICAgICAqL1xuICAgIHRoaXMuX2ZsdXNoQ2FsbGJhY2sgPSBmbiA9PiBmbigpO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLl9mbHVzaFBlbmRpbmcgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFBcnJheTxzdHJpbmc+fVxuICAgICAqL1xuICAgIHRoaXMuX3VuZmx1c2hlZExvY2FsTmFtZXMgPSBbXTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFEb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyfVxuICAgICAqL1xuICAgIHRoaXMuX2RvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIgPSBuZXcgRG9jdW1lbnRDb25zdHJ1Y3Rpb25PYnNlcnZlcihpbnRlcm5hbHMsIGRvY3VtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxOYW1lXG4gICAqIEBwYXJhbSB7IUZ1bmN0aW9ufSBjb25zdHJ1Y3RvclxuICAgKi9cbiAgZGVmaW5lKGxvY2FsTmFtZSwgY29uc3RydWN0b3IpIHtcbiAgICBpZiAoIShjb25zdHJ1Y3RvciBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ3VzdG9tIGVsZW1lbnQgY29uc3RydWN0b3JzIG11c3QgYmUgZnVuY3Rpb25zLicpO1xuICAgIH1cblxuICAgIGlmICghVXRpbGl0aWVzLmlzVmFsaWRDdXN0b21FbGVtZW50TmFtZShsb2NhbE5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYFRoZSBlbGVtZW50IG5hbWUgJyR7bG9jYWxOYW1lfScgaXMgbm90IHZhbGlkLmApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9pbnRlcm5hbHMubG9jYWxOYW1lVG9EZWZpbml0aW9uKGxvY2FsTmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQSBjdXN0b20gZWxlbWVudCB3aXRoIG5hbWUgJyR7bG9jYWxOYW1lfScgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkLmApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9lbGVtZW50RGVmaW5pdGlvbklzUnVubmluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIGN1c3RvbSBlbGVtZW50IGlzIGFscmVhZHkgYmVpbmcgZGVmaW5lZC4nKTtcbiAgICB9XG4gICAgdGhpcy5fZWxlbWVudERlZmluaXRpb25Jc1J1bm5pbmcgPSB0cnVlO1xuXG4gICAgbGV0IGNvbm5lY3RlZENhbGxiYWNrO1xuICAgIGxldCBkaXNjb25uZWN0ZWRDYWxsYmFjaztcbiAgICBsZXQgYWRvcHRlZENhbGxiYWNrO1xuICAgIGxldCBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2s7XG4gICAgbGV0IG9ic2VydmVkQXR0cmlidXRlcztcbiAgICB0cnkge1xuICAgICAgLyoqIEB0eXBlIHshT2JqZWN0fSAqL1xuICAgICAgY29uc3QgcHJvdG90eXBlID0gY29uc3RydWN0b3IucHJvdG90eXBlO1xuICAgICAgaWYgKCEocHJvdG90eXBlIGluc3RhbmNlb2YgT2JqZWN0KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY3VzdG9tIGVsZW1lbnQgY29uc3RydWN0b3JcXCdzIHByb3RvdHlwZSBpcyBub3QgYW4gb2JqZWN0LicpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBnZXRDYWxsYmFjayhuYW1lKSB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrVmFsdWUgPSBwcm90b3R5cGVbbmFtZV07XG4gICAgICAgIGlmIChjYWxsYmFja1ZhbHVlICE9PSB1bmRlZmluZWQgJiYgIShjYWxsYmFja1ZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgJyR7bmFtZX0nIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbi5gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2tWYWx1ZTtcbiAgICAgIH1cblxuICAgICAgY29ubmVjdGVkQ2FsbGJhY2sgPSBnZXRDYWxsYmFjaygnY29ubmVjdGVkQ2FsbGJhY2snKTtcbiAgICAgIGRpc2Nvbm5lY3RlZENhbGxiYWNrID0gZ2V0Q2FsbGJhY2soJ2Rpc2Nvbm5lY3RlZENhbGxiYWNrJyk7XG4gICAgICBhZG9wdGVkQ2FsbGJhY2sgPSBnZXRDYWxsYmFjaygnYWRvcHRlZENhbGxiYWNrJyk7XG4gICAgICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sgPSBnZXRDYWxsYmFjaygnYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrJyk7XG4gICAgICBvYnNlcnZlZEF0dHJpYnV0ZXMgPSBjb25zdHJ1Y3Rvclsnb2JzZXJ2ZWRBdHRyaWJ1dGVzJ10gfHwgW107XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLl9lbGVtZW50RGVmaW5pdGlvbklzUnVubmluZyA9IGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmluaXRpb24gPSB7XG4gICAgICBsb2NhbE5hbWUsXG4gICAgICBjb25zdHJ1Y3RvcixcbiAgICAgIGNvbm5lY3RlZENhbGxiYWNrLFxuICAgICAgZGlzY29ubmVjdGVkQ2FsbGJhY2ssXG4gICAgICBhZG9wdGVkQ2FsbGJhY2ssXG4gICAgICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2ssXG4gICAgICBvYnNlcnZlZEF0dHJpYnV0ZXMsXG4gICAgICBjb25zdHJ1Y3Rpb25TdGFjazogW10sXG4gICAgfTtcblxuICAgIHRoaXMuX2ludGVybmFscy5zZXREZWZpbml0aW9uKGxvY2FsTmFtZSwgZGVmaW5pdGlvbik7XG5cbiAgICB0aGlzLl91bmZsdXNoZWRMb2NhbE5hbWVzLnB1c2gobG9jYWxOYW1lKTtcblxuICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgY2FsbGVkIHRoZSBmbHVzaCBjYWxsYmFjayBhbmQgaXQgaGFzbid0IGNhbGxlZCBiYWNrIHlldCxcbiAgICAvLyBkb24ndCBjYWxsIGl0IGFnYWluLlxuICAgIGlmICghdGhpcy5fZmx1c2hQZW5kaW5nKSB7XG4gICAgICB0aGlzLl9mbHVzaFBlbmRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5fZmx1c2hDYWxsYmFjaygoKSA9PiB0aGlzLl9mbHVzaCgpKTtcbiAgICB9XG4gIH1cblxuICBfZmx1c2goKSB7XG4gICAgLy8gSWYgbm8gbmV3IGRlZmluaXRpb25zIHdlcmUgZGVmaW5lZCwgZG9uJ3QgYXR0ZW1wdCB0byBmbHVzaC4gVGhpcyBjb3VsZFxuICAgIC8vIGhhcHBlbiBpZiBhIGZsdXNoIGNhbGxiYWNrIGtlZXBzIHRoZSBmdW5jdGlvbiBpdCBpcyBnaXZlbiBhbmQgY2FsbHMgaXRcbiAgICAvLyBtdWx0aXBsZSB0aW1lcy5cbiAgICBpZiAodGhpcy5fZmx1c2hQZW5kaW5nID09PSBmYWxzZSkgcmV0dXJuO1xuXG4gICAgdGhpcy5fZmx1c2hQZW5kaW5nID0gZmFsc2U7XG4gICAgdGhpcy5faW50ZXJuYWxzLnBhdGNoQW5kVXBncmFkZVRyZWUoZG9jdW1lbnQpO1xuXG4gICAgd2hpbGUgKHRoaXMuX3VuZmx1c2hlZExvY2FsTmFtZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgbG9jYWxOYW1lID0gdGhpcy5fdW5mbHVzaGVkTG9jYWxOYW1lcy5zaGlmdCgpO1xuICAgICAgY29uc3QgZGVmZXJyZWQgPSB0aGlzLl93aGVuRGVmaW5lZERlZmVycmVkLmdldChsb2NhbE5hbWUpO1xuICAgICAgaWYgKGRlZmVycmVkKSB7XG4gICAgICAgIGRlZmVycmVkLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsTmFtZVxuICAgKiBAcmV0dXJuIHtGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAqL1xuICBnZXQobG9jYWxOYW1lKSB7XG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IHRoaXMuX2ludGVybmFscy5sb2NhbE5hbWVUb0RlZmluaXRpb24obG9jYWxOYW1lKTtcbiAgICBpZiAoZGVmaW5pdGlvbikge1xuICAgICAgcmV0dXJuIGRlZmluaXRpb24uY29uc3RydWN0b3I7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxOYW1lXG4gICAqIEByZXR1cm4geyFQcm9taXNlPHVuZGVmaW5lZD59XG4gICAqL1xuICB3aGVuRGVmaW5lZChsb2NhbE5hbWUpIHtcbiAgICBpZiAoIVV0aWxpdGllcy5pc1ZhbGlkQ3VzdG9tRWxlbWVudE5hbWUobG9jYWxOYW1lKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBTeW50YXhFcnJvcihgJyR7bG9jYWxOYW1lfScgaXMgbm90IGEgdmFsaWQgY3VzdG9tIGVsZW1lbnQgbmFtZS5gKSk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJpb3IgPSB0aGlzLl93aGVuRGVmaW5lZERlZmVycmVkLmdldChsb2NhbE5hbWUpO1xuICAgIGlmIChwcmlvcikge1xuICAgICAgcmV0dXJuIHByaW9yLnRvUHJvbWlzZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmVycmVkID0gbmV3IERlZmVycmVkKCk7XG4gICAgdGhpcy5fd2hlbkRlZmluZWREZWZlcnJlZC5zZXQobG9jYWxOYW1lLCBkZWZlcnJlZCk7XG5cbiAgICBjb25zdCBkZWZpbml0aW9uID0gdGhpcy5faW50ZXJuYWxzLmxvY2FsTmFtZVRvRGVmaW5pdGlvbihsb2NhbE5hbWUpO1xuICAgIC8vIFJlc29sdmUgaW1tZWRpYXRlbHkgb25seSBpZiB0aGUgZ2l2ZW4gbG9jYWwgbmFtZSBoYXMgYSBkZWZpbml0aW9uICphbmQqXG4gICAgLy8gdGhlIGZ1bGwgZG9jdW1lbnQgd2FsayB0byB1cGdyYWRlIGVsZW1lbnRzIHdpdGggdGhhdCBsb2NhbCBuYW1lIGhhc1xuICAgIC8vIGFscmVhZHkgaGFwcGVuZWQuXG4gICAgaWYgKGRlZmluaXRpb24gJiYgdGhpcy5fdW5mbHVzaGVkTG9jYWxOYW1lcy5pbmRleE9mKGxvY2FsTmFtZSkgPT09IC0xKSB7XG4gICAgICBkZWZlcnJlZC5yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlZmVycmVkLnRvUHJvbWlzZSgpO1xuICB9XG5cbiAgcG9seWZpbGxXcmFwRmx1c2hDYWxsYmFjayhvdXRlcikge1xuICAgIHRoaXMuX2RvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZmx1c2hDYWxsYmFjaztcbiAgICB0aGlzLl9mbHVzaENhbGxiYWNrID0gZmx1c2ggPT4gb3V0ZXIoKCkgPT4gaW5uZXIoZmx1c2gpKTtcbiAgfVxufVxuXG4vLyBDbG9zdXJlIGNvbXBpbGVyIGV4cG9ydHMuXG53aW5kb3dbJ0N1c3RvbUVsZW1lbnRSZWdpc3RyeSddID0gQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5O1xuQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZVsnZGVmaW5lJ10gPSBDdXN0b21FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmRlZmluZTtcbkN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGVbJ2dldCddID0gQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5nZXQ7XG5DdXN0b21FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlWyd3aGVuRGVmaW5lZCddID0gQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS53aGVuRGVmaW5lZDtcbkN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGVbJ3BvbHlmaWxsV3JhcEZsdXNoQ2FsbGJhY2snXSA9IEN1c3RvbUVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUucG9seWZpbGxXcmFwRmx1c2hDYWxsYmFjaztcbiIsImV4cG9ydCBkZWZhdWx0IHtcbiAgRG9jdW1lbnRfY3JlYXRlRWxlbWVudDogd2luZG93LkRvY3VtZW50LnByb3RvdHlwZS5jcmVhdGVFbGVtZW50LFxuICBEb2N1bWVudF9jcmVhdGVFbGVtZW50TlM6IHdpbmRvdy5Eb2N1bWVudC5wcm90b3R5cGUuY3JlYXRlRWxlbWVudE5TLFxuICBEb2N1bWVudF9pbXBvcnROb2RlOiB3aW5kb3cuRG9jdW1lbnQucHJvdG90eXBlLmltcG9ydE5vZGUsXG4gIERvY3VtZW50X3ByZXBlbmQ6IHdpbmRvdy5Eb2N1bWVudC5wcm90b3R5cGVbJ3ByZXBlbmQnXSxcbiAgRG9jdW1lbnRfYXBwZW5kOiB3aW5kb3cuRG9jdW1lbnQucHJvdG90eXBlWydhcHBlbmQnXSxcbiAgTm9kZV9jbG9uZU5vZGU6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5jbG9uZU5vZGUsXG4gIE5vZGVfYXBwZW5kQ2hpbGQ6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5hcHBlbmRDaGlsZCxcbiAgTm9kZV9pbnNlcnRCZWZvcmU6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5pbnNlcnRCZWZvcmUsXG4gIE5vZGVfcmVtb3ZlQ2hpbGQ6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5yZW1vdmVDaGlsZCxcbiAgTm9kZV9yZXBsYWNlQ2hpbGQ6IHdpbmRvdy5Ob2RlLnByb3RvdHlwZS5yZXBsYWNlQ2hpbGQsXG4gIE5vZGVfdGV4dENvbnRlbnQ6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iod2luZG93Lk5vZGUucHJvdG90eXBlLCAndGV4dENvbnRlbnQnKSxcbiAgRWxlbWVudF9hdHRhY2hTaGFkb3c6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsnYXR0YWNoU2hhZG93J10sXG4gIEVsZW1lbnRfaW5uZXJIVE1MOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZSwgJ2lubmVySFRNTCcpLFxuICBFbGVtZW50X2dldEF0dHJpYnV0ZTogd2luZG93LkVsZW1lbnQucHJvdG90eXBlLmdldEF0dHJpYnV0ZSxcbiAgRWxlbWVudF9zZXRBdHRyaWJ1dGU6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGUsXG4gIEVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGUucmVtb3ZlQXR0cmlidXRlLFxuICBFbGVtZW50X2dldEF0dHJpYnV0ZU5TOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGUuZ2V0QXR0cmlidXRlTlMsXG4gIEVsZW1lbnRfc2V0QXR0cmlidXRlTlM6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGVOUyxcbiAgRWxlbWVudF9yZW1vdmVBdHRyaWJ1dGVOUzogd2luZG93LkVsZW1lbnQucHJvdG90eXBlLnJlbW92ZUF0dHJpYnV0ZU5TLFxuICBFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudDogd2luZG93LkVsZW1lbnQucHJvdG90eXBlWydpbnNlcnRBZGphY2VudEVsZW1lbnQnXSxcbiAgRWxlbWVudF9wcmVwZW5kOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGVbJ3ByZXBlbmQnXSxcbiAgRWxlbWVudF9hcHBlbmQ6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsnYXBwZW5kJ10sXG4gIEVsZW1lbnRfYmVmb3JlOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGVbJ2JlZm9yZSddLFxuICBFbGVtZW50X2FmdGVyOiB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGVbJ2FmdGVyJ10sXG4gIEVsZW1lbnRfcmVwbGFjZVdpdGg6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsncmVwbGFjZVdpdGgnXSxcbiAgRWxlbWVudF9yZW1vdmU6IHdpbmRvdy5FbGVtZW50LnByb3RvdHlwZVsncmVtb3ZlJ10sXG4gIEhUTUxFbGVtZW50OiB3aW5kb3cuSFRNTEVsZW1lbnQsXG4gIEhUTUxFbGVtZW50X2lubmVySFRNTDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3cuSFRNTEVsZW1lbnQucHJvdG90eXBlLCAnaW5uZXJIVE1MJyksXG4gIEhUTUxFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudDogd2luZG93LkhUTUxFbGVtZW50LnByb3RvdHlwZVsnaW5zZXJ0QWRqYWNlbnRFbGVtZW50J10sXG59O1xuIiwiLyoqXG4gKiBUaGlzIGNsYXNzIGV4aXN0cyBvbmx5IHRvIHdvcmsgYXJvdW5kIENsb3N1cmUncyBsYWNrIG9mIGEgd2F5IHRvIGRlc2NyaWJlXG4gKiBzaW5nbGV0b25zLiBJdCByZXByZXNlbnRzIHRoZSAnYWxyZWFkeSBjb25zdHJ1Y3RlZCBtYXJrZXInIHVzZWQgaW4gY3VzdG9tXG4gKiBlbGVtZW50IGNvbnN0cnVjdGlvbiBzdGFja3MuXG4gKlxuICogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jY29uY2VwdC1hbHJlYWR5LWNvbnN0cnVjdGVkLW1hcmtlclxuICovXG5jbGFzcyBBbHJlYWR5Q29uc3RydWN0ZWRNYXJrZXIge31cblxuZXhwb3J0IGRlZmF1bHQgbmV3IEFscmVhZHlDb25zdHJ1Y3RlZE1hcmtlcigpO1xuIiwiaW1wb3J0IE5hdGl2ZSBmcm9tICcuL05hdGl2ZS5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuLi9DdXN0b21FbGVtZW50SW50ZXJuYWxzLmpzJztcbmltcG9ydCBDRVN0YXRlIGZyb20gJy4uL0N1c3RvbUVsZW1lbnRTdGF0ZS5qcyc7XG5pbXBvcnQgQWxyZWFkeUNvbnN0cnVjdGVkTWFya2VyIGZyb20gJy4uL0FscmVhZHlDb25zdHJ1Y3RlZE1hcmtlci5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gaW50ZXJuYWxzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGludGVybmFscykge1xuICB3aW5kb3dbJ0hUTUxFbGVtZW50J10gPSAoZnVuY3Rpb24oKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKG5ldzogSFRNTEVsZW1lbnQpOiAhSFRNTEVsZW1lbnR9XG4gICAgICovXG4gICAgZnVuY3Rpb24gSFRNTEVsZW1lbnQoKSB7XG4gICAgICAvLyBUaGlzIHNob3VsZCByZWFsbHkgYmUgYG5ldy50YXJnZXRgIGJ1dCBgbmV3LnRhcmdldGAgY2FuJ3QgYmUgZW11bGF0ZWRcbiAgICAgIC8vIGluIEVTNS4gQXNzdW1pbmcgdGhlIHVzZXIga2VlcHMgdGhlIGRlZmF1bHQgdmFsdWUgb2YgdGhlIGNvbnN0cnVjdG9yJ3NcbiAgICAgIC8vIHByb3RvdHlwZSdzIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHksIHRoaXMgaXMgZXF1aXZhbGVudC5cbiAgICAgIC8qKiBAdHlwZSB7IUZ1bmN0aW9ufSAqL1xuICAgICAgY29uc3QgY29uc3RydWN0b3IgPSB0aGlzLmNvbnN0cnVjdG9yO1xuXG4gICAgICBjb25zdCBkZWZpbml0aW9uID0gaW50ZXJuYWxzLmNvbnN0cnVjdG9yVG9EZWZpbml0aW9uKGNvbnN0cnVjdG9yKTtcbiAgICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjdXN0b20gZWxlbWVudCBiZWluZyBjb25zdHJ1Y3RlZCB3YXMgbm90IHJlZ2lzdGVyZWQgd2l0aCBgY3VzdG9tRWxlbWVudHNgLicpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjb25zdHJ1Y3Rpb25TdGFjayA9IGRlZmluaXRpb24uY29uc3RydWN0aW9uU3RhY2s7XG5cbiAgICAgIGlmIChjb25zdHJ1Y3Rpb25TdGFjay5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IE5hdGl2ZS5Eb2N1bWVudF9jcmVhdGVFbGVtZW50LmNhbGwoZG9jdW1lbnQsIGRlZmluaXRpb24ubG9jYWxOYW1lKTtcbiAgICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGVsZW1lbnQsIGNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gICAgICAgIGVsZW1lbnQuX19DRV9zdGF0ZSA9IENFU3RhdGUuY3VzdG9tO1xuICAgICAgICBlbGVtZW50Ll9fQ0VfZGVmaW5pdGlvbiA9IGRlZmluaXRpb247XG4gICAgICAgIGludGVybmFscy5wYXRjaChlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxhc3RJbmRleCA9IGNvbnN0cnVjdGlvblN0YWNrLmxlbmd0aCAtIDE7XG4gICAgICBjb25zdCBlbGVtZW50ID0gY29uc3RydWN0aW9uU3RhY2tbbGFzdEluZGV4XTtcbiAgICAgIGlmIChlbGVtZW50ID09PSBBbHJlYWR5Q29uc3RydWN0ZWRNYXJrZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgSFRNTEVsZW1lbnQgY29uc3RydWN0b3Igd2FzIGVpdGhlciBjYWxsZWQgcmVlbnRyYW50bHkgZm9yIHRoaXMgY29uc3RydWN0b3Igb3IgY2FsbGVkIG11bHRpcGxlIHRpbWVzLicpO1xuICAgICAgfVxuICAgICAgY29uc3RydWN0aW9uU3RhY2tbbGFzdEluZGV4XSA9IEFscmVhZHlDb25zdHJ1Y3RlZE1hcmtlcjtcblxuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGVsZW1lbnQsIGNvbnN0cnVjdG9yLnByb3RvdHlwZSk7XG4gICAgICBpbnRlcm5hbHMucGF0Y2goLyoqIEB0eXBlIHshSFRNTEVsZW1lbnR9ICovIChlbGVtZW50KSk7XG5cbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIEhUTUxFbGVtZW50LnByb3RvdHlwZSA9IE5hdGl2ZS5IVE1MRWxlbWVudC5wcm90b3R5cGU7XG5cbiAgICByZXR1cm4gSFRNTEVsZW1lbnQ7XG4gIH0pKCk7XG59O1xuIiwiaW1wb3J0IEN1c3RvbUVsZW1lbnRJbnRlcm5hbHMgZnJvbSAnLi4vLi4vQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyc7XG5pbXBvcnQgKiBhcyBVdGlsaXRpZXMgZnJvbSAnLi4vLi4vVXRpbGl0aWVzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogICBwcmVwZW5kOiAhZnVuY3Rpb24oLi4uKCFOb2RlfHN0cmluZykpLFxuICAqICBhcHBlbmQ6ICFmdW5jdGlvbiguLi4oIU5vZGV8c3RyaW5nKSksXG4gKiB9fVxuICovXG5sZXQgUGFyZW50Tm9kZU5hdGl2ZU1ldGhvZHM7XG5cbi8qKlxuICogQHBhcmFtIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gaW50ZXJuYWxzXG4gKiBAcGFyYW0geyFPYmplY3R9IGRlc3RpbmF0aW9uXG4gKiBAcGFyYW0geyFQYXJlbnROb2RlTmF0aXZlTWV0aG9kc30gYnVpbHRJblxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMsIGRlc3RpbmF0aW9uLCBidWlsdEluKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ3ByZXBlbmQnXSA9IGZ1bmN0aW9uKC4uLm5vZGVzKSB7XG4gICAgLy8gVE9ETzogRml4IHRoaXMgZm9yIHdoZW4gb25lIG9mIGBub2Rlc2AgaXMgYSBEb2N1bWVudEZyYWdtZW50IVxuICAgIGNvbnN0IGNvbm5lY3RlZEJlZm9yZSA9IC8qKiBAdHlwZSB7IUFycmF5PCFOb2RlPn0gKi8gKG5vZGVzLmZpbHRlcihub2RlID0+IHtcbiAgICAgIC8vIERvY3VtZW50RnJhZ21lbnRzIGFyZSBub3QgY29ubmVjdGVkIGFuZCB3aWxsIG5vdCBiZSBhZGRlZCB0byB0aGUgbGlzdC5cbiAgICAgIHJldHVybiBub2RlIGluc3RhbmNlb2YgTm9kZSAmJiBVdGlsaXRpZXMuaXNDb25uZWN0ZWQobm9kZSk7XG4gICAgfSkpO1xuXG4gICAgYnVpbHRJbi5wcmVwZW5kLmFwcGx5KHRoaXMsIG5vZGVzKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29ubmVjdGVkQmVmb3JlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUoY29ubmVjdGVkQmVmb3JlW2ldKTtcbiAgICB9XG5cbiAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmNvbm5lY3RUcmVlKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ2FwcGVuZCddID0gZnVuY3Rpb24oLi4ubm9kZXMpIHtcbiAgICAvLyBUT0RPOiBGaXggdGhpcyBmb3Igd2hlbiBvbmUgb2YgYG5vZGVzYCBpcyBhIERvY3VtZW50RnJhZ21lbnQhXG4gICAgY29uc3QgY29ubmVjdGVkQmVmb3JlID0gLyoqIEB0eXBlIHshQXJyYXk8IU5vZGU+fSAqLyAobm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgYW5kIHdpbGwgbm90IGJlIGFkZGVkIHRvIHRoZSBsaXN0LlxuICAgICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICB9KSk7XG5cbiAgICBidWlsdEluLmFwcGVuZC5hcHBseSh0aGlzLCBub2Rlcyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5lY3RlZEJlZm9yZS5sZW5ndGg7IGkrKykge1xuICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKGNvbm5lY3RlZEJlZm9yZVtpXSk7XG4gICAgfVxuXG4gICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShub2RlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbn07XG4iLCJpbXBvcnQgTmF0aXZlIGZyb20gJy4vTmF0aXZlLmpzJztcbmltcG9ydCBDdXN0b21FbGVtZW50SW50ZXJuYWxzIGZyb20gJy4uL0N1c3RvbUVsZW1lbnRJbnRlcm5hbHMuanMnO1xuaW1wb3J0ICogYXMgVXRpbGl0aWVzIGZyb20gJy4uL1V0aWxpdGllcy5qcyc7XG5cbmltcG9ydCBQYXRjaFBhcmVudE5vZGUgZnJvbSAnLi9JbnRlcmZhY2UvUGFyZW50Tm9kZS5qcyc7XG5cbi8qKlxuICogQHBhcmFtIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gaW50ZXJuYWxzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGludGVybmFscykge1xuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRG9jdW1lbnQucHJvdG90eXBlLCAnY3JlYXRlRWxlbWVudCcsXG4gICAgLyoqXG4gICAgICogQHRoaXMge0RvY3VtZW50fVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbE5hbWVcbiAgICAgKiBAcmV0dXJuIHshRWxlbWVudH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbihsb2NhbE5hbWUpIHtcbiAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGRvY3VtZW50IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkuXG4gICAgICBpZiAodGhpcy5fX0NFX2hhc1JlZ2lzdHJ5KSB7XG4gICAgICAgIGNvbnN0IGRlZmluaXRpb24gPSBpbnRlcm5hbHMubG9jYWxOYW1lVG9EZWZpbml0aW9uKGxvY2FsTmFtZSk7XG4gICAgICAgIGlmIChkZWZpbml0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyAoZGVmaW5pdGlvbi5jb25zdHJ1Y3RvcikoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQgPSAvKiogQHR5cGUgeyFFbGVtZW50fSAqL1xuICAgICAgICAoTmF0aXZlLkRvY3VtZW50X2NyZWF0ZUVsZW1lbnQuY2FsbCh0aGlzLCBsb2NhbE5hbWUpKTtcbiAgICAgIGludGVybmFscy5wYXRjaChyZXN1bHQpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRG9jdW1lbnQucHJvdG90eXBlLCAnaW1wb3J0Tm9kZScsXG4gICAgLyoqXG4gICAgICogQHRoaXMge0RvY3VtZW50fVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBkZWVwXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZSwgZGVlcCkge1xuICAgICAgY29uc3QgY2xvbmUgPSBOYXRpdmUuRG9jdW1lbnRfaW1wb3J0Tm9kZS5jYWxsKHRoaXMsIG5vZGUsIGRlZXApO1xuICAgICAgLy8gT25seSBjcmVhdGUgY3VzdG9tIGVsZW1lbnRzIGlmIHRoaXMgZG9jdW1lbnQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeS5cbiAgICAgIGlmICghdGhpcy5fX0NFX2hhc1JlZ2lzdHJ5KSB7XG4gICAgICAgIGludGVybmFscy5wYXRjaFRyZWUoY2xvbmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW50ZXJuYWxzLnBhdGNoQW5kVXBncmFkZVRyZWUoY2xvbmUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNsb25lO1xuICAgIH0pO1xuXG4gIGNvbnN0IE5TX0hUTUwgPSBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIjtcblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRG9jdW1lbnQucHJvdG90eXBlLCAnY3JlYXRlRWxlbWVudE5TJyxcbiAgICAvKipcbiAgICAgKiBAdGhpcyB7RG9jdW1lbnR9XG4gICAgICogQHBhcmFtIHs/c3RyaW5nfSBuYW1lc3BhY2VcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbG9jYWxOYW1lXG4gICAgICogQHJldHVybiB7IUVsZW1lbnR9XG4gICAgICovXG4gICAgZnVuY3Rpb24obmFtZXNwYWNlLCBsb2NhbE5hbWUpIHtcbiAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGRvY3VtZW50IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkuXG4gICAgICBpZiAodGhpcy5fX0NFX2hhc1JlZ2lzdHJ5ICYmIChuYW1lc3BhY2UgPT09IG51bGwgfHwgbmFtZXNwYWNlID09PSBOU19IVE1MKSkge1xuICAgICAgICBjb25zdCBkZWZpbml0aW9uID0gaW50ZXJuYWxzLmxvY2FsTmFtZVRvRGVmaW5pdGlvbihsb2NhbE5hbWUpO1xuICAgICAgICBpZiAoZGVmaW5pdGlvbikge1xuICAgICAgICAgIHJldHVybiBuZXcgKGRlZmluaXRpb24uY29uc3RydWN0b3IpKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gLyoqIEB0eXBlIHshRWxlbWVudH0gKi9cbiAgICAgICAgKE5hdGl2ZS5Eb2N1bWVudF9jcmVhdGVFbGVtZW50TlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIGxvY2FsTmFtZSkpO1xuICAgICAgaW50ZXJuYWxzLnBhdGNoKHJlc3VsdCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gIFBhdGNoUGFyZW50Tm9kZShpbnRlcm5hbHMsIERvY3VtZW50LnByb3RvdHlwZSwge1xuICAgIHByZXBlbmQ6IE5hdGl2ZS5Eb2N1bWVudF9wcmVwZW5kLFxuICAgIGFwcGVuZDogTmF0aXZlLkRvY3VtZW50X2FwcGVuZCxcbiAgfSk7XG59O1xuIiwiaW1wb3J0IE5hdGl2ZSBmcm9tICcuL05hdGl2ZS5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuLi9DdXN0b21FbGVtZW50SW50ZXJuYWxzLmpzJztcbmltcG9ydCAqIGFzIFV0aWxpdGllcyBmcm9tICcuLi9VdGlsaXRpZXMuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9IGludGVybmFsc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMpIHtcbiAgLy8gYE5vZGUjbm9kZVZhbHVlYCBpcyBpbXBsZW1lbnRlZCBvbiBgQXR0cmAuXG4gIC8vIGBOb2RlI3RleHRDb250ZW50YCBpcyBpbXBsZW1lbnRlZCBvbiBgQXR0cmAsIGBFbGVtZW50YC5cblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoTm9kZS5wcm90b3R5cGUsICdpbnNlcnRCZWZvcmUnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtOb2RlfVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcGFyYW0gez9Ob2RlfSByZWZOb2RlXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZSwgcmVmTm9kZSkge1xuICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSB7XG4gICAgICAgIGNvbnN0IGluc2VydGVkTm9kZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkobm9kZS5jaGlsZE5vZGVzKTtcbiAgICAgICAgY29uc3QgbmF0aXZlUmVzdWx0ID0gTmF0aXZlLk5vZGVfaW5zZXJ0QmVmb3JlLmNhbGwodGhpcywgbm9kZSwgcmVmTm9kZSk7XG5cbiAgICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgY2FuJ3QgYmUgY29ubmVjdGVkLCBzbyBgZGlzY29ubmVjdFRyZWVgIHdpbGwgbmV2ZXJcbiAgICAgICAgLy8gbmVlZCB0byBiZSBjYWxsZWQgb24gYSBEb2N1bWVudEZyYWdtZW50J3MgY2hpbGRyZW4gYWZ0ZXIgaW5zZXJ0aW5nIGl0LlxuXG4gICAgICAgIGlmIChVdGlsaXRpZXMuaXNDb25uZWN0ZWQodGhpcykpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluc2VydGVkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShpbnNlcnRlZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmF0aXZlUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlV2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKG5vZGUpO1xuICAgICAgY29uc3QgbmF0aXZlUmVzdWx0ID0gTmF0aXZlLk5vZGVfaW5zZXJ0QmVmb3JlLmNhbGwodGhpcywgbm9kZSwgcmVmTm9kZSk7XG5cbiAgICAgIGlmIChub2RlV2FzQ29ubmVjdGVkKSB7XG4gICAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZShub2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuYXRpdmVSZXN1bHQ7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKE5vZGUucHJvdG90eXBlLCAnYXBwZW5kQ2hpbGQnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtOb2RlfVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcmV0dXJuIHshTm9kZX1cbiAgICAgKi9cbiAgICBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIERvY3VtZW50RnJhZ21lbnQpIHtcbiAgICAgICAgY29uc3QgaW5zZXJ0ZWROb2RlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseShub2RlLmNoaWxkTm9kZXMpO1xuICAgICAgICBjb25zdCBuYXRpdmVSZXN1bHQgPSBOYXRpdmUuTm9kZV9hcHBlbmRDaGlsZC5jYWxsKHRoaXMsIG5vZGUpO1xuXG4gICAgICAgIC8vIERvY3VtZW50RnJhZ21lbnRzIGNhbid0IGJlIGNvbm5lY3RlZCwgc28gYGRpc2Nvbm5lY3RUcmVlYCB3aWxsIG5ldmVyXG4gICAgICAgIC8vIG5lZWQgdG8gYmUgY2FsbGVkIG9uIGEgRG9jdW1lbnRGcmFnbWVudCdzIGNoaWxkcmVuIGFmdGVyIGluc2VydGluZyBpdC5cblxuICAgICAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnNlcnRlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUoaW5zZXJ0ZWROb2Rlc1tpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5hdGl2ZVJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm9kZVdhc0Nvbm5lY3RlZCA9IFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICAgIGNvbnN0IG5hdGl2ZVJlc3VsdCA9IE5hdGl2ZS5Ob2RlX2FwcGVuZENoaWxkLmNhbGwodGhpcywgbm9kZSk7XG5cbiAgICAgIGlmIChub2RlV2FzQ29ubmVjdGVkKSB7XG4gICAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZShub2RlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuYXRpdmVSZXN1bHQ7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKE5vZGUucHJvdG90eXBlLCAnY2xvbmVOb2RlJyxcbiAgICAvKipcbiAgICAgKiBAdGhpcyB7Tm9kZX1cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBkZWVwXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24oZGVlcCkge1xuICAgICAgY29uc3QgY2xvbmUgPSBOYXRpdmUuTm9kZV9jbG9uZU5vZGUuY2FsbCh0aGlzLCBkZWVwKTtcbiAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGVsZW1lbnQncyBvd25lciBkb2N1bWVudCBpc1xuICAgICAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeS5cbiAgICAgIGlmICghdGhpcy5vd25lckRvY3VtZW50Ll9fQ0VfaGFzUmVnaXN0cnkpIHtcbiAgICAgICAgaW50ZXJuYWxzLnBhdGNoVHJlZShjbG9uZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnRlcm5hbHMucGF0Y2hBbmRVcGdyYWRlVHJlZShjbG9uZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2xvbmU7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKE5vZGUucHJvdG90eXBlLCAncmVtb3ZlQ2hpbGQnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtOb2RlfVxuICAgICAqIEBwYXJhbSB7IU5vZGV9IG5vZGVcbiAgICAgKiBAcmV0dXJuIHshTm9kZX1cbiAgICAgKi9cbiAgICBmdW5jdGlvbihub2RlKSB7XG4gICAgICBjb25zdCBub2RlV2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKG5vZGUpO1xuICAgICAgY29uc3QgbmF0aXZlUmVzdWx0ID0gTmF0aXZlLk5vZGVfcmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCBub2RlKTtcblxuICAgICAgaWYgKG5vZGVXYXNDb25uZWN0ZWQpIHtcbiAgICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKG5vZGUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmF0aXZlUmVzdWx0O1xuICAgIH0pO1xuXG4gIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChOb2RlLnByb3RvdHlwZSwgJ3JlcGxhY2VDaGlsZCcsXG4gICAgLyoqXG4gICAgICogQHRoaXMge05vZGV9XG4gICAgICogQHBhcmFtIHshTm9kZX0gbm9kZVRvSW5zZXJ0XG4gICAgICogQHBhcmFtIHshTm9kZX0gbm9kZVRvUmVtb3ZlXG4gICAgICogQHJldHVybiB7IU5vZGV9XG4gICAgICovXG4gICAgZnVuY3Rpb24obm9kZVRvSW5zZXJ0LCBub2RlVG9SZW1vdmUpIHtcbiAgICAgIGlmIChub2RlVG9JbnNlcnQgaW5zdGFuY2VvZiBEb2N1bWVudEZyYWdtZW50KSB7XG4gICAgICAgIGNvbnN0IGluc2VydGVkTm9kZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkobm9kZVRvSW5zZXJ0LmNoaWxkTm9kZXMpO1xuICAgICAgICBjb25zdCBuYXRpdmVSZXN1bHQgPSBOYXRpdmUuTm9kZV9yZXBsYWNlQ2hpbGQuY2FsbCh0aGlzLCBub2RlVG9JbnNlcnQsIG5vZGVUb1JlbW92ZSk7XG5cbiAgICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgY2FuJ3QgYmUgY29ubmVjdGVkLCBzbyBgZGlzY29ubmVjdFRyZWVgIHdpbGwgbmV2ZXJcbiAgICAgICAgLy8gbmVlZCB0byBiZSBjYWxsZWQgb24gYSBEb2N1bWVudEZyYWdtZW50J3MgY2hpbGRyZW4gYWZ0ZXIgaW5zZXJ0aW5nIGl0LlxuXG4gICAgICAgIGlmIChVdGlsaXRpZXMuaXNDb25uZWN0ZWQodGhpcykpIHtcbiAgICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUobm9kZVRvUmVtb3ZlKTtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluc2VydGVkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShpbnNlcnRlZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmF0aXZlUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlVG9JbnNlcnRXYXNDb25uZWN0ZWQgPSBVdGlsaXRpZXMuaXNDb25uZWN0ZWQobm9kZVRvSW5zZXJ0KTtcbiAgICAgIGNvbnN0IG5hdGl2ZVJlc3VsdCA9IE5hdGl2ZS5Ob2RlX3JlcGxhY2VDaGlsZC5jYWxsKHRoaXMsIG5vZGVUb0luc2VydCwgbm9kZVRvUmVtb3ZlKTtcbiAgICAgIGNvbnN0IHRoaXNJc0Nvbm5lY3RlZCA9IFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKTtcblxuICAgICAgaWYgKHRoaXNJc0Nvbm5lY3RlZCkge1xuICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUobm9kZVRvUmVtb3ZlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVUb0luc2VydFdhc0Nvbm5lY3RlZCkge1xuICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUobm9kZVRvSW5zZXJ0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXNJc0Nvbm5lY3RlZCkge1xuICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZVRvSW5zZXJ0KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5hdGl2ZVJlc3VsdDtcbiAgICB9KTtcblxuXG4gIGZ1bmN0aW9uIHBhdGNoX3RleHRDb250ZW50KGRlc3RpbmF0aW9uLCBiYXNlRGVzY3JpcHRvcikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZXN0aW5hdGlvbiwgJ3RleHRDb250ZW50Jywge1xuICAgICAgZW51bWVyYWJsZTogYmFzZURlc2NyaXB0b3IuZW51bWVyYWJsZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogYmFzZURlc2NyaXB0b3IuZ2V0LFxuICAgICAgc2V0OiAvKiogQHRoaXMge05vZGV9ICovIGZ1bmN0aW9uKGFzc2lnbmVkVmFsdWUpIHtcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIHRleHQgbm9kZSB0aGVuIHRoZXJlIGFyZSBubyBub2RlcyB0byBkaXNjb25uZWN0LlxuICAgICAgICBpZiAodGhpcy5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgICAgICBiYXNlRGVzY3JpcHRvci5zZXQuY2FsbCh0aGlzLCBhc3NpZ25lZFZhbHVlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgcmVtb3ZlZE5vZGVzID0gdW5kZWZpbmVkO1xuICAgICAgICAvLyBDaGVja2luZyBmb3IgYGZpcnN0Q2hpbGRgIGlzIGZhc3RlciB0aGFuIHJlYWRpbmcgYGNoaWxkTm9kZXMubGVuZ3RoYFxuICAgICAgICAvLyB0byBjb21wYXJlIHdpdGggMC5cbiAgICAgICAgaWYgKHRoaXMuZmlyc3RDaGlsZCkge1xuICAgICAgICAgIC8vIFVzaW5nIGBjaGlsZE5vZGVzYCBpcyBmYXN0ZXIgdGhhbiBgY2hpbGRyZW5gLCBldmVuIHRob3VnaCB3ZSBvbmx5XG4gICAgICAgICAgLy8gY2FyZSBhYm91dCBlbGVtZW50cy5cbiAgICAgICAgICBjb25zdCBjaGlsZE5vZGVzID0gdGhpcy5jaGlsZE5vZGVzO1xuICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZXNMZW5ndGggPSBjaGlsZE5vZGVzLmxlbmd0aDtcbiAgICAgICAgICBpZiAoY2hpbGROb2Rlc0xlbmd0aCA+IDAgJiYgVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICAgICAgICAvLyBDb3B5aW5nIGFuIGFycmF5IGJ5IGl0ZXJhdGluZyBpcyBmYXN0ZXIgdGhhbiB1c2luZyBzbGljZS5cbiAgICAgICAgICAgIHJlbW92ZWROb2RlcyA9IG5ldyBBcnJheShjaGlsZE5vZGVzTGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGROb2Rlc0xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIHJlbW92ZWROb2Rlc1tpXSA9IGNoaWxkTm9kZXNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYmFzZURlc2NyaXB0b3Iuc2V0LmNhbGwodGhpcywgYXNzaWduZWRWYWx1ZSk7XG5cbiAgICAgICAgaWYgKHJlbW92ZWROb2Rlcykge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVtb3ZlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUocmVtb3ZlZE5vZGVzW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBpZiAoTmF0aXZlLk5vZGVfdGV4dENvbnRlbnQgJiYgTmF0aXZlLk5vZGVfdGV4dENvbnRlbnQuZ2V0KSB7XG4gICAgcGF0Y2hfdGV4dENvbnRlbnQoTm9kZS5wcm90b3R5cGUsIE5hdGl2ZS5Ob2RlX3RleHRDb250ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBpbnRlcm5hbHMuYWRkUGF0Y2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcGF0Y2hfdGV4dENvbnRlbnQoZWxlbWVudCwge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIC8vIE5PVEU6IFRoaXMgaW1wbGVtZW50YXRpb24gb2YgdGhlIGB0ZXh0Q29udGVudGAgZ2V0dGVyIGFzc3VtZXMgdGhhdFxuICAgICAgICAvLyB0ZXh0IG5vZGVzJyBgdGV4dENvbnRlbnRgIGdldHRlciB3aWxsIG5vdCBiZSBwYXRjaGVkLlxuICAgICAgICBnZXQ6IC8qKiBAdGhpcyB7Tm9kZX0gKi8gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgLyoqIEB0eXBlIHshQXJyYXk8c3RyaW5nPn0gKi9cbiAgICAgICAgICBjb25zdCBwYXJ0cyA9IFtdO1xuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHBhcnRzLnB1c2godGhpcy5jaGlsZE5vZGVzW2ldLnRleHRDb250ZW50KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFydHMuam9pbignJyk7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogLyoqIEB0aGlzIHtOb2RlfSAqLyBmdW5jdGlvbihhc3NpZ25lZFZhbHVlKSB7XG4gICAgICAgICAgd2hpbGUgKHRoaXMuZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgTmF0aXZlLk5vZGVfcmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCB0aGlzLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBOYXRpdmUuTm9kZV9hcHBlbmRDaGlsZC5jYWxsKHRoaXMsIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGFzc2lnbmVkVmFsdWUpKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59O1xuIiwiaW1wb3J0IEN1c3RvbUVsZW1lbnRJbnRlcm5hbHMgZnJvbSAnLi4vLi4vQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyc7XG5pbXBvcnQgKiBhcyBVdGlsaXRpZXMgZnJvbSAnLi4vLi4vVXRpbGl0aWVzLmpzJztcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogICBiZWZvcmU6ICFmdW5jdGlvbiguLi4oIU5vZGV8c3RyaW5nKSksXG4gKiAgIGFmdGVyOiAhZnVuY3Rpb24oLi4uKCFOb2RlfHN0cmluZykpLFxuICogICByZXBsYWNlV2l0aDogIWZ1bmN0aW9uKC4uLighTm9kZXxzdHJpbmcpKSxcbiAqICAgcmVtb3ZlOiAhZnVuY3Rpb24oKSxcbiAqIH19XG4gKi9cbmxldCBDaGlsZE5vZGVOYXRpdmVNZXRob2RzO1xuXG4vKipcbiAqIEBwYXJhbSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9IGludGVybmFsc1xuICogQHBhcmFtIHshT2JqZWN0fSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHshQ2hpbGROb2RlTmF0aXZlTWV0aG9kc30gYnVpbHRJblxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMsIGRlc3RpbmF0aW9uLCBidWlsdEluKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ2JlZm9yZSddID0gZnVuY3Rpb24oLi4ubm9kZXMpIHtcbiAgICAvLyBUT0RPOiBGaXggdGhpcyBmb3Igd2hlbiBvbmUgb2YgYG5vZGVzYCBpcyBhIERvY3VtZW50RnJhZ21lbnQhXG4gICAgY29uc3QgY29ubmVjdGVkQmVmb3JlID0gLyoqIEB0eXBlIHshQXJyYXk8IU5vZGU+fSAqLyAobm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgYW5kIHdpbGwgbm90IGJlIGFkZGVkIHRvIHRoZSBsaXN0LlxuICAgICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICB9KSk7XG5cbiAgICBidWlsdEluLmJlZm9yZS5hcHBseSh0aGlzLCBub2Rlcyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5lY3RlZEJlZm9yZS5sZW5ndGg7IGkrKykge1xuICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKGNvbm5lY3RlZEJlZm9yZVtpXSk7XG4gICAgfVxuXG4gICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKSkge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgIGludGVybmFscy5jb25uZWN0VHJlZShub2RlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQHBhcmFtIHsuLi4oIU5vZGV8c3RyaW5nKX0gbm9kZXNcbiAgICovXG4gIGRlc3RpbmF0aW9uWydhZnRlciddID0gZnVuY3Rpb24oLi4ubm9kZXMpIHtcbiAgICAvLyBUT0RPOiBGaXggdGhpcyBmb3Igd2hlbiBvbmUgb2YgYG5vZGVzYCBpcyBhIERvY3VtZW50RnJhZ21lbnQhXG4gICAgY29uc3QgY29ubmVjdGVkQmVmb3JlID0gLyoqIEB0eXBlIHshQXJyYXk8IU5vZGU+fSAqLyAobm9kZXMuZmlsdGVyKG5vZGUgPT4ge1xuICAgICAgLy8gRG9jdW1lbnRGcmFnbWVudHMgYXJlIG5vdCBjb25uZWN0ZWQgYW5kIHdpbGwgbm90IGJlIGFkZGVkIHRvIHRoZSBsaXN0LlxuICAgICAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBOb2RlICYmIFV0aWxpdGllcy5pc0Nvbm5lY3RlZChub2RlKTtcbiAgICB9KSk7XG5cbiAgICBidWlsdEluLmFmdGVyLmFwcGx5KHRoaXMsIG5vZGVzKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29ubmVjdGVkQmVmb3JlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpbnRlcm5hbHMuZGlzY29ubmVjdFRyZWUoY29ubmVjdGVkQmVmb3JlW2ldKTtcbiAgICB9XG5cbiAgICBpZiAoVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmNvbm5lY3RUcmVlKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLighTm9kZXxzdHJpbmcpfSBub2Rlc1xuICAgKi9cbiAgZGVzdGluYXRpb25bJ3JlcGxhY2VXaXRoJ10gPSBmdW5jdGlvbiguLi5ub2Rlcykge1xuICAgIC8vIFRPRE86IEZpeCB0aGlzIGZvciB3aGVuIG9uZSBvZiBgbm9kZXNgIGlzIGEgRG9jdW1lbnRGcmFnbWVudCFcbiAgICBjb25zdCBjb25uZWN0ZWRCZWZvcmUgPSAvKiogQHR5cGUgeyFBcnJheTwhTm9kZT59ICovIChub2Rlcy5maWx0ZXIobm9kZSA9PiB7XG4gICAgICAvLyBEb2N1bWVudEZyYWdtZW50cyBhcmUgbm90IGNvbm5lY3RlZCBhbmQgd2lsbCBub3QgYmUgYWRkZWQgdG8gdGhlIGxpc3QuXG4gICAgICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE5vZGUgJiYgVXRpbGl0aWVzLmlzQ29ubmVjdGVkKG5vZGUpO1xuICAgIH0pKTtcblxuICAgIGNvbnN0IHdhc0Nvbm5lY3RlZCA9IFV0aWxpdGllcy5pc0Nvbm5lY3RlZCh0aGlzKTtcblxuICAgIGJ1aWx0SW4ucmVwbGFjZVdpdGguYXBwbHkodGhpcywgbm9kZXMpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb25uZWN0ZWRCZWZvcmUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZShjb25uZWN0ZWRCZWZvcmVbaV0pO1xuICAgIH1cblxuICAgIGlmICh3YXNDb25uZWN0ZWQpIHtcbiAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZSh0aGlzKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcbiAgICAgICAgICBpbnRlcm5hbHMuY29ubmVjdFRyZWUobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZGVzdGluYXRpb25bJ3JlbW92ZSddID0gZnVuY3Rpb24oKSB7XG4gICAgY29uc3Qgd2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKHRoaXMpO1xuXG4gICAgYnVpbHRJbi5yZW1vdmUuY2FsbCh0aGlzKTtcblxuICAgIGlmICh3YXNDb25uZWN0ZWQpIHtcbiAgICAgIGludGVybmFscy5kaXNjb25uZWN0VHJlZSh0aGlzKTtcbiAgICB9XG4gIH07XG59O1xuIiwiaW1wb3J0IE5hdGl2ZSBmcm9tICcuL05hdGl2ZS5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudEludGVybmFscyBmcm9tICcuLi9DdXN0b21FbGVtZW50SW50ZXJuYWxzLmpzJztcbmltcG9ydCBDRVN0YXRlIGZyb20gJy4uL0N1c3RvbUVsZW1lbnRTdGF0ZS5qcyc7XG5pbXBvcnQgKiBhcyBVdGlsaXRpZXMgZnJvbSAnLi4vVXRpbGl0aWVzLmpzJztcblxuaW1wb3J0IFBhdGNoUGFyZW50Tm9kZSBmcm9tICcuL0ludGVyZmFjZS9QYXJlbnROb2RlLmpzJztcbmltcG9ydCBQYXRjaENoaWxkTm9kZSBmcm9tICcuL0ludGVyZmFjZS9DaGlsZE5vZGUuanMnO1xuXG4vKipcbiAqIEBwYXJhbSB7IUN1c3RvbUVsZW1lbnRJbnRlcm5hbHN9IGludGVybmFsc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihpbnRlcm5hbHMpIHtcbiAgaWYgKE5hdGl2ZS5FbGVtZW50X2F0dGFjaFNoYWRvdykge1xuICAgIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChFbGVtZW50LnByb3RvdHlwZSwgJ2F0dGFjaFNoYWRvdycsXG4gICAgICAvKipcbiAgICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAgICogQHBhcmFtIHshe21vZGU6IHN0cmluZ319IGluaXRcbiAgICAgICAqIEByZXR1cm4ge1NoYWRvd1Jvb3R9XG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uKGluaXQpIHtcbiAgICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IE5hdGl2ZS5FbGVtZW50X2F0dGFjaFNoYWRvdy5jYWxsKHRoaXMsIGluaXQpO1xuICAgICAgICB0aGlzLl9fQ0Vfc2hhZG93Um9vdCA9IHNoYWRvd1Jvb3Q7XG4gICAgICAgIHJldHVybiBzaGFkb3dSb290O1xuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS53YXJuKCdDdXN0b20gRWxlbWVudHM6IGBFbGVtZW50I2F0dGFjaFNoYWRvd2Agd2FzIG5vdCBwYXRjaGVkLicpO1xuICB9XG5cblxuICBmdW5jdGlvbiBwYXRjaF9pbm5lckhUTUwoZGVzdGluYXRpb24sIGJhc2VEZXNjcmlwdG9yKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGRlc3RpbmF0aW9uLCAnaW5uZXJIVE1MJywge1xuICAgICAgZW51bWVyYWJsZTogYmFzZURlc2NyaXB0b3IuZW51bWVyYWJsZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogYmFzZURlc2NyaXB0b3IuZ2V0LFxuICAgICAgc2V0OiAvKiogQHRoaXMge0VsZW1lbnR9ICovIGZ1bmN0aW9uKGh0bWxTdHJpbmcpIHtcbiAgICAgICAgY29uc3QgaXNDb25uZWN0ZWQgPSBVdGlsaXRpZXMuaXNDb25uZWN0ZWQodGhpcyk7XG5cbiAgICAgICAgLy8gTk9URTogSW4gSUUxMSwgd2hlbiB1c2luZyB0aGUgbmF0aXZlIGBpbm5lckhUTUxgIHNldHRlciwgYWxsIG5vZGVzXG4gICAgICAgIC8vIHRoYXQgd2VyZSBwcmV2aW91c2x5IGRlc2NlbmRhbnRzIG9mIHRoZSBjb250ZXh0IGVsZW1lbnQgaGF2ZSBhbGwgb2ZcbiAgICAgICAgLy8gdGhlaXIgY2hpbGRyZW4gcmVtb3ZlZCBhcyBwYXJ0IG9mIHRoZSBzZXQgLSB0aGUgZW50aXJlIHN1YnRyZWUgaXNcbiAgICAgICAgLy8gJ2Rpc2Fzc2VtYmxlZCcuIFRoaXMgd29yayBhcm91bmQgd2Fsa3MgdGhlIHN1YnRyZWUgKmJlZm9yZSogdXNpbmcgdGhlXG4gICAgICAgIC8vIG5hdGl2ZSBzZXR0ZXIuXG4gICAgICAgIC8qKiBAdHlwZSB7IUFycmF5PCFFbGVtZW50Pnx1bmRlZmluZWR9ICovXG4gICAgICAgIGxldCByZW1vdmVkRWxlbWVudHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgIHJlbW92ZWRFbGVtZW50cyA9IFtdO1xuICAgICAgICAgIFV0aWxpdGllcy53YWxrRGVlcERlc2NlbmRhbnRFbGVtZW50cyh0aGlzLCBlbGVtZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSB0aGlzKSB7XG4gICAgICAgICAgICAgIHJlbW92ZWRFbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgYmFzZURlc2NyaXB0b3Iuc2V0LmNhbGwodGhpcywgaHRtbFN0cmluZyk7XG5cbiAgICAgICAgaWYgKHJlbW92ZWRFbGVtZW50cykge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVtb3ZlZEVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gcmVtb3ZlZEVsZW1lbnRzW2ldO1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQuX19DRV9zdGF0ZSA9PT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RlZENhbGxiYWNrKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE9ubHkgY3JlYXRlIGN1c3RvbSBlbGVtZW50cyBpZiB0aGlzIGVsZW1lbnQncyBvd25lciBkb2N1bWVudCBpc1xuICAgICAgICAvLyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5LlxuICAgICAgICBpZiAoIXRoaXMub3duZXJEb2N1bWVudC5fX0NFX2hhc1JlZ2lzdHJ5KSB7XG4gICAgICAgICAgaW50ZXJuYWxzLnBhdGNoVHJlZSh0aGlzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnRlcm5hbHMucGF0Y2hBbmRVcGdyYWRlVHJlZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaHRtbFN0cmluZztcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBpZiAoTmF0aXZlLkVsZW1lbnRfaW5uZXJIVE1MICYmIE5hdGl2ZS5FbGVtZW50X2lubmVySFRNTC5nZXQpIHtcbiAgICBwYXRjaF9pbm5lckhUTUwoRWxlbWVudC5wcm90b3R5cGUsIE5hdGl2ZS5FbGVtZW50X2lubmVySFRNTCk7XG4gIH0gZWxzZSBpZiAoTmF0aXZlLkhUTUxFbGVtZW50X2lubmVySFRNTCAmJiBOYXRpdmUuSFRNTEVsZW1lbnRfaW5uZXJIVE1MLmdldCkge1xuICAgIHBhdGNoX2lubmVySFRNTChIVE1MRWxlbWVudC5wcm90b3R5cGUsIE5hdGl2ZS5IVE1MRWxlbWVudF9pbm5lckhUTUwpO1xuICB9IGVsc2Uge1xuXG4gICAgLyoqIEB0eXBlIHtIVE1MRGl2RWxlbWVudH0gKi9cbiAgICBjb25zdCByYXdEaXYgPSBOYXRpdmUuRG9jdW1lbnRfY3JlYXRlRWxlbWVudC5jYWxsKGRvY3VtZW50LCAnZGl2Jyk7XG5cbiAgICBpbnRlcm5hbHMuYWRkUGF0Y2goZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcGF0Y2hfaW5uZXJIVE1MKGVsZW1lbnQsIHtcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAvLyBJbXBsZW1lbnRzIGdldHRpbmcgYGlubmVySFRNTGAgYnkgcGVyZm9ybWluZyBhbiB1bnBhdGNoZWQgYGNsb25lTm9kZWBcbiAgICAgICAgLy8gb2YgdGhlIGVsZW1lbnQgYW5kIHJldHVybmluZyB0aGUgcmVzdWx0aW5nIGVsZW1lbnQncyBgaW5uZXJIVE1MYC5cbiAgICAgICAgLy8gVE9ETzogSXMgdGhpcyB0b28gZXhwZW5zaXZlP1xuICAgICAgICBnZXQ6IC8qKiBAdGhpcyB7RWxlbWVudH0gKi8gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIE5hdGl2ZS5Ob2RlX2Nsb25lTm9kZS5jYWxsKHRoaXMsIHRydWUpLmlubmVySFRNTDtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gSW1wbGVtZW50cyBzZXR0aW5nIGBpbm5lckhUTUxgIGJ5IGNyZWF0aW5nIGFuIHVucGF0Y2hlZCBlbGVtZW50LFxuICAgICAgICAvLyBzZXR0aW5nIGBpbm5lckhUTUxgIG9mIHRoYXQgZWxlbWVudCBhbmQgcmVwbGFjaW5nIHRoZSB0YXJnZXRcbiAgICAgICAgLy8gZWxlbWVudCdzIGNoaWxkcmVuIHdpdGggdGhvc2Ugb2YgdGhlIHVucGF0Y2hlZCBlbGVtZW50LlxuICAgICAgICBzZXQ6IC8qKiBAdGhpcyB7RWxlbWVudH0gKi8gZnVuY3Rpb24oYXNzaWduZWRWYWx1ZSkge1xuICAgICAgICAgIC8vIE5PVEU6IHJlLXJvdXRlIHRvIGBjb250ZW50YCBmb3IgYHRlbXBsYXRlYCBlbGVtZW50cy5cbiAgICAgICAgICAvLyBXZSBuZWVkIHRvIGRvIHRoaXMgYmVjYXVzZSBgdGVtcGxhdGUuYXBwZW5kQ2hpbGRgIGRvZXMgbm90XG4gICAgICAgICAgLy8gcm91dGUgaW50byBgdGVtcGxhdGUuY29udGVudGAuXG4gICAgICAgICAgLyoqIEB0eXBlIHshTm9kZX0gKi9cbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5sb2NhbE5hbWUgPT09ICd0ZW1wbGF0ZScgPyAoLyoqIEB0eXBlIHshSFRNTFRlbXBsYXRlRWxlbWVudH0gKi8gKHRoaXMpKS5jb250ZW50IDogdGhpcztcbiAgICAgICAgICByYXdEaXYuaW5uZXJIVE1MID0gYXNzaWduZWRWYWx1ZTtcblxuICAgICAgICAgIHdoaWxlIChjb250ZW50LmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgTmF0aXZlLk5vZGVfcmVtb3ZlQ2hpbGQuY2FsbChjb250ZW50LCBjb250ZW50LmNoaWxkTm9kZXNbMF0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3aGlsZSAocmF3RGl2LmNoaWxkTm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgTmF0aXZlLk5vZGVfYXBwZW5kQ2hpbGQuY2FsbChjb250ZW50LCByYXdEaXYuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuXG4gIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChFbGVtZW50LnByb3RvdHlwZSwgJ3NldEF0dHJpYnV0ZScsXG4gICAgLyoqXG4gICAgICogQHRoaXMge0VsZW1lbnR9XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3VmFsdWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbihuYW1lLCBuZXdWYWx1ZSkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBub24tY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgaWYgKHRoaXMuX19DRV9zdGF0ZSAhPT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgcmV0dXJuIE5hdGl2ZS5FbGVtZW50X3NldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUsIG5ld1ZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSBOYXRpdmUuRWxlbWVudF9nZXRBdHRyaWJ1dGUuY2FsbCh0aGlzLCBuYW1lKTtcbiAgICAgIE5hdGl2ZS5FbGVtZW50X3NldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUsIG5ld1ZhbHVlKTtcbiAgICAgIG5ld1ZhbHVlID0gTmF0aXZlLkVsZW1lbnRfZ2V0QXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICBpbnRlcm5hbHMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKHRoaXMsIG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbnVsbCk7XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKEVsZW1lbnQucHJvdG90eXBlLCAnc2V0QXR0cmlidXRlTlMnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAqIEBwYXJhbSB7P3N0cmluZ30gbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmV3VmFsdWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbihuYW1lc3BhY2UsIG5hbWUsIG5ld1ZhbHVlKSB7XG4gICAgICAvLyBGYXN0IHBhdGggZm9yIG5vbi1jdXN0b20gZWxlbWVudHMuXG4gICAgICBpZiAodGhpcy5fX0NFX3N0YXRlICE9PSBDRVN0YXRlLmN1c3RvbSkge1xuICAgICAgICByZXR1cm4gTmF0aXZlLkVsZW1lbnRfc2V0QXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUsIG5ld1ZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb2xkVmFsdWUgPSBOYXRpdmUuRWxlbWVudF9nZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSk7XG4gICAgICBOYXRpdmUuRWxlbWVudF9zZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSwgbmV3VmFsdWUpO1xuICAgICAgbmV3VmFsdWUgPSBOYXRpdmUuRWxlbWVudF9nZXRBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSk7XG4gICAgICBpbnRlcm5hbHMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKHRoaXMsIG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbmFtZXNwYWNlKTtcbiAgICB9KTtcblxuICBVdGlsaXRpZXMuc2V0UHJvcGVydHlVbmNoZWNrZWQoRWxlbWVudC5wcm90b3R5cGUsICdyZW1vdmVBdHRyaWJ1dGUnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICovXG4gICAgZnVuY3Rpb24obmFtZSkge1xuICAgICAgLy8gRmFzdCBwYXRoIGZvciBub24tY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgaWYgKHRoaXMuX19DRV9zdGF0ZSAhPT0gQ0VTdGF0ZS5jdXN0b20pIHtcbiAgICAgICAgcmV0dXJuIE5hdGl2ZS5FbGVtZW50X3JlbW92ZUF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvbGRWYWx1ZSA9IE5hdGl2ZS5FbGVtZW50X2dldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIG5hbWUpO1xuICAgICAgTmF0aXZlLkVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICBpZiAob2xkVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgaW50ZXJuYWxzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayh0aGlzLCBuYW1lLCBvbGRWYWx1ZSwgbnVsbCwgbnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgVXRpbGl0aWVzLnNldFByb3BlcnR5VW5jaGVja2VkKEVsZW1lbnQucHJvdG90eXBlLCAncmVtb3ZlQXR0cmlidXRlTlMnLFxuICAgIC8qKlxuICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAqIEBwYXJhbSB7P3N0cmluZ30gbmFtZXNwYWNlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbihuYW1lc3BhY2UsIG5hbWUpIHtcbiAgICAgIC8vIEZhc3QgcGF0aCBmb3Igbm9uLWN1c3RvbSBlbGVtZW50cy5cbiAgICAgIGlmICh0aGlzLl9fQ0Vfc3RhdGUgIT09IENFU3RhdGUuY3VzdG9tKSB7XG4gICAgICAgIHJldHVybiBOYXRpdmUuRWxlbWVudF9yZW1vdmVBdHRyaWJ1dGVOUy5jYWxsKHRoaXMsIG5hbWVzcGFjZSwgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9sZFZhbHVlID0gTmF0aXZlLkVsZW1lbnRfZ2V0QXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUpO1xuICAgICAgTmF0aXZlLkVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUpO1xuICAgICAgLy8gSW4gb2xkZXIgYnJvd3NlcnMsIGBFbGVtZW50I2dldEF0dHJpYnV0ZU5TYCBtYXkgcmV0dXJuIHRoZSBlbXB0eSBzdHJpbmdcbiAgICAgIC8vIGluc3RlYWQgb2YgbnVsbCBpZiB0aGUgYXR0cmlidXRlIGRvZXMgbm90IGV4aXN0LiBGb3IgZGV0YWlscywgc2VlO1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnQvZ2V0QXR0cmlidXRlTlMjTm90ZXNcbiAgICAgIGNvbnN0IG5ld1ZhbHVlID0gTmF0aXZlLkVsZW1lbnRfZ2V0QXR0cmlidXRlTlMuY2FsbCh0aGlzLCBuYW1lc3BhY2UsIG5hbWUpO1xuICAgICAgaWYgKG9sZFZhbHVlICE9PSBuZXdWYWx1ZSkge1xuICAgICAgICBpbnRlcm5hbHMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKHRoaXMsIG5hbWUsIG9sZFZhbHVlLCBuZXdWYWx1ZSwgbmFtZXNwYWNlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuXG4gIGZ1bmN0aW9uIHBhdGNoX2luc2VydEFkamFjZW50RWxlbWVudChkZXN0aW5hdGlvbiwgYmFzZU1ldGhvZCkge1xuICAgIFV0aWxpdGllcy5zZXRQcm9wZXJ0eVVuY2hlY2tlZChkZXN0aW5hdGlvbiwgJ2luc2VydEFkamFjZW50RWxlbWVudCcsXG4gICAgICAvKipcbiAgICAgICAqIEB0aGlzIHtFbGVtZW50fVxuICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHdoZXJlXG4gICAgICAgKiBAcGFyYW0geyFFbGVtZW50fSBlbGVtZW50XG4gICAgICAgKiBAcmV0dXJuIHs/RWxlbWVudH1cbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24od2hlcmUsIGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3Qgd2FzQ29ubmVjdGVkID0gVXRpbGl0aWVzLmlzQ29ubmVjdGVkKGVsZW1lbnQpO1xuICAgICAgICBjb25zdCBpbnNlcnRlZEVsZW1lbnQgPSAvKiogQHR5cGUgeyFFbGVtZW50fSAqL1xuICAgICAgICAgIChiYXNlTWV0aG9kLmNhbGwodGhpcywgd2hlcmUsIGVsZW1lbnQpKTtcblxuICAgICAgICBpZiAod2FzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmRpc2Nvbm5lY3RUcmVlKGVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFV0aWxpdGllcy5pc0Nvbm5lY3RlZChpbnNlcnRlZEVsZW1lbnQpKSB7XG4gICAgICAgICAgaW50ZXJuYWxzLmNvbm5lY3RUcmVlKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnNlcnRlZEVsZW1lbnQ7XG4gICAgICB9KTtcbiAgfVxuXG4gIGlmIChOYXRpdmUuSFRNTEVsZW1lbnRfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KSB7XG4gICAgcGF0Y2hfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KEhUTUxFbGVtZW50LnByb3RvdHlwZSwgTmF0aXZlLkhUTUxFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudCk7XG4gIH0gZWxzZSBpZiAoTmF0aXZlLkVsZW1lbnRfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KSB7XG4gICAgcGF0Y2hfaW5zZXJ0QWRqYWNlbnRFbGVtZW50KEVsZW1lbnQucHJvdG90eXBlLCBOYXRpdmUuRWxlbWVudF9pbnNlcnRBZGphY2VudEVsZW1lbnQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUud2FybignQ3VzdG9tIEVsZW1lbnRzOiBgRWxlbWVudCNpbnNlcnRBZGphY2VudEVsZW1lbnRgIHdhcyBub3QgcGF0Y2hlZC4nKTtcbiAgfVxuXG5cbiAgUGF0Y2hQYXJlbnROb2RlKGludGVybmFscywgRWxlbWVudC5wcm90b3R5cGUsIHtcbiAgICBwcmVwZW5kOiBOYXRpdmUuRWxlbWVudF9wcmVwZW5kLFxuICAgIGFwcGVuZDogTmF0aXZlLkVsZW1lbnRfYXBwZW5kLFxuICB9KTtcblxuICBQYXRjaENoaWxkTm9kZShpbnRlcm5hbHMsIEVsZW1lbnQucHJvdG90eXBlLCB7XG4gICAgYmVmb3JlOiBOYXRpdmUuRWxlbWVudF9iZWZvcmUsXG4gICAgYWZ0ZXI6IE5hdGl2ZS5FbGVtZW50X2FmdGVyLFxuICAgIHJlcGxhY2VXaXRoOiBOYXRpdmUuRWxlbWVudF9yZXBsYWNlV2l0aCxcbiAgICByZW1vdmU6IE5hdGl2ZS5FbGVtZW50X3JlbW92ZSxcbiAgfSk7XG59O1xuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE2IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG5cbmltcG9ydCBDdXN0b21FbGVtZW50SW50ZXJuYWxzIGZyb20gJy4vQ3VzdG9tRWxlbWVudEludGVybmFscy5qcyc7XG5pbXBvcnQgQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5IGZyb20gJy4vQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LmpzJztcblxuaW1wb3J0IFBhdGNoSFRNTEVsZW1lbnQgZnJvbSAnLi9QYXRjaC9IVE1MRWxlbWVudC5qcyc7XG5pbXBvcnQgUGF0Y2hEb2N1bWVudCBmcm9tICcuL1BhdGNoL0RvY3VtZW50LmpzJztcbmltcG9ydCBQYXRjaE5vZGUgZnJvbSAnLi9QYXRjaC9Ob2RlLmpzJztcbmltcG9ydCBQYXRjaEVsZW1lbnQgZnJvbSAnLi9QYXRjaC9FbGVtZW50LmpzJztcblxuY29uc3QgcHJpb3JDdXN0b21FbGVtZW50cyA9IHdpbmRvd1snY3VzdG9tRWxlbWVudHMnXTtcblxuaWYgKCFwcmlvckN1c3RvbUVsZW1lbnRzIHx8XG4gICAgIHByaW9yQ3VzdG9tRWxlbWVudHNbJ2ZvcmNlUG9seWZpbGwnXSB8fFxuICAgICAodHlwZW9mIHByaW9yQ3VzdG9tRWxlbWVudHNbJ2RlZmluZSddICE9ICdmdW5jdGlvbicpIHx8XG4gICAgICh0eXBlb2YgcHJpb3JDdXN0b21FbGVtZW50c1snZ2V0J10gIT0gJ2Z1bmN0aW9uJykpIHtcbiAgLyoqIEB0eXBlIHshQ3VzdG9tRWxlbWVudEludGVybmFsc30gKi9cbiAgY29uc3QgaW50ZXJuYWxzID0gbmV3IEN1c3RvbUVsZW1lbnRJbnRlcm5hbHMoKTtcblxuICBQYXRjaEhUTUxFbGVtZW50KGludGVybmFscyk7XG4gIFBhdGNoRG9jdW1lbnQoaW50ZXJuYWxzKTtcbiAgUGF0Y2hOb2RlKGludGVybmFscyk7XG4gIFBhdGNoRWxlbWVudChpbnRlcm5hbHMpO1xuXG4gIC8vIFRoZSBtYWluIGRvY3VtZW50IGlzIGFsd2F5cyBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5LlxuICBkb2N1bWVudC5fX0NFX2hhc1JlZ2lzdHJ5ID0gdHJ1ZTtcblxuICAvKiogQHR5cGUgeyFDdXN0b21FbGVtZW50UmVnaXN0cnl9ICovXG4gIGNvbnN0IGN1c3RvbUVsZW1lbnRzID0gbmV3IEN1c3RvbUVsZW1lbnRSZWdpc3RyeShpbnRlcm5hbHMpO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdjdXN0b21FbGVtZW50cycsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICB2YWx1ZTogY3VzdG9tRWxlbWVudHMsXG4gIH0pO1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IChjKSAyMDE0IFRoZSBQb2x5bWVyIFByb2plY3QgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFRoaXMgY29kZSBtYXkgb25seSBiZSB1c2VkIHVuZGVyIHRoZSBCU0Qgc3R5bGUgbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vcG9seW1lci5naXRodWIuaW8vTElDRU5TRS50eHRcbiAqIFRoZSBjb21wbGV0ZSBzZXQgb2YgYXV0aG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0FVVEhPUlMudHh0XG4gKiBUaGUgY29tcGxldGUgc2V0IG9mIGNvbnRyaWJ1dG9ycyBtYXkgYmUgZm91bmQgYXQgaHR0cDovL3BvbHltZXIuZ2l0aHViLmlvL0NPTlRSSUJVVE9SUy50eHRcbiAqIENvZGUgZGlzdHJpYnV0ZWQgYnkgR29vZ2xlIGFzIHBhcnQgb2YgdGhlIHBvbHltZXIgcHJvamVjdCBpcyBhbHNvXG4gKiBzdWJqZWN0IHRvIGFuIGFkZGl0aW9uYWwgSVAgcmlnaHRzIGdyYW50IGZvdW5kIGF0IGh0dHA6Ly9wb2x5bWVyLmdpdGh1Yi5pby9QQVRFTlRTLnR4dFxuICovXG4vLyBAdmVyc2lvbiAwLjcuMjJcblxuKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBpZiAoZ2xvYmFsLkpzTXV0YXRpb25PYnNlcnZlcikge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgcmVnaXN0cmF0aW9uc1RhYmxlID0gbmV3IFdlYWtNYXAoKTtcbiAgdmFyIHNldEltbWVkaWF0ZTtcbiAgaWYgKC9UcmlkZW50fEVkZ2UvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgICBzZXRJbW1lZGlhdGUgPSBzZXRUaW1lb3V0O1xuICB9IGVsc2UgaWYgKHdpbmRvdy5zZXRJbW1lZGlhdGUpIHtcbiAgICBzZXRJbW1lZGlhdGUgPSB3aW5kb3cuc2V0SW1tZWRpYXRlO1xuICB9IGVsc2Uge1xuICAgIHZhciBzZXRJbW1lZGlhdGVRdWV1ZSA9IFtdO1xuICAgIHZhciBzZW50aW5lbCA9IFN0cmluZyhNYXRoLnJhbmRvbSgpKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGUuZGF0YSA9PT0gc2VudGluZWwpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gc2V0SW1tZWRpYXRlUXVldWU7XG4gICAgICAgIHNldEltbWVkaWF0ZVF1ZXVlID0gW107XG4gICAgICAgIHF1ZXVlLmZvckVhY2goZnVuY3Rpb24oZnVuYykge1xuICAgICAgICAgIGZ1bmMoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oZnVuYykge1xuICAgICAgc2V0SW1tZWRpYXRlUXVldWUucHVzaChmdW5jKTtcbiAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZShzZW50aW5lbCwgXCIqXCIpO1xuICAgIH07XG4gIH1cbiAgdmFyIGlzU2NoZWR1bGVkID0gZmFsc2U7XG4gIHZhciBzY2hlZHVsZWRPYnNlcnZlcnMgPSBbXTtcbiAgZnVuY3Rpb24gc2NoZWR1bGVDYWxsYmFjayhvYnNlcnZlcikge1xuICAgIHNjaGVkdWxlZE9ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgICBpZiAoIWlzU2NoZWR1bGVkKSB7XG4gICAgICBpc1NjaGVkdWxlZCA9IHRydWU7XG4gICAgICBzZXRJbW1lZGlhdGUoZGlzcGF0Y2hDYWxsYmFja3MpO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiB3cmFwSWZOZWVkZWQobm9kZSkge1xuICAgIHJldHVybiB3aW5kb3cuU2hhZG93RE9NUG9seWZpbGwgJiYgd2luZG93LlNoYWRvd0RPTVBvbHlmaWxsLndyYXBJZk5lZWRlZChub2RlKSB8fCBub2RlO1xuICB9XG4gIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2tzKCkge1xuICAgIGlzU2NoZWR1bGVkID0gZmFsc2U7XG4gICAgdmFyIG9ic2VydmVycyA9IHNjaGVkdWxlZE9ic2VydmVycztcbiAgICBzY2hlZHVsZWRPYnNlcnZlcnMgPSBbXTtcbiAgICBvYnNlcnZlcnMuc29ydChmdW5jdGlvbihvMSwgbzIpIHtcbiAgICAgIHJldHVybiBvMS51aWRfIC0gbzIudWlkXztcbiAgICB9KTtcbiAgICB2YXIgYW55Tm9uRW1wdHkgPSBmYWxzZTtcbiAgICBvYnNlcnZlcnMuZm9yRWFjaChmdW5jdGlvbihvYnNlcnZlcikge1xuICAgICAgdmFyIHF1ZXVlID0gb2JzZXJ2ZXIudGFrZVJlY29yZHMoKTtcbiAgICAgIHJlbW92ZVRyYW5zaWVudE9ic2VydmVyc0ZvcihvYnNlcnZlcik7XG4gICAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIG9ic2VydmVyLmNhbGxiYWNrXyhxdWV1ZSwgb2JzZXJ2ZXIpO1xuICAgICAgICBhbnlOb25FbXB0eSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKGFueU5vbkVtcHR5KSBkaXNwYXRjaENhbGxiYWNrcygpO1xuICB9XG4gIGZ1bmN0aW9uIHJlbW92ZVRyYW5zaWVudE9ic2VydmVyc0ZvcihvYnNlcnZlcikge1xuICAgIG9ic2VydmVyLm5vZGVzXy5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciByZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9uc1RhYmxlLmdldChub2RlKTtcbiAgICAgIGlmICghcmVnaXN0cmF0aW9ucykgcmV0dXJuO1xuICAgICAgcmVnaXN0cmF0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKHJlZ2lzdHJhdGlvbikge1xuICAgICAgICBpZiAocmVnaXN0cmF0aW9uLm9ic2VydmVyID09PSBvYnNlcnZlcikgcmVnaXN0cmF0aW9uLnJlbW92ZVRyYW5zaWVudE9ic2VydmVycygpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgZnVuY3Rpb24gZm9yRWFjaEFuY2VzdG9yQW5kT2JzZXJ2ZXJFbnF1ZXVlUmVjb3JkKHRhcmdldCwgY2FsbGJhY2spIHtcbiAgICBmb3IgKHZhciBub2RlID0gdGFyZ2V0OyBub2RlOyBub2RlID0gbm9kZS5wYXJlbnROb2RlKSB7XG4gICAgICB2YXIgcmVnaXN0cmF0aW9ucyA9IHJlZ2lzdHJhdGlvbnNUYWJsZS5nZXQobm9kZSk7XG4gICAgICBpZiAocmVnaXN0cmF0aW9ucykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHJlZ2lzdHJhdGlvbnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICB2YXIgcmVnaXN0cmF0aW9uID0gcmVnaXN0cmF0aW9uc1tqXTtcbiAgICAgICAgICB2YXIgb3B0aW9ucyA9IHJlZ2lzdHJhdGlvbi5vcHRpb25zO1xuICAgICAgICAgIGlmIChub2RlICE9PSB0YXJnZXQgJiYgIW9wdGlvbnMuc3VidHJlZSkgY29udGludWU7XG4gICAgICAgICAgdmFyIHJlY29yZCA9IGNhbGxiYWNrKG9wdGlvbnMpO1xuICAgICAgICAgIGlmIChyZWNvcmQpIHJlZ2lzdHJhdGlvbi5lbnF1ZXVlKHJlY29yZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIHVpZENvdW50ZXIgPSAwO1xuICBmdW5jdGlvbiBKc011dGF0aW9uT2JzZXJ2ZXIoY2FsbGJhY2spIHtcbiAgICB0aGlzLmNhbGxiYWNrXyA9IGNhbGxiYWNrO1xuICAgIHRoaXMubm9kZXNfID0gW107XG4gICAgdGhpcy5yZWNvcmRzXyA9IFtdO1xuICAgIHRoaXMudWlkXyA9ICsrdWlkQ291bnRlcjtcbiAgfVxuICBKc011dGF0aW9uT2JzZXJ2ZXIucHJvdG90eXBlID0ge1xuICAgIG9ic2VydmU6IGZ1bmN0aW9uKHRhcmdldCwgb3B0aW9ucykge1xuICAgICAgdGFyZ2V0ID0gd3JhcElmTmVlZGVkKHRhcmdldCk7XG4gICAgICBpZiAoIW9wdGlvbnMuY2hpbGRMaXN0ICYmICFvcHRpb25zLmF0dHJpYnV0ZXMgJiYgIW9wdGlvbnMuY2hhcmFjdGVyRGF0YSB8fCBvcHRpb25zLmF0dHJpYnV0ZU9sZFZhbHVlICYmICFvcHRpb25zLmF0dHJpYnV0ZXMgfHwgb3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIgJiYgb3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIubGVuZ3RoICYmICFvcHRpb25zLmF0dHJpYnV0ZXMgfHwgb3B0aW9ucy5jaGFyYWN0ZXJEYXRhT2xkVmFsdWUgJiYgIW9wdGlvbnMuY2hhcmFjdGVyRGF0YSkge1xuICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIHZhciByZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9uc1RhYmxlLmdldCh0YXJnZXQpO1xuICAgICAgaWYgKCFyZWdpc3RyYXRpb25zKSByZWdpc3RyYXRpb25zVGFibGUuc2V0KHRhcmdldCwgcmVnaXN0cmF0aW9ucyA9IFtdKTtcbiAgICAgIHZhciByZWdpc3RyYXRpb247XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lzdHJhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbnNbaV0ub2JzZXJ2ZXIgPT09IHRoaXMpIHtcbiAgICAgICAgICByZWdpc3RyYXRpb24gPSByZWdpc3RyYXRpb25zW2ldO1xuICAgICAgICAgIHJlZ2lzdHJhdGlvbi5yZW1vdmVMaXN0ZW5lcnMoKTtcbiAgICAgICAgICByZWdpc3RyYXRpb24ub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghcmVnaXN0cmF0aW9uKSB7XG4gICAgICAgIHJlZ2lzdHJhdGlvbiA9IG5ldyBSZWdpc3RyYXRpb24odGhpcywgdGFyZ2V0LCBvcHRpb25zKTtcbiAgICAgICAgcmVnaXN0cmF0aW9ucy5wdXNoKHJlZ2lzdHJhdGlvbik7XG4gICAgICAgIHRoaXMubm9kZXNfLnB1c2godGFyZ2V0KTtcbiAgICAgIH1cbiAgICAgIHJlZ2lzdHJhdGlvbi5hZGRMaXN0ZW5lcnMoKTtcbiAgICB9LFxuICAgIGRpc2Nvbm5lY3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5ub2Rlc18uZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHZhciByZWdpc3RyYXRpb25zID0gcmVnaXN0cmF0aW9uc1RhYmxlLmdldChub2RlKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWdpc3RyYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHJlZ2lzdHJhdGlvbiA9IHJlZ2lzdHJhdGlvbnNbaV07XG4gICAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5vYnNlcnZlciA9PT0gdGhpcykge1xuICAgICAgICAgICAgcmVnaXN0cmF0aW9uLnJlbW92ZUxpc3RlbmVycygpO1xuICAgICAgICAgICAgcmVnaXN0cmF0aW9ucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMpO1xuICAgICAgdGhpcy5yZWNvcmRzXyA9IFtdO1xuICAgIH0sXG4gICAgdGFrZVJlY29yZHM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNvcHlPZlJlY29yZHMgPSB0aGlzLnJlY29yZHNfO1xuICAgICAgdGhpcy5yZWNvcmRzXyA9IFtdO1xuICAgICAgcmV0dXJuIGNvcHlPZlJlY29yZHM7XG4gICAgfVxuICB9O1xuICBmdW5jdGlvbiBNdXRhdGlvblJlY29yZCh0eXBlLCB0YXJnZXQpIHtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIHRoaXMuYWRkZWROb2RlcyA9IFtdO1xuICAgIHRoaXMucmVtb3ZlZE5vZGVzID0gW107XG4gICAgdGhpcy5wcmV2aW91c1NpYmxpbmcgPSBudWxsO1xuICAgIHRoaXMubmV4dFNpYmxpbmcgPSBudWxsO1xuICAgIHRoaXMuYXR0cmlidXRlTmFtZSA9IG51bGw7XG4gICAgdGhpcy5hdHRyaWJ1dGVOYW1lc3BhY2UgPSBudWxsO1xuICAgIHRoaXMub2xkVmFsdWUgPSBudWxsO1xuICB9XG4gIGZ1bmN0aW9uIGNvcHlNdXRhdGlvblJlY29yZChvcmlnaW5hbCkge1xuICAgIHZhciByZWNvcmQgPSBuZXcgTXV0YXRpb25SZWNvcmQob3JpZ2luYWwudHlwZSwgb3JpZ2luYWwudGFyZ2V0KTtcbiAgICByZWNvcmQuYWRkZWROb2RlcyA9IG9yaWdpbmFsLmFkZGVkTm9kZXMuc2xpY2UoKTtcbiAgICByZWNvcmQucmVtb3ZlZE5vZGVzID0gb3JpZ2luYWwucmVtb3ZlZE5vZGVzLnNsaWNlKCk7XG4gICAgcmVjb3JkLnByZXZpb3VzU2libGluZyA9IG9yaWdpbmFsLnByZXZpb3VzU2libGluZztcbiAgICByZWNvcmQubmV4dFNpYmxpbmcgPSBvcmlnaW5hbC5uZXh0U2libGluZztcbiAgICByZWNvcmQuYXR0cmlidXRlTmFtZSA9IG9yaWdpbmFsLmF0dHJpYnV0ZU5hbWU7XG4gICAgcmVjb3JkLmF0dHJpYnV0ZU5hbWVzcGFjZSA9IG9yaWdpbmFsLmF0dHJpYnV0ZU5hbWVzcGFjZTtcbiAgICByZWNvcmQub2xkVmFsdWUgPSBvcmlnaW5hbC5vbGRWYWx1ZTtcbiAgICByZXR1cm4gcmVjb3JkO1xuICB9XG4gIHZhciBjdXJyZW50UmVjb3JkLCByZWNvcmRXaXRoT2xkVmFsdWU7XG4gIGZ1bmN0aW9uIGdldFJlY29yZCh0eXBlLCB0YXJnZXQpIHtcbiAgICByZXR1cm4gY3VycmVudFJlY29yZCA9IG5ldyBNdXRhdGlvblJlY29yZCh0eXBlLCB0YXJnZXQpO1xuICB9XG4gIGZ1bmN0aW9uIGdldFJlY29yZFdpdGhPbGRWYWx1ZShvbGRWYWx1ZSkge1xuICAgIGlmIChyZWNvcmRXaXRoT2xkVmFsdWUpIHJldHVybiByZWNvcmRXaXRoT2xkVmFsdWU7XG4gICAgcmVjb3JkV2l0aE9sZFZhbHVlID0gY29weU11dGF0aW9uUmVjb3JkKGN1cnJlbnRSZWNvcmQpO1xuICAgIHJlY29yZFdpdGhPbGRWYWx1ZS5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgIHJldHVybiByZWNvcmRXaXRoT2xkVmFsdWU7XG4gIH1cbiAgZnVuY3Rpb24gY2xlYXJSZWNvcmRzKCkge1xuICAgIGN1cnJlbnRSZWNvcmQgPSByZWNvcmRXaXRoT2xkVmFsdWUgPSB1bmRlZmluZWQ7XG4gIH1cbiAgZnVuY3Rpb24gcmVjb3JkUmVwcmVzZW50c0N1cnJlbnRNdXRhdGlvbihyZWNvcmQpIHtcbiAgICByZXR1cm4gcmVjb3JkID09PSByZWNvcmRXaXRoT2xkVmFsdWUgfHwgcmVjb3JkID09PSBjdXJyZW50UmVjb3JkO1xuICB9XG4gIGZ1bmN0aW9uIHNlbGVjdFJlY29yZChsYXN0UmVjb3JkLCBuZXdSZWNvcmQpIHtcbiAgICBpZiAobGFzdFJlY29yZCA9PT0gbmV3UmVjb3JkKSByZXR1cm4gbGFzdFJlY29yZDtcbiAgICBpZiAocmVjb3JkV2l0aE9sZFZhbHVlICYmIHJlY29yZFJlcHJlc2VudHNDdXJyZW50TXV0YXRpb24obGFzdFJlY29yZCkpIHJldHVybiByZWNvcmRXaXRoT2xkVmFsdWU7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgZnVuY3Rpb24gUmVnaXN0cmF0aW9uKG9ic2VydmVyLCB0YXJnZXQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLm9ic2VydmVyID0gb2JzZXJ2ZXI7XG4gICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnRyYW5zaWVudE9ic2VydmVkTm9kZXMgPSBbXTtcbiAgfVxuICBSZWdpc3RyYXRpb24ucHJvdG90eXBlID0ge1xuICAgIGVucXVldWU6IGZ1bmN0aW9uKHJlY29yZCkge1xuICAgICAgdmFyIHJlY29yZHMgPSB0aGlzLm9ic2VydmVyLnJlY29yZHNfO1xuICAgICAgdmFyIGxlbmd0aCA9IHJlY29yZHMubGVuZ3RoO1xuICAgICAgaWYgKHJlY29yZHMubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgbGFzdFJlY29yZCA9IHJlY29yZHNbbGVuZ3RoIC0gMV07XG4gICAgICAgIHZhciByZWNvcmRUb1JlcGxhY2VMYXN0ID0gc2VsZWN0UmVjb3JkKGxhc3RSZWNvcmQsIHJlY29yZCk7XG4gICAgICAgIGlmIChyZWNvcmRUb1JlcGxhY2VMYXN0KSB7XG4gICAgICAgICAgcmVjb3Jkc1tsZW5ndGggLSAxXSA9IHJlY29yZFRvUmVwbGFjZUxhc3Q7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzY2hlZHVsZUNhbGxiYWNrKHRoaXMub2JzZXJ2ZXIpO1xuICAgICAgfVxuICAgICAgcmVjb3Jkc1tsZW5ndGhdID0gcmVjb3JkO1xuICAgIH0sXG4gICAgYWRkTGlzdGVuZXJzOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYWRkTGlzdGVuZXJzXyh0aGlzLnRhcmdldCk7XG4gICAgfSxcbiAgICBhZGRMaXN0ZW5lcnNfOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgIGlmIChvcHRpb25zLmF0dHJpYnV0ZXMpIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUF0dHJNb2RpZmllZFwiLCB0aGlzLCB0cnVlKTtcbiAgICAgIGlmIChvcHRpb25zLmNoYXJhY3RlckRhdGEpIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNoYXJhY3RlckRhdGFNb2RpZmllZFwiLCB0aGlzLCB0cnVlKTtcbiAgICAgIGlmIChvcHRpb25zLmNoaWxkTGlzdCkgbm9kZS5hZGRFdmVudExpc3RlbmVyKFwiRE9NTm9kZUluc2VydGVkXCIsIHRoaXMsIHRydWUpO1xuICAgICAgaWYgKG9wdGlvbnMuY2hpbGRMaXN0IHx8IG9wdGlvbnMuc3VidHJlZSkgbm9kZS5hZGRFdmVudExpc3RlbmVyKFwiRE9NTm9kZVJlbW92ZWRcIiwgdGhpcywgdHJ1ZSk7XG4gICAgfSxcbiAgICByZW1vdmVMaXN0ZW5lcnM6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcnNfKHRoaXMudGFyZ2V0KTtcbiAgICB9LFxuICAgIHJlbW92ZUxpc3RlbmVyc186IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuICAgICAgaWYgKG9wdGlvbnMuYXR0cmlidXRlcykgbm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiRE9NQXR0ck1vZGlmaWVkXCIsIHRoaXMsIHRydWUpO1xuICAgICAgaWYgKG9wdGlvbnMuY2hhcmFjdGVyRGF0YSkgbm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiRE9NQ2hhcmFjdGVyRGF0YU1vZGlmaWVkXCIsIHRoaXMsIHRydWUpO1xuICAgICAgaWYgKG9wdGlvbnMuY2hpbGRMaXN0KSBub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJET01Ob2RlSW5zZXJ0ZWRcIiwgdGhpcywgdHJ1ZSk7XG4gICAgICBpZiAob3B0aW9ucy5jaGlsZExpc3QgfHwgb3B0aW9ucy5zdWJ0cmVlKSBub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJET01Ob2RlUmVtb3ZlZFwiLCB0aGlzLCB0cnVlKTtcbiAgICB9LFxuICAgIGFkZFRyYW5zaWVudE9ic2VydmVyOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZSA9PT0gdGhpcy50YXJnZXQpIHJldHVybjtcbiAgICAgIHRoaXMuYWRkTGlzdGVuZXJzXyhub2RlKTtcbiAgICAgIHRoaXMudHJhbnNpZW50T2JzZXJ2ZWROb2Rlcy5wdXNoKG5vZGUpO1xuICAgICAgdmFyIHJlZ2lzdHJhdGlvbnMgPSByZWdpc3RyYXRpb25zVGFibGUuZ2V0KG5vZGUpO1xuICAgICAgaWYgKCFyZWdpc3RyYXRpb25zKSByZWdpc3RyYXRpb25zVGFibGUuc2V0KG5vZGUsIHJlZ2lzdHJhdGlvbnMgPSBbXSk7XG4gICAgICByZWdpc3RyYXRpb25zLnB1c2godGhpcyk7XG4gICAgfSxcbiAgICByZW1vdmVUcmFuc2llbnRPYnNlcnZlcnM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHRyYW5zaWVudE9ic2VydmVkTm9kZXMgPSB0aGlzLnRyYW5zaWVudE9ic2VydmVkTm9kZXM7XG4gICAgICB0aGlzLnRyYW5zaWVudE9ic2VydmVkTm9kZXMgPSBbXTtcbiAgICAgIHRyYW5zaWVudE9ic2VydmVkTm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXJzXyhub2RlKTtcbiAgICAgICAgdmFyIHJlZ2lzdHJhdGlvbnMgPSByZWdpc3RyYXRpb25zVGFibGUuZ2V0KG5vZGUpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlZ2lzdHJhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAocmVnaXN0cmF0aW9uc1tpXSA9PT0gdGhpcykge1xuICAgICAgICAgICAgcmVnaXN0cmF0aW9ucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIHRoaXMpO1xuICAgIH0sXG4gICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICBzd2l0Y2ggKGUudHlwZSkge1xuICAgICAgIGNhc2UgXCJET01BdHRyTW9kaWZpZWRcIjpcbiAgICAgICAgdmFyIG5hbWUgPSBlLmF0dHJOYW1lO1xuICAgICAgICB2YXIgbmFtZXNwYWNlID0gZS5yZWxhdGVkTm9kZS5uYW1lc3BhY2VVUkk7XG4gICAgICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldDtcbiAgICAgICAgdmFyIHJlY29yZCA9IG5ldyBnZXRSZWNvcmQoXCJhdHRyaWJ1dGVzXCIsIHRhcmdldCk7XG4gICAgICAgIHJlY29yZC5hdHRyaWJ1dGVOYW1lID0gbmFtZTtcbiAgICAgICAgcmVjb3JkLmF0dHJpYnV0ZU5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcbiAgICAgICAgdmFyIG9sZFZhbHVlID0gZS5hdHRyQ2hhbmdlID09PSBNdXRhdGlvbkV2ZW50LkFERElUSU9OID8gbnVsbCA6IGUucHJldlZhbHVlO1xuICAgICAgICBmb3JFYWNoQW5jZXN0b3JBbmRPYnNlcnZlckVucXVldWVSZWNvcmQodGFyZ2V0LCBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgaWYgKCFvcHRpb25zLmF0dHJpYnV0ZXMpIHJldHVybjtcbiAgICAgICAgICBpZiAob3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIgJiYgb3B0aW9ucy5hdHRyaWJ1dGVGaWx0ZXIubGVuZ3RoICYmIG9wdGlvbnMuYXR0cmlidXRlRmlsdGVyLmluZGV4T2YobmFtZSkgPT09IC0xICYmIG9wdGlvbnMuYXR0cmlidXRlRmlsdGVyLmluZGV4T2YobmFtZXNwYWNlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9wdGlvbnMuYXR0cmlidXRlT2xkVmFsdWUpIHJldHVybiBnZXRSZWNvcmRXaXRoT2xkVmFsdWUob2xkVmFsdWUpO1xuICAgICAgICAgIHJldHVybiByZWNvcmQ7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgIGNhc2UgXCJET01DaGFyYWN0ZXJEYXRhTW9kaWZpZWRcIjpcbiAgICAgICAgdmFyIHRhcmdldCA9IGUudGFyZ2V0O1xuICAgICAgICB2YXIgcmVjb3JkID0gZ2V0UmVjb3JkKFwiY2hhcmFjdGVyRGF0YVwiLCB0YXJnZXQpO1xuICAgICAgICB2YXIgb2xkVmFsdWUgPSBlLnByZXZWYWx1ZTtcbiAgICAgICAgZm9yRWFjaEFuY2VzdG9yQW5kT2JzZXJ2ZXJFbnF1ZXVlUmVjb3JkKHRhcmdldCwgZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIGlmICghb3B0aW9ucy5jaGFyYWN0ZXJEYXRhKSByZXR1cm47XG4gICAgICAgICAgaWYgKG9wdGlvbnMuY2hhcmFjdGVyRGF0YU9sZFZhbHVlKSByZXR1cm4gZ2V0UmVjb3JkV2l0aE9sZFZhbHVlKG9sZFZhbHVlKTtcbiAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgICBjYXNlIFwiRE9NTm9kZVJlbW92ZWRcIjpcbiAgICAgICAgdGhpcy5hZGRUcmFuc2llbnRPYnNlcnZlcihlLnRhcmdldCk7XG5cbiAgICAgICBjYXNlIFwiRE9NTm9kZUluc2VydGVkXCI6XG4gICAgICAgIHZhciBjaGFuZ2VkTm9kZSA9IGUudGFyZ2V0O1xuICAgICAgICB2YXIgYWRkZWROb2RlcywgcmVtb3ZlZE5vZGVzO1xuICAgICAgICBpZiAoZS50eXBlID09PSBcIkRPTU5vZGVJbnNlcnRlZFwiKSB7XG4gICAgICAgICAgYWRkZWROb2RlcyA9IFsgY2hhbmdlZE5vZGUgXTtcbiAgICAgICAgICByZW1vdmVkTm9kZXMgPSBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGRlZE5vZGVzID0gW107XG4gICAgICAgICAgcmVtb3ZlZE5vZGVzID0gWyBjaGFuZ2VkTm9kZSBdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmV2aW91c1NpYmxpbmcgPSBjaGFuZ2VkTm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgIHZhciBuZXh0U2libGluZyA9IGNoYW5nZWROb2RlLm5leHRTaWJsaW5nO1xuICAgICAgICB2YXIgcmVjb3JkID0gZ2V0UmVjb3JkKFwiY2hpbGRMaXN0XCIsIGUudGFyZ2V0LnBhcmVudE5vZGUpO1xuICAgICAgICByZWNvcmQuYWRkZWROb2RlcyA9IGFkZGVkTm9kZXM7XG4gICAgICAgIHJlY29yZC5yZW1vdmVkTm9kZXMgPSByZW1vdmVkTm9kZXM7XG4gICAgICAgIHJlY29yZC5wcmV2aW91c1NpYmxpbmcgPSBwcmV2aW91c1NpYmxpbmc7XG4gICAgICAgIHJlY29yZC5uZXh0U2libGluZyA9IG5leHRTaWJsaW5nO1xuICAgICAgICBmb3JFYWNoQW5jZXN0b3JBbmRPYnNlcnZlckVucXVldWVSZWNvcmQoZS5yZWxhdGVkTm9kZSwgZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIGlmICghb3B0aW9ucy5jaGlsZExpc3QpIHJldHVybjtcbiAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNsZWFyUmVjb3JkcygpO1xuICAgIH1cbiAgfTtcbiAgZ2xvYmFsLkpzTXV0YXRpb25PYnNlcnZlciA9IEpzTXV0YXRpb25PYnNlcnZlcjtcbiAgaWYgKCFnbG9iYWwuTXV0YXRpb25PYnNlcnZlcikge1xuICAgIGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyID0gSnNNdXRhdGlvbk9ic2VydmVyO1xuICAgIEpzTXV0YXRpb25PYnNlcnZlci5faXNQb2x5ZmlsbGVkID0gdHJ1ZTtcbiAgfVxufSkoc2VsZik7XG4iLCIvKlxuQ29weXJpZ2h0IChjKSAyMDEyIEJhcm5lc2FuZG5vYmxlLmNvbSwgbGxjLCBEb25hdm9uIFdlc3QsIGFuZCBEb21lbmljIERlbmljb2xhXG5cblBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZ1xuYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG5cIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbndpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbmRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xucGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvXG50aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlXG5pbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCxcbkVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkRcbk5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkVcbkxJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT05cbk9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbiovXG4oZnVuY3Rpb24gKGdsb2JhbCwgdW5kZWZpbmVkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBpZiAoZ2xvYmFsLnNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIG5leHRIYW5kbGUgPSAxOyAvLyBTcGVjIHNheXMgZ3JlYXRlciB0aGFuIHplcm9cbiAgICB2YXIgdGFza3NCeUhhbmRsZSA9IHt9O1xuICAgIHZhciBjdXJyZW50bHlSdW5uaW5nQVRhc2sgPSBmYWxzZTtcbiAgICB2YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xuICAgIHZhciBzZXRJbW1lZGlhdGU7XG5cbiAgICBmdW5jdGlvbiBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3MpIHtcbiAgICAgICAgdGFza3NCeUhhbmRsZVtuZXh0SGFuZGxlXSA9IHBhcnRpYWxseUFwcGxpZWQuYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICAgICAgcmV0dXJuIG5leHRIYW5kbGUrKztcbiAgICB9XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgdGhlIHNhbWUgYXJndW1lbnRzIGFzIHNldEltbWVkaWF0ZSwgYnV0XG4gICAgLy8gcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgcmVxdWlyZXMgbm8gYXJndW1lbnRzLlxuICAgIGZ1bmN0aW9uIHBhcnRpYWxseUFwcGxpZWQoaGFuZGxlcikge1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVyLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIChuZXcgRnVuY3Rpb24oXCJcIiArIGhhbmRsZXIpKSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bklmUHJlc2VudChoYW5kbGUpIHtcbiAgICAgICAgLy8gRnJvbSB0aGUgc3BlYzogXCJXYWl0IHVudGlsIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGFsZ29yaXRobSBzdGFydGVkIGJlZm9yZSB0aGlzIG9uZSBoYXZlIGNvbXBsZXRlZC5cIlxuICAgICAgICAvLyBTbyBpZiB3ZSdyZSBjdXJyZW50bHkgcnVubmluZyBhIHRhc2ssIHdlJ2xsIG5lZWQgdG8gZGVsYXkgdGhpcyBpbnZvY2F0aW9uLlxuICAgICAgICBpZiAoY3VycmVudGx5UnVubmluZ0FUYXNrKSB7XG4gICAgICAgICAgICAvLyBEZWxheSBieSBkb2luZyBhIHNldFRpbWVvdXQuIHNldEltbWVkaWF0ZSB3YXMgdHJpZWQgaW5zdGVhZCwgYnV0IGluIEZpcmVmb3ggNyBpdCBnZW5lcmF0ZWQgYVxuICAgICAgICAgICAgLy8gXCJ0b28gbXVjaCByZWN1cnNpb25cIiBlcnJvci5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocGFydGlhbGx5QXBwbGllZChydW5JZlByZXNlbnQsIGhhbmRsZSksIDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgICAgICAgICBpZiAodGFzaykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IHRydWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgdGFzaygpO1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGhhbmRsZSkge1xuICAgICAgICBkZWxldGUgdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICBzZXRJbW1lZGlhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICBwcm9jZXNzLm5leHRUaWNrKHBhcnRpYWxseUFwcGxpZWQocnVuSWZQcmVzZW50LCBoYW5kbGUpKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FuVXNlUG9zdE1lc3NhZ2UoKSB7XG4gICAgICAgIC8vIFRoZSB0ZXN0IGFnYWluc3QgYGltcG9ydFNjcmlwdHNgIHByZXZlbnRzIHRoaXMgaW1wbGVtZW50YXRpb24gZnJvbSBiZWluZyBpbnN0YWxsZWQgaW5zaWRlIGEgd2ViIHdvcmtlcixcbiAgICAgICAgLy8gd2hlcmUgYGdsb2JhbC5wb3N0TWVzc2FnZWAgbWVhbnMgc29tZXRoaW5nIGNvbXBsZXRlbHkgZGlmZmVyZW50IGFuZCBjYW4ndCBiZSB1c2VkIGZvciB0aGlzIHB1cnBvc2UuXG4gICAgICAgIGlmIChnbG9iYWwucG9zdE1lc3NhZ2UgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgICAgICAgICB2YXIgcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyA9IHRydWU7XG4gICAgICAgICAgICB2YXIgb2xkT25NZXNzYWdlID0gZ2xvYmFsLm9ubWVzc2FnZTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gZmFsc2U7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKFwiXCIsIFwiKlwiKTtcbiAgICAgICAgICAgIGdsb2JhbC5vbm1lc3NhZ2UgPSBvbGRPbk1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gcG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICAvLyBJbnN0YWxscyBhbiBldmVudCBoYW5kbGVyIG9uIGBnbG9iYWxgIGZvciB0aGUgYG1lc3NhZ2VgIGV2ZW50OiBzZWVcbiAgICAgICAgLy8gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vd2luZG93LnBvc3RNZXNzYWdlXG4gICAgICAgIC8vICogaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvY29tbXMuaHRtbCNjcm9zc0RvY3VtZW50TWVzc2FnZXNcblxuICAgICAgICB2YXIgbWVzc2FnZVByZWZpeCA9IFwic2V0SW1tZWRpYXRlJFwiICsgTWF0aC5yYW5kb20oKSArIFwiJFwiO1xuICAgICAgICB2YXIgb25HbG9iYWxNZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zb3VyY2UgPT09IGdsb2JhbCAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBldmVudC5kYXRhID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAgICAgZXZlbnQuZGF0YS5pbmRleE9mKG1lc3NhZ2VQcmVmaXgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcnVuSWZQcmVzZW50KCtldmVudC5kYXRhLnNsaWNlKG1lc3NhZ2VQcmVmaXgubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlLCBmYWxzZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbG9iYWwuYXR0YWNoRXZlbnQoXCJvbm1lc3NhZ2VcIiwgb25HbG9iYWxNZXNzYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGFkZEZyb21TZXRJbW1lZGlhdGVBcmd1bWVudHMoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShtZXNzYWdlUHJlZml4ICsgaGFuZGxlLCBcIipcIik7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIGhhbmRsZSA9IGFkZEZyb21TZXRJbW1lZGlhdGVBcmd1bWVudHMoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaGFuZGxlKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgdmFyIGh0bWwgPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICBzZXRJbW1lZGlhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBhZGRGcm9tU2V0SW1tZWRpYXRlQXJndW1lbnRzKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgICAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICAgICAgICB2YXIgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB2YXIgaGFuZGxlID0gYWRkRnJvbVNldEltbWVkaWF0ZUFyZ3VtZW50cyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgc2V0VGltZW91dChwYXJ0aWFsbHlBcHBsaWVkKHJ1bklmUHJlc2VudCwgaGFuZGxlKSwgMCk7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIElmIHN1cHBvcnRlZCwgd2Ugc2hvdWxkIGF0dGFjaCB0byB0aGUgcHJvdG90eXBlIG9mIGdsb2JhbCwgc2luY2UgdGhhdCBpcyB3aGVyZSBzZXRUaW1lb3V0IGV0IGFsLiBsaXZlLlxuICAgIHZhciBhdHRhY2hUbyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZiAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZ2xvYmFsKTtcbiAgICBhdHRhY2hUbyA9IGF0dGFjaFRvICYmIGF0dGFjaFRvLnNldFRpbWVvdXQgPyBhdHRhY2hUbyA6IGdsb2JhbDtcblxuICAgIC8vIERvbid0IGdldCBmb29sZWQgYnkgZS5nLiBicm93c2VyaWZ5IGVudmlyb25tZW50cy5cbiAgICBpZiAoe30udG9TdHJpbmcuY2FsbChnbG9iYWwucHJvY2VzcykgPT09IFwiW29iamVjdCBwcm9jZXNzXVwiKSB7XG4gICAgICAgIC8vIEZvciBOb2RlLmpzIGJlZm9yZSAwLjlcbiAgICAgICAgaW5zdGFsbE5leHRUaWNrSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoY2FuVXNlUG9zdE1lc3NhZ2UoKSkge1xuICAgICAgICAvLyBGb3Igbm9uLUlFMTAgbW9kZXJuIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCkge1xuICAgICAgICAvLyBGb3Igd2ViIHdvcmtlcnMsIHdoZXJlIHN1cHBvcnRlZFxuICAgICAgICBpbnN0YWxsTWVzc2FnZUNoYW5uZWxJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChkb2MgJiYgXCJvbnJlYWR5c3RhdGVjaGFuZ2VcIiBpbiBkb2MuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKSkge1xuICAgICAgICAvLyBGb3IgSUUgNuKAkzhcbiAgICAgICAgaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRm9yIG9sZGVyIGJyb3dzZXJzXG4gICAgICAgIGluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24oKTtcbiAgICB9XG5cbiAgICBhdHRhY2hUby5zZXRJbW1lZGlhdGUgPSBzZXRJbW1lZGlhdGU7XG4gICAgYXR0YWNoVG8uY2xlYXJJbW1lZGlhdGUgPSBjbGVhckltbWVkaWF0ZTtcbn0oc2VsZikpO1xuIiwiLy8gQ2F1dGlvbjpcbi8vIERvIG5vdCByZXBsYWNlIHRoaXMgaW1wb3J0IHN0YXRlbWVudCB3aXRoIGNvZGVzLlxuLy9cbi8vIElmIHlvdSByZXBsYWNlIHRoaXMgaW1wb3J0IHN0YXRlbWVudCB3aXRoIGNvZGVzLFxuLy8gdGhlIGNvZGVzIHdpbGwgYmUgZXhlY3V0ZWQgYWZ0ZXIgdGhlIGZvbGxvd2luZyBwb2x5ZmlsbHMgYXJlIGltcG9ydGVkXG4vLyBiZWNhdXNlIGltcG9ydCBzdGF0ZW1lbnRzIGFyZSBob2lzdGVkIGR1cmluZyBjb21waWxhdGlvbi5cbmltcG9ydCAnLi9wb2x5ZmlsbC1zd2l0Y2hlcyc7XG5cbi8vIFBvbHlmaWxsIEVDTUFTY3JpcHQgc3RhbmRhcmQgZmVhdHVyZXMgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICdjb3JlLWpzL2ZuL29iamVjdC9zZXQtcHJvdG90eXBlLW9mJztcbmltcG9ydCAnY29yZS1qcy9mbi9zZXQnO1xuaW1wb3J0ICdjb3JlLWpzL2ZuL21hcCc7XG5pbXBvcnQgJ2NvcmUtanMvZm4vd2Vhay1tYXAnO1xuaW1wb3J0ICdjb3JlLWpzL2ZuL2FycmF5L2Zyb20nO1xuXG4vLyBQb2x5ZmlsbCBDdXN0b20gRWxlbWVudHMgdjEgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICdAb25zZW51aS9jdXN0b20tZWxlbWVudHMvc3JjL2N1c3RvbS1lbGVtZW50cyc7XG5cbi8vIFBvbHlmaWxsIE11dGF0aW9uT2JzZXJ2ZXIgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICcuL011dGF0aW9uT2JzZXJ2ZXJAMC43LjIyL011dGF0aW9uT2JzZXJ2ZXIuanMnO1xuXG4vLyBQb2x5ZmlsbCBzZXRJbW1lZGlhdGUgd2l0aCBnbG9iYWwgbmFtZXNwYWNlIHBvbGx1dGlvblxuaW1wb3J0ICcuL3NldEltbWVkaWF0ZUAxLjAuMittb2Qvc2V0SW1tZWRpYXRlLmpzJztcbiIsIihmdW5jdGlvbigpIHtcbiAgdmFyIERFRkFVTFRfVklFV1BPUlQgPSAnd2lkdGg9ZGV2aWNlLXdpZHRoLGluaXRpYWwtc2NhbGU9MSxtYXhpbXVtLXNjYWxlPTEsbWluaW11bS1zY2FsZT0xLHVzZXItc2NhbGFibGU9bm8nO1xuXG4gIHZhciBWaWV3cG9ydCA9IHsgXG4gICAgZW5zdXJlVmlld3BvcnRFbGVtZW50OiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9dmlld3BvcnRdJyk7XG5cbiAgICAgIGlmICghdmlld3BvcnRFbGVtZW50KSB7XG4gICAgICAgIHZpZXdwb3J0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ21ldGEnKTtcbiAgICAgICAgdmlld3BvcnRFbGVtZW50Lm5hbWUgPSAndmlld3BvcnQnO1xuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHZpZXdwb3J0RWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2aWV3cG9ydEVsZW1lbnQ7XG4gICAgfSxcblxuICAgIHNldHVwOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnQgPSBWaWV3cG9ydC5lbnN1cmVWaWV3cG9ydEVsZW1lbnQoKTtcblxuICAgICAgaWYgKCF2aWV3cG9ydEVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXZpZXdwb3J0RWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2NvbnRlbnQnKSkge1xuICAgICAgICB2aWV3cG9ydEVsZW1lbnQuc2V0QXR0cmlidXRlKCdjb250ZW50JywgREVGQVVMVF9WSUVXUE9SVCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHdpbmRvdy5WaWV3cG9ydCA9IFZpZXdwb3J0O1xufSkoKTtcbiIsImltcG9ydCB7IEZhc3RDbGljayB9IGZyb20gJ0BvbnNlbnVpL2Zhc3RjbGljayc7XG5pbXBvcnQgJy4vb25zL3BsYXRmb3JtJzsgLy8gVGhpcyBmaWxlIG11c3QgYmUgbG9hZGVkIGJlZm9yZSBDdXN0b20gRWxlbWVudHMgcG9seWZpbGxzLlxuaW1wb3J0ICcuL3BvbHlmaWxscy9pbmRleC5qcyc7XG5pbXBvcnQgJy4vdmVuZG9yL2luZGV4LmpzJztcbmltcG9ydCAnLi9vbnMvbWljcm9ldmVudC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNldHVwKG9ucykge1xuICBpZiAod2luZG93Ll9vbnNMb2FkZWQpIHtcbiAgICBvbnMuX3V0aWwud2FybignT25zZW4gVUkgaXMgbG9hZGVkIG1vcmUgdGhhbiBvbmNlLicpO1xuICB9XG4gIHdpbmRvdy5fb25zTG9hZGVkID0gdHJ1ZTtcblxuICAvLyBmYXN0Y2xpY2tcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoKSA9PiB7XG4gICAgb25zLmZhc3RDbGljayA9IEZhc3RDbGljay5hdHRhY2goZG9jdW1lbnQuYm9keSk7XG5cbiAgICBjb25zdCBzdXBwb3J0VG91Y2hBY3Rpb24gPSAndG91Y2gtYWN0aW9uJyBpbiBkb2N1bWVudC5ib2R5LnN0eWxlO1xuXG4gICAgb25zLnBsYXRmb3JtLl9ydW5PbkFjdHVhbFBsYXRmb3JtKCgpID0+IHtcbiAgICAgIGlmIChvbnMucGxhdGZvcm0uaXNBbmRyb2lkKCkpIHtcbiAgICAgICAgLy8gSW4gQW5kcm9pZDQuNCssIGNvcnJlY3Qgdmlld3BvcnQgc2V0dGluZ3MgY2FuIHJlbW92ZSBjbGljayBkZWxheS5cbiAgICAgICAgLy8gU28gZGlzYWJsZSBGYXN0Q2xpY2sgb24gQW5kcm9pZC5cbiAgICAgICAgb25zLmZhc3RDbGljay5kZXN0cm95KCk7XG4gICAgICB9IGVsc2UgaWYgKG9ucy5wbGF0Zm9ybS5pc0lPUygpKSB7XG4gICAgICAgIGlmIChzdXBwb3J0VG91Y2hBY3Rpb24gJiYgKG9ucy5wbGF0Zm9ybS5pc0lPU1NhZmFyaSgpIHx8IG9ucy5wbGF0Zm9ybS5pc1dLV2ViVmlldygpKSkge1xuICAgICAgICAgIC8vIElmICd0b3VjaC1hY3Rpb24nIHN1cHBvcnRlZCBpbiBpT1MgU2FmYXJpIG9yIFdLV2ViVmlldywgZGlzYWJsZSBGYXN0Q2xpY2suXG4gICAgICAgICAgb25zLmZhc3RDbGljay5kZXN0cm95KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRG8gbm90aGluZy4gJ3RvdWNoLWFjdGlvbjogbWFuaXB1bGF0aW9uJyBoYXMgbm8gZWZmZWN0IG9uIFVJV2ViVmlldy5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9LCBmYWxzZSk7XG5cbiAgb25zLnJlYWR5KGZ1bmN0aW9uKCkge1xuICAgIG9ucy5lbmFibGVEZXZpY2VCYWNrQnV0dG9uSGFuZGxlcigpO1xuICAgIG9ucy5fZGVmYXVsdERldmljZUJhY2tCdXR0b25IYW5kbGVyID0gb25zLl9pbnRlcm5hbC5kYmJEaXNwYXRjaGVyLmNyZWF0ZUhhbmRsZXIod2luZG93LmRvY3VtZW50LmJvZHksICgpID0+IHtcbiAgICAgIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChuYXZpZ2F0b3IsICdhcHAnKSkge1xuICAgICAgICBuYXZpZ2F0b3IuYXBwLmV4aXRBcHAoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2FybignQ291bGQgbm90IGNsb3NlIHRoZSBhcHAuIElzIFxcJ2NvcmRvdmEuanNcXCcgaW5jbHVkZWQ/XFxuRXJyb3I6IFxcJ3dpbmRvdy5uYXZpZ2F0b3IuYXBwXFwnIGlzIHVuZGVmaW5lZC4nKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkb2N1bWVudC5ib2R5Ll9nZXN0dXJlRGV0ZWN0b3IgPSBuZXcgb25zLkdlc3R1cmVEZXRlY3Rvcihkb2N1bWVudC5ib2R5LCB7IHBhc3NpdmU6IHRydWUgfSk7XG5cbiAgICAvLyBTaW11bGF0ZSBEZXZpY2UgQmFjayBCdXR0b24gb24gRVNDIHByZXNzXG4gICAgaWYgKCFvbnMucGxhdGZvcm0uaXNXZWJWaWV3KCkpIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAyNykge1xuICAgICAgICAgIG9ucy5maXJlRGV2aWNlQmFja0J1dHRvbkV2ZW50KCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gc2V0dXAgbG9hZGluZyBwbGFjZWhvbGRlclxuICAgIG9ucy5fc2V0dXBMb2FkaW5nUGxhY2VIb2xkZXJzKCk7XG4gIH0pO1xuXG4gIC8vIHZpZXdwb3J0LmpzXG4gIFZpZXdwb3J0LnNldHVwKCk7XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5mdW5jdGlvbiBnZXRFbGVtZW50Q2xhc3MoKSB7XG4gIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09ICdmdW5jdGlvbicpIHsgLy8gY2FzZSBvZiBTYWZhcmlcbiAgICBjb25zdCBCYXNlRWxlbWVudCA9ICgpID0+IHt9O1xuICAgIEJhc2VFbGVtZW50LnByb3RvdHlwZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHJldHVybiBCYXNlRWxlbWVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gSFRNTEVsZW1lbnQ7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFzZUVsZW1lbnQgZXh0ZW5kcyBnZXRFbGVtZW50Q2xhc3MoKSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy10ZW1wbGF0ZVxuICogQGNhdGVnb3J5IHV0aWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgRGVmaW5lIGEgc2VwYXJhdGUgSFRNTCBmcmFnbWVudCBhbmQgdXNlIGFzIGEgdGVtcGxhdGUuIFRoZXNlIHRlbXBsYXRlcyBjYW4gYmUgbG9hZGVkIGFzIHBhZ2VzIGluIGA8b25zLW5hdmlnYXRvcj5gLCBgPG9ucy10YWJiYXI+YCBhbmQgYDxvbnMtc3BsaXR0ZXI+YC4gVGhleSBjYW4gYWxzbyBiZSB1c2VkIHRvIGdlbmVyYXRlIGRpYWxvZ3MuIFNpbmNlIE9uc2VuIFVJIDIuNC4wLCB0aGUgbmF0aXZlIGA8dGVtcGxhdGU+YCBlbGVtZW50IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgYDxvbnMtdGVtcGxhdGU+YCBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlIGFuZCBmZWF0dXJlcy4gYDxvbnMtdGVtcGxhdGU+YCBpcyBzdGlsbCBzdXBwb3J0ZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg4bjg7Pjg5fjg6zjg7zjg4jjgajjgZfjgabkvb/nlKjjgZnjgovjgZ/jgoHjga5IVE1M44OV44Op44Kw44Oh44Oz44OI44KS5a6a576p44GX44G+44GZ44CC44GT44Gu6KaB57Sg44GnSFRNTOOCkuWuo+iogOOBmeOCi+OBqOOAgWlk5bGe5oCn44Gr5oyH5a6a44GX44Gf5ZCN5YmN44KScGFnZeOBrlVSTOOBqOOBl+OBpm9ucy1uYXZpZ2F0b3Ljgarjganjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgYvjgonlj4LnhafjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQHNlZWFsc28gb25zLW5hdmlnYXRvclxuICogICBbZW5dVGhlIGA8b25zLW5hdmlnYXRvcj5gIGNvbXBvbmVudCBlbmFibGVzIHN0YWNrIGJhc2VkIG5hdmlnYXRpb24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtdGFiYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtdGFiYmFyPmAgY29tcG9uZW50IGlzIHVzZWQgdG8gYWRkIHRhYiBuYXZpZ2F0aW9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyXG4gKiAgIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXI+YCBjb21wb25lbnQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGEgZHJhZ2dhYmxlIG1lbnUgb3IgY29sdW1uIGJhc2VkIGxheW91dC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXRlbXBsYXRlIGlkPVwiZm9vYmFyLmh0bWxcIj5cbiAqICAgPG9ucy1wYWdlPlxuICogICAgIFBhZ2UgY29udGVudFxuICogICA8L29ucy1wYWdlPlxuICogPC9vbnMtdGVtcGxhdGU+XG4gKlxuICogPG9ucy1uYXZpZ2F0b3IgcGFnZT1cImZvb2Jhci5odG1sXCI+PC9vbnMtbmF2aWdhdG9yPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZW1wbGF0ZUVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB0ZW1wbGF0ZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UZW1wbGF0ZSBjb250ZW50LiBUaGlzIHByb3BlcnR5IGNhbiBub3QgYmUgdXNlZCB3aXRoIEFuZ3VsYXJKUyBiaW5kaW5ncy5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnRlbXBsYXRlID0gdGhpcy5pbm5lckhUTUw7XG5cbiAgICB3aGlsZSAodGhpcy5maXJzdENoaWxkKSB7XG4gICAgICB0aGlzLnJlbW92ZUNoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgaWYgKHRoaXMucGFyZW50Tm9kZSkgeyAvLyBOb3RlOiB0aGlzLnBhcmVudE5vZGUgaXMgbm90IHNldCBpbiBzb21lIENFMC9DRTEgcG9seWZpbGxzLlxuICAgICAgLy8gU2hvdyB3YXJuaW5nIHdoZW4gdGhlIG9ucy10ZW1wbGF0ZSBpcyBub3QgbG9jYXRlZCBqdXN0IHVuZGVyIGRvY3VtZW50LmJvZHlcbiAgICAgIGlmICh0aGlzLnBhcmVudE5vZGUgIT09IGRvY3VtZW50LmJvZHkpIHsgLy8gaWYgdGhlIHBhcmVudCBpcyBub3QgZG9jdW1lbnQuYm9keVxuICAgICAgICB1dGlsLndhcm4oYG9ucy10ZW1wbGF0ZSAoaWQgPSAke3RoaXMuZ2V0QXR0cmlidXRlKCdpZCcpfSkgbXVzdCBiZSBsb2NhdGVkIGp1c3QgdW5kZXIgZG9jdW1lbnQuYm9keSR7IHRoaXMucGFyZW50Tm9kZS5vdXRlckhUTUwgPyBgOlxcblxcbiR7dGhpcy5wYXJlbnROb2RlLm91dGVySFRNTH1gIDogJy4nIH1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZXZlbnQgPSBuZXcgQ3VzdG9tRXZlbnQoJ190ZW1wbGF0ZWxvYWRlZCcsIHtidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiB0cnVlfSk7XG4gICAgZXZlbnQudGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlO1xuICAgIGV2ZW50LnRlbXBsYXRlSWQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnaWQnKTtcblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gIH1cbn1cblxub25zRWxlbWVudHMuVGVtcGxhdGUgPSBUZW1wbGF0ZUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy10ZW1wbGF0ZScsIFRlbXBsYXRlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBvcmllbnRhdGlvbiBmcm9tICcuLi9vbnMvb3JpZW50YXRpb24nO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL29ucy9wbGF0Zm9ybSc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtaWZcbiAqIEBjYXRlZ29yeSBjb25kaXRpb25hbFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2lmXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIENvbmRpdGlvbmFsbHkgZGlzcGxheSBjb250ZW50IGRlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0sIGRldmljZSBvcmllbnRhdGlvbiBvciBib3RoLlxuICpcbiAqICAgICBTb21ldGltZXMgaXQgaXMgdXNlZnVsIHRvIGNvbmRpdGlvbmFsbHkgaGlkZSBvciBzaG93IGNlcnRhaW4gY29tcG9uZW50cyBiYXNlZCBvbiBwbGF0Zm9ybS4gV2hlbiBydW5uaW5nIG9uIGlPUyB0aGUgYDxvbnMtaWY+YCBlbGVtZW50IGNhbiBiZSB1c2VkIHRvIGhpZGUgdGhlIGA8b25zLWZhYj5gIGVsZW1lbnQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1wYWdlPlxuICogICA8b25zLWlmIG9yaWVudGF0aW9uPVwibGFuZHNjYXBlXCI+XG4gKiAgICAgTGFuZHNjYXBlIHZpZXchXG4gKiAgIDwvb25zLWlmPlxuICogICA8b25zLWlmIHBsYXRmb3JtPVwiYW5kcm9pZFwiPlxuICogICAgIFRoaXMgaXMgQW5kcm9pZC5cbiAqICAgPC9vbnMtaWY+XG4gKiAgIDxvbnMtaWYgcGxhdGZvcm09XCJpb3Mgb3RoZXJcIj5cbiAqICAgICBUaGlzIGlzIG5vdCBBbmRyb2lkLlxuICogICA8L29ucy1pZj5cbiAqIDwvb25zLXBhZ2U+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIElmRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwbGF0Zm9ybVxuICAgKiBAaW5pdG9ubHlcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BhY2Utc2VwYXJhdGVkIHBsYXRmb3JtIG5hbWVzLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBcImlvc1wiYCwgYFwiYW5kcm9pZFwiYCwgYFwid2luZG93c1wiYCBhbmQgYFwib3RoZXJcImAuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBvcmllbnRhdGlvblxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1FaXRoZXIgYFwicG9ydHJhaXRcImAgb3IgYFwibGFuZHNjYXBlXCJgLlsvZW5dXG4gICAqICBbamFdcG9ydHJhaXTjgoLjgZfjgY/jga9sYW5kc2NhcGXjgpLmjIflrprjgZfjgb7jgZlbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIGlmIChwbGF0Zm9ybS5fZ2V0U2VsZWN0ZWRQbGF0Zm9ybSgpICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuX3BsYXRmb3JtVXBkYXRlKCk7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLl9pc0FsbG93ZWRQbGF0Zm9ybSgpKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgICAgICB0aGlzLmNoaWxkTm9kZXNbMF0ucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcGxhdGZvcm1VcGRhdGUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuX29uT3JpZW50YXRpb25DaGFuZ2UoKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIG9yaWVudGF0aW9uLm9uKCdjaGFuZ2UnLCB0aGlzLl9vbk9yaWVudGF0aW9uQ2hhbmdlLmJpbmQodGhpcykpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnb3JpZW50YXRpb24nXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lKSB7XG4gICAgaWYgKG5hbWUgPT09ICdvcmllbnRhdGlvbicpIHtcbiAgICAgIHRoaXMuX29uT3JpZW50YXRpb25DaGFuZ2UoKTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBvcmllbnRhdGlvbi5vZmYoJ2NoYW5nZScsIHRoaXMuX29uT3JpZW50YXRpb25DaGFuZ2UpO1xuICB9XG5cbiAgX3BsYXRmb3JtVXBkYXRlKCkge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHRoaXMuX2lzQWxsb3dlZFBsYXRmb3JtKCkgPyAnJyA6ICdub25lJztcbiAgfVxuXG4gIF9pc0FsbG93ZWRQbGF0Zm9ybSgpIHtcbiAgICByZXR1cm4gIXRoaXMuZ2V0QXR0cmlidXRlKCdwbGF0Zm9ybScpIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdwbGF0Zm9ybScpLnNwbGl0KC9cXHMrLykuaW5kZXhPZihwbGF0Zm9ybS5nZXRNb2JpbGVPUygpKSA+PSAwO1xuICB9XG5cbiAgX29uT3JpZW50YXRpb25DaGFuZ2UoKSB7XG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdvcmllbnRhdGlvbicpICYmIHRoaXMuX2lzQWxsb3dlZFBsYXRmb3JtKCkpIHtcbiAgICAgIGNvbnN0IGNvbmRpdGlvbmFsT3JpZW50YXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgnb3JpZW50YXRpb24nKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3QgY3VycmVudE9yaWVudGF0aW9uID0gb3JpZW50YXRpb24uaXNQb3J0cmFpdCgpID8gJ3BvcnRyYWl0JyA6ICdsYW5kc2NhcGUnO1xuXG4gICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPSAoY29uZGl0aW9uYWxPcmllbnRhdGlvbiA9PT0gY3VycmVudE9yaWVudGF0aW9uKSA/ICcnIDogJ25vbmUnO1xuICAgIH1cbiAgfVxufVxuXG5vbnNFbGVtZW50cy5JZiA9IElmRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWlmJywgSWZFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VBbmltYXRvciB7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLnRpbWluZ1xuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kdXJhdGlvblxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kZWxheVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy50aW1pbmcgPSBvcHRpb25zLnRpbWluZyB8fCAnbGluZWFyJztcbiAgICB0aGlzLmR1cmF0aW9uID0gb3B0aW9ucy5kdXJhdGlvbiB8fCAwO1xuICAgIHRoaXMuZGVsYXkgPSBvcHRpb25zLmRlbGF5IHx8IDA7XG5cbiAgICB0aGlzLmRlZiA9IHtcbiAgICAgIHRpbWluZzogdGhpcy50aW1pbmcsXG4gICAgICBkdXJhdGlvbjogdGhpcy5kdXJhdGlvbixcbiAgICAgIGRlbGF5OiB0aGlzLmRlbGF5XG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBleHRlbmQocHJvcGVydGllcyA9IHt9KSB7XG4gICAgY29uc3QgZXh0ZW5kZWRBbmltYXRvciA9IHRoaXM7XG4gICAgY29uc3QgbmV3QW5pbWF0b3IgPSBmdW5jdGlvbigpIHtcbiAgICAgIGV4dGVuZGVkQW5pbWF0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHV0aWwuZXh0ZW5kKHRoaXMsIHByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICBuZXdBbmltYXRvci5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3QW5pbWF0b3I7XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuLy8gVGhpcyBvYmplY3Qgc2hvdWxkIG5vdCBiZSBleHBvc2VkIHRvIHVzZXJzLiBQbGVhc2Uga2VlcCB0aGlzIHByaXZhdGUuXG5jb25zdCBpUGhvbmVYUGF0Y2ggPSB7fTtcblxuaVBob25lWFBhdGNoLmlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUgPSAoKSA9PiB7XG4gIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdvbnNmbGFnLWlwaG9uZXgtcG9ydHJhaXQnKSAhPSBudWxsICYmIHdpbmRvdy5pbm5lcldpZHRoIDwgd2luZG93LmlubmVySGVpZ2h0O1xufVxuXG5pUGhvbmVYUGF0Y2guaXNJUGhvbmVYTGFuZHNjYXBlUGF0Y2hBY3RpdmUgPSAoKSA9PiB7XG4gIC8vIElmIHdpZHRoID09PSBoZWlnaHQsIHRyZWF0IGl0IGFzIGxhbmRzY2FwZVxuICByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgnb25zZmxhZy1pcGhvbmV4LWxhbmRzY2FwZScpICE9IG51bGwgJiYgd2luZG93LmlubmVyV2lkdGggPj0gd2luZG93LmlubmVySGVpZ2h0O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHNhZmUgYXJlYSBsZW5ndGhzIGJhc2VkIG9uIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBzYWZlIGFyZWFzLlxuICovXG5pUGhvbmVYUGF0Y2guZ2V0U2FmZUFyZWFMZW5ndGhzID0gKCkgPT4ge1xuICBsZXQgc2FmZUFyZWFMZW5ndGhzO1xuICBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUoKSkge1xuICAgIHNhZmVBcmVhTGVuZ3RocyA9IHtcbiAgICAgIHRvcDogNDQsXG4gICAgICByaWdodDogMCxcbiAgICAgIGJvdHRvbTogMzQsXG4gICAgICBsZWZ0OiAwXG4gICAgfTtcbiAgfSBlbHNlIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYTGFuZHNjYXBlUGF0Y2hBY3RpdmUoKSkge1xuICAgIHNhZmVBcmVhTGVuZ3RocyA9IHtcbiAgICAgIHRvcDogMCxcbiAgICAgIHJpZ2h0OiA0NCxcbiAgICAgIGJvdHRvbTogMjEsXG4gICAgICBsZWZ0OiA0NFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgc2FmZUFyZWFMZW5ndGhzID0ge1xuICAgICAgdG9wOiAwLFxuICAgICAgcmlnaHQ6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICBsZWZ0OiAwXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBzYWZlQXJlYUxlbmd0aHM7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc2FmZSBhcmVhIHJlY3QgYmFzZWQgb24gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHNhZmUgYXJlYXMuXG4gKi9cbmlQaG9uZVhQYXRjaC5nZXRTYWZlQXJlYURPTVJlY3QgPSAoKSA9PiB7XG4gIGxldCBzYWZlQXJlYVJlY3Q7XG4gIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYUG9ydHJhaXRQYXRjaEFjdGl2ZSgpKSB7XG4gICAgc2FmZUFyZWFSZWN0ID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDQ0LCAvKiAwICsgNDQgKHRvcCBzYWZlIGFyZWEpICovXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpbmRvdy5pbm5lckhlaWdodCAtIDc4IC8qIGhlaWdodCAtIDQ0ICh0b3Agc2FmZSBhcmVhKSAtIDM0IChib3R0b20gc2FmZSBhcmVhKSAqL1xuICAgIH07XG4gIH0gZWxzZSBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWExhbmRzY2FwZVBhdGNoQWN0aXZlKCkpIHtcbiAgICBzYWZlQXJlYVJlY3QgPSB7XG4gICAgICB4OiA0NCwgLyogMCArIDQ0IChsZWZ0IHNhZmUgYXJlYSkgKi9cbiAgICAgIHk6IDAsXG4gICAgICB3aWR0aDogd2luZG93LmlubmVyV2lkdGggLSA4OCwgLyogd2lkdGggLSA0NCAobGVmdCBzYWZlIGFyZWEpIC0gMzQgKHJpZ2h0IHNhZmUgYXJlYSkgKi9cbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0IC0gMjEgLyogaGVpZ2h0IC0gMjEgKGJvdHRvbSBzYWZlIGFyZWEpICovXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBzYWZlQXJlYVJlY3QgPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIHdpZHRoOiB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4uc2FmZUFyZWFSZWN0LFxuICAgIGxlZnQ6IHNhZmVBcmVhUmVjdC54LFxuICAgIHRvcDogc2FmZUFyZWFSZWN0LnksXG4gICAgcmlnaHQ6IHNhZmVBcmVhUmVjdC54ICsgc2FmZUFyZWFSZWN0LndpZHRoLFxuICAgIGJvdHRvbTogc2FmZUFyZWFSZWN0LnkgKyBzYWZlQXJlYVJlY3QuaGVpZ2h0XG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGlQaG9uZVhQYXRjaDtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5pbXBvcnQgQmFzZUFuaW1hdG9yIGZyb20gJy4uLy4uL29ucy9iYXNlLWFuaW1hdG9yJ1xuaW1wb3J0IGlQaG9uZVhQYXRjaCBmcm9tICcuLi8uLi9vbnMvaXBob25leC1wYXRjaCc7XG5cbmV4cG9ydCBjbGFzcyBBY3Rpb25TaGVldEFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIHNob3coZGlhbG9nLCBkb25lKSB7XG4gICAgZG9uZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBoaWRlKGRpYWxvZywgZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxufVxuXG4vKipcbiAqIEFuZHJvaWQgc3R5bGUgYW5pbWF0b3IgZm9yIEFjdGlvbiBTaGVldC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1EQWN0aW9uU2hlZXRBbmltYXRvciBleHRlbmRzIEFjdGlvblNoZWV0QW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHsgdGltaW5nID0gJ2Vhc2UnLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40IH0gPSB7fSkge1xuICAgIHN1cGVyKHt0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbn0pO1xuXG4gICAgdGhpcy5tYXNrVGltaW5nID0gJ2xpbmVhcic7XG4gICAgdGhpcy5tYXNrRHVyYXRpb24gPSAwLjI7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaylcbiAgICAgICAgLnF1ZXVlKHsgb3BhY2l0eTogMCB9KVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoeyBvcGFjaXR5OiAxLjAgfSwge1xuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLm1hc2tEdXJhdGlvbixcbiAgICAgICAgICB0aW1pbmc6IHRoaXMubWFza1RpbWluZ1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fc2hlZXQsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDAsIDgwJSwgMClgLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2spXG4gICAgICAgIC5xdWV1ZSh7IG9wYWNpdHk6IDEgfSlcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHsgb3BhY2l0eTogMCB9LCB7XG4gICAgICAgICAgZHVyYXRpb246IHRoaXMubWFza0R1cmF0aW9uLFxuICAgICAgICAgIHRpbWluZzogdGhpcy5tYXNrVGltaW5nXG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9zaGVldCwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiAxIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCA4MCUsIDApYCwgb3BhY2l0eTogMCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBpT1Mgc3R5bGUgYW5pbWF0b3IgZm9yIGRpYWxvZy5cbiAqL1xuZXhwb3J0IGNsYXNzIElPU0FjdGlvblNoZWV0QW5pbWF0b3IgZXh0ZW5kcyBBY3Rpb25TaGVldEFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7IHRpbWluZyA9ICdlYXNlJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuMyB9ID0ge30pIHtcbiAgICBzdXBlcih7dGltaW5nLCBkZWxheSwgZHVyYXRpb259KTtcblxuICAgIHRoaXMubWFza1RpbWluZyA9ICdsaW5lYXInO1xuICAgIHRoaXMubWFza0R1cmF0aW9uID0gMC4yO1xuICAgIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYUG9ydHJhaXRQYXRjaEFjdGl2ZSgpKSB7XG4gICAgICB0aGlzLmxpZnRBbW91bnQgPSAnY2FsYygxMDAlICsgNDhweCknO1xuICAgIH0gZWxzZSBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWExhbmRzY2FwZVBhdGNoQWN0aXZlKCkpIHtcbiAgICAgIHRoaXMubGlmdEFtb3VudCA9ICdjYWxjKDEwMCUgKyAzM3B4KSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGlmdEFtb3VudCA9IGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0IC8gMi4wIC0gMSArICdweCc7IC8vIGF2b2lkIEZvcmNlZCBTeW5jaHJvbm91cyBMYXlvdXRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaylcbiAgICAgIC5xdWV1ZSh7IG9wYWNpdHk6IDAgfSlcbiAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAucXVldWUoeyBvcGFjaXR5OiAxIH0sIHtcbiAgICAgICAgZHVyYXRpb246IHRoaXMubWFza0R1cmF0aW9uLFxuICAgICAgICB0aW1pbmc6IHRoaXMubWFza1RpbWluZ1xuICAgICAgfSksXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX3NoZWV0LCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMubGlmdEFtb3VudH0sIDApYCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKGRpYWxvZywgY2FsbGJhY2spIHtcbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrKVxuICAgICAgLnF1ZXVlKHsgb3BhY2l0eTogMSB9KVxuICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgIC5xdWV1ZSh7IG9wYWNpdHk6IDAgfSwge1xuICAgICAgICBkdXJhdGlvbjogdGhpcy5tYXNrRHVyYXRpb24sXG4gICAgICAgIHRpbWluZzogdGhpcy5tYXNrVGltaW5nXG4gICAgICB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fc2hlZXQsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmxpZnRBbW91bnR9LCAwKWAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9hbmltYXRvci1mYWN0b3J5JztcbmltcG9ydCBEb29yTG9jayBmcm9tICcuLi8uLi9vbnMvZG9vcmxvY2snO1xuaW1wb3J0IGRldmljZUJhY2tCdXR0b25EaXNwYXRjaGVyIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9kZXZpY2UtYmFjay1idXR0b24tZGlzcGF0Y2hlcic7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmFzZURpYWxvZ0VsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgdXRpbC50aHJvd01lbWJlcigpO1xuICB9XG5cbiAgX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBfdG9nZ2xlU3R5bGUoc2hvdWxkU2hvdykge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHNob3VsZFNob3cgPyAnYmxvY2snIDogJ25vbmUnO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlRGlhbG9nRWxlbWVudCkge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgdGhpcy5fdmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuX2Rvb3JMb2NrID0gbmV3IERvb3JMb2NrKCk7XG4gICAgdGhpcy5fY2FuY2VsID0gdGhpcy5fY2FuY2VsLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fc2VsZkNhbWVsTmFtZSA9IHV0aWwuY2FtZWxpemUodGhpcy50YWdOYW1lLnNsaWNlKDQpKTtcbiAgICB0aGlzLl9kZWZhdWx0REJCID0gZSA9PiB0aGlzLmNhbmNlbGFibGUgPyB0aGlzLl9jYW5jZWwoKSA6IGUuY2FsbFBhcmVudEhhbmRsZXIoKTtcbiAgICB0aGlzLl9hbmltYXRvckZhY3RvcnkgPSB0aGlzLl91cGRhdGVBbmltYXRvckZhY3RvcnkoKTtcbiAgfVxuXG4gIGdldCBvbkRldmljZUJhY2tCdXR0b24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyO1xuICB9XG5cbiAgc2V0IG9uRGV2aWNlQmFja0J1dHRvbihjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLl9iYWNrQnV0dG9uSGFuZGxlcikge1xuICAgICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIuZGVzdHJveSgpO1xuICAgIH1cblxuICAgIHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyID0gZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIuY3JlYXRlSGFuZGxlcih0aGlzLCBjYWxsYmFjayk7XG4gIH1cblxuICBfY2FuY2VsKCkge1xuICAgIGlmICh0aGlzLmNhbmNlbGFibGUgJiYgIXRoaXMuX3J1bm5pbmcpIHtcbiAgICAgIHRoaXMuX3J1bm5pbmcgPSB0cnVlO1xuICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgLnRoZW4oXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcnVubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdkaWFsb2ctY2FuY2VsJyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoKSA9PiB0aGlzLl9ydW5uaW5nID0gZmFsc2VcbiAgICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBzaG93KC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gdGhpcy5fc2V0VmlzaWJsZSh0cnVlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGhpZGUoLi4uYXJncykge1xuICAgIHJldHVybiB0aGlzLl9zZXRWaXNpYmxlKGZhbHNlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIHRvZ2dsZSguLi5hcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NldFZpc2libGUoIXRoaXMudmlzaWJsZSwgLi4uYXJncyk7XG4gIH1cblxuICBfc2V0VmlzaWJsZShzaG91bGRTaG93LCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBhY3Rpb24gPSBzaG91bGRTaG93ID8gJ3Nob3cnIDogJ2hpZGUnO1xuXG4gICAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9O1xuICAgIG9wdGlvbnMuYW5pbWF0aW9uT3B0aW9ucyA9IHV0aWwuZXh0ZW5kKFxuICAgICAgb3B0aW9ucy5hbmltYXRpb25PcHRpb25zIHx8IHt9LFxuICAgICAgQW5pbWF0b3JGYWN0b3J5LnBhcnNlQW5pbWF0aW9uT3B0aW9uc1N0cmluZyh0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uLW9wdGlvbnMnKSlcbiAgICApO1xuXG4gICAgbGV0IGNhbmNlbGVkID0gZmFsc2U7XG4gICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsIGBwcmUke2FjdGlvbn1gLCB7IC8vIHByZXNob3cgcHJlaGlkZVxuICAgICAgW3RoaXMuX3NlbGZDYW1lbE5hbWVdOiB0aGlzLFxuICAgICAgY2FuY2VsOiAoKSA9PiBjYW5jZWxlZCA9IHRydWVcbiAgICB9KTtcblxuICAgIGlmIChjYW5jZWxlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGBDYW5jZWxlZCBpbiBwcmUke2FjdGlvbn0gZXZlbnQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgdGhpcy5fZG9vckxvY2sud2FpdFVubG9jaygoKSA9PiB7XG4gICAgICAgIGNvbnN0IHVubG9jayA9IHRoaXMuX2Rvb3JMb2NrLmxvY2soKTtcbiAgICAgICAgY29uc3QgYW5pbWF0b3IgPSB0aGlzLl9hbmltYXRvckZhY3RvcnkubmV3QW5pbWF0b3Iob3B0aW9ucyk7XG5cbiAgICAgICAgc2hvdWxkU2hvdyAmJiB0aGlzLl90b2dnbGVTdHlsZSh0cnVlLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5fdmlzaWJsZSA9IHNob3VsZFNob3c7XG4gICAgICAgIHV0aWwuaW9zUGFnZVNjcm9sbEZpeChzaG91bGRTaG93KTtcblxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgIGFuaW1hdG9yW2FjdGlvbl0odGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgIXNob3VsZFNob3cgJiYgdGhpcy5fdG9nZ2xlU3R5bGUoZmFsc2UsIG9wdGlvbnMpO1xuXG4gICAgICAgICAgICB1bmxvY2soKTtcblxuICAgICAgICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ18nICsgYWN0aW9uKTtcbiAgICAgICAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncG9zdCcgKyBhY3Rpb24sIHtbdGhpcy5fc2VsZkNhbWVsTmFtZV06IHRoaXN9KTsgLy8gcG9zdHNob3cgcG9zdGhpZGVcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgICBvcHRpb25zLmNhbGxiYWNrKHRoaXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXNvbHZlKHRoaXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgdmlzaWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fdmlzaWJsZTtcbiAgfVxuXG4gIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuICAgIHJldHVybiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZSh0aGlzLCAnZGlzYWJsZWQnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgZGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICB9XG5cbiAgc2V0IGNhbmNlbGFibGUodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2NhbmNlbGFibGUnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgY2FuY2VsYWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2NhbmNlbGFibGUnKTtcbiAgfVxuXG4gIF91cGRhdGVNYXNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fbWFzayAmJiB0aGlzLmdldEF0dHJpYnV0ZSgnbWFzay1jb2xvcicpKSB7XG4gICAgICAgIHRoaXMuX21hc2suc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ21hc2stY29sb3InKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fZGVmYXVsdERCQiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5vbkRldmljZUJhY2tCdXR0b24gPSB0aGlzLl9kZWZhdWx0REJCLmJpbmQodGhpcyk7XG4gICAgfVxuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9tYXNrKSB7XG4gICAgICAgIHRoaXMuX21hc2suYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9jYW5jZWwsIGZhbHNlKTtcbiAgICAgICAgdXRpbC5pb3NNYXNrU2Nyb2xsRml4KHRoaXMuX21hc2ssIHRydWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgaWYgKHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX21hc2spIHtcbiAgICAgIHRoaXMuX21hc2sucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9jYW5jZWwsIGZhbHNlKTtcbiAgICAgIHV0aWwuaW9zTWFza1Njcm9sbEZpeCh0aGlzLl9tYXNrLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnYW5pbWF0aW9uJywgJ21hc2stY29sb3InXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2FuaW1hdGlvbic6XG4gICAgICAgIHRoaXMuX2FuaW1hdG9yRmFjdG9yeSA9IHRoaXMuX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21hc2stY29sb3InOlxuICAgICAgICB0aGlzLl91cGRhdGVNYXNrKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ3ByZXNob3cnLCAncG9zdHNob3cnLCAncHJlaGlkZScsICdwb3N0aGlkZScsICdkaWFsb2ctY2FuY2VsJ107XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi8uLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi8uLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgeyBBY3Rpb25TaGVldEFuaW1hdG9yLCBJT1NBY3Rpb25TaGVldEFuaW1hdG9yLCBNREFjdGlvblNoZWV0QW5pbWF0b3IgfSBmcm9tICcuL2FuaW1hdG9yJztcbmltcG9ydCBwbGF0Zm9ybSBmcm9tICcuLi8uLi9vbnMvcGxhdGZvcm0nO1xuaW1wb3J0IEJhc2VEaWFsb2dFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1kaWFsb2cnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5hY3Rpb24tc2hlZXQnOiAnYWN0aW9uLXNoZWV0LS0qJyxcbiAgJy5hY3Rpb24tc2hlZXQtbWFzayc6ICdhY3Rpb24tc2hlZXQtbWFzay0tKicsXG4gICcuYWN0aW9uLXNoZWV0LXRpdGxlJzogJ2FjdGlvbi1zaGVldC10aXRsZS0tKidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdkZWZhdWx0JzogKCkgPT4gcGxhdGZvcm0uaXNBbmRyb2lkKCkgPyBNREFjdGlvblNoZWV0QW5pbWF0b3IgOiBJT1NBY3Rpb25TaGVldEFuaW1hdG9yLFxuICAnbm9uZSc6IEFjdGlvblNoZWV0QW5pbWF0b3Jcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWFjdGlvbi1zaGVldFxuICogQGNhdGVnb3J5IGRpYWxvZ1xuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBBY3Rpb24vYm90dG9tIHNoZWV0IHRoYXQgaXMgZGlzcGxheWVkIG9uIHRvcCBvZiBjdXJyZW50IHNjcmVlbi5cbiAqXG4gKiAgICAgVGhpcyBlbGVtZW50IGNhbiBlaXRoZXIgYmUgYXR0YWNoZWQgZGlyZWN0bHkgdG8gdGhlIGA8Ym9keT5gIG9yIGR5bmFtaWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHRlbXBsYXRlIHVzaW5nIHRoZSBgb25zLmNyZWF0ZUVsZW1lbnQodGVtcGxhdGUsIHsgYXBwZW5kOiB0cnVlIH0pYCB1dGlsaXR5IGZ1bmN0aW9uIGFuZCB0aGUgYDx0ZW1wbGF0ZT5gIHRhZy5cbiAqXG4gKiAgICAgVGhlIGFjdGlvbiBzaGVldCBpcyB1c2VmdWwgZm9yIGRpc3BsYXlpbmcgYSBsaXN0IG9mIG9wdGlvbnMgYW5kIGFza2luZyB0aGUgdXNlciB0byBtYWtlIGEgZGVjaXNpb24uIEEgYG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uYCBpcyBwcm92aWRlZCBmb3IgdGhpcyBwdXJwb3NlLCBhbHRob3VnaCBpdCBjYW4gY29udGFpbiBhbnkgdHlwZSBvZiBjb250ZW50LlxuICpcbiAqICAgICBJdCB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZGlzcGxheWVkIGFzIE1hdGVyaWFsIERlc2lnbiAoYm90dG9tIHNoZWV0KSB3aGVuIHJ1bm5pbmcgb24gYW4gQW5kcm9pZCBkZXZpY2UuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICDjgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjgIHjgoLjgZfjgY/jga/jg5zjg4jjg6Djgrfjg7zjg4jjgpLnj77lnKjjga7jgrnjgq/jg6rjg7zjg7PkuIrjgavooajnpLrjgZfjgb7jgZnjgIJcbiAqXG4gKiAgICAg44GT44Gu6KaB57Sg44Gv44CBYDxib2R5PmDopoHntKDjgavnm7TmjqXjgqLjgr/jg4Pjg4HjgZXjgozjgovjgYvjgIHjgoLjgZfjgY/jga9gb25zLmNyZWF0ZUVsZW1lbnQodGVtcGxhdGUsIHsgYXBwZW5kOiB0cnVlIH0pYOOBqGA8dGVtcGxhdGU+YOOCv+OCsOOCkuS9v+OBo+OBpuODhuODs+ODl+ODrOODvOODiOOBi+OCieWLleeahOOBq+eUn+aIkOOBleOCjOOBvuOBmeOAglxuICpcbiAqICAgICDjgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjga/jgIHpgbjmip7ogqLjga7jg6rjgrnjg4jjgpLooajnpLrjgZfjgabjg6bjg7zjgrbjg7zjgavlsIvjga3jgovjga7jgavkvr/liKnjgafjgZnjgIJgb25zLWFjdGlvbi1zaGVldC1idXR0b25g44Gv44CB44GT44Gu6KaB57Sg44Gu5Lit44Gr572u44GP44Gf44KB44Gr5o+Q5L6b44GV44KM44Gm44GE44G+44GZ44GM44CB44Gd44KM5Lul5aSW44Gr44KC5LuW44Gu44Gp44Gu44KI44GG44Gq6KaB57Sg44KS5ZCr44KA44GT44Go44GM44Gn44GN44G+44GZ44CCXG4gKlxuICogICAgIEFuZHJvaWTjg4fjg5DjgqTjgrnjgaflrp/ooYzjgZXjgozjgovjgajjgY3jgavjga/jgIHoh6rli5XnmoTjgavjg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Mo44Oc44OI44Og44K344O844OIKeOBqOOBl+OBpuihqOekuuOBleOCjOOBvuOBmeOAglxuICogICBbL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIGJvdHRvbSBzaGVldC5bL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44Oc44OI44Og44K344O844OI44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL3JlZmVyZW5jZS9hY3Rpb24tc2hlZXRcbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQHNlZWFsc28gb25zLXBvcG92ZXJcbiAqICAgW2VuXWA8b25zLXBvcG92ZXI+YCBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLXBvcG92ZXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLW1vZGFsXG4gKiAgIFtlbl1gPG9ucy1tb2RhbD5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbW9kYWzjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtYWN0aW9uLXNoZWV0IGlkPVwic2hlZXRcIj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqIDwvb25zLWFjdGlvbi1zaGVldD5cbiAqXG4gKiA8c2NyaXB0PlxuICogICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hlZXQnKS5zaG93KCk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWN0aW9uU2hlZXRFbGVtZW50IGV4dGVuZHMgQmFzZURpYWxvZ0VsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBhY3Rpb24gc2hlZXQgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozjgovnm7TliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuYWN0aW9uU2hlZXRcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC5jYW5jZWxcbiAgICogICBbZW5dRXhlY3V0ZSB0aGlzIGZ1bmN0aW9uIHRvIHN0b3AgdGhlIGFjdGlvbiBzaGVldCBmcm9tIGJlaW5nIHNob3duLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWun+ihjOOBmeOCi+OBqOOAgeODgOOCpOOCouODreOCsOOBruihqOekuuOBjOOCreODo+ODs+OCu+ODq+OBleOCjOOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdHNob3dcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBhY3Rpb24gc2hlZXQgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozjgZ/nm7TlvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuYWN0aW9uU2hlZXRcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZWhpZGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGJlZm9yZSB0aGUgYWN0aW9uIHNoZWV0IGlzIGhpZGRlbi5bL2VuXVxuICAgKiBbamFd44OA44Kk44Ki44Ot44Kw44GM6Zqg44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmFjdGlvblNoZWV0XG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBhY3Rpb24gc2hlZXQgZnJvbSBiZWluZyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5a6f6KGM44GZ44KL44Go44CB44OA44Kk44Ki44Ot44Kw44Gu6Z2e6KGo56S644GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0aGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIGFjdGlvbiBzaGVldCBpcyBoaWRkZW4uWy9lbl1cbiAgICogW2phXeODgOOCpOOCouODreOCsOOBjOmaoOOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5hY3Rpb25TaGVldFxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHRpdGxlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXU9wdGlvbmFsIHRpdGxlIG9mIHRoZSBhY3Rpb24gc2hlZXQuIEEgbmV3IGVsZW1lbnQgd2lsbCBiZSBjcmVhdGVkIGNvbnRhaW5pbmcgdGhpcyBzdHJpbmcuWy9lbl1cbiAgICogIFtqYV3jgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjga7jgr/jgqTjg4jjg6vjgpLmjIflrprjgZfjgb7jgZnjgILjgZPjgZPjgafmjIflrprjgZfjgZ/mloflrZfliJfjgpLlkKvjgoDmlrDjgZfjgYTopoHntKDjgYzkvZzmiJDjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgYWN0aW9uIHNoZWV0LlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgY2FuY2VsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGFjdGlvbiBzaGVldCBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OBjOioreWumuOBleOCjOOCi+OBqOOAgeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBruiDjOaZr+OChEFuZHJvaWTjg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7PjgpLmjqjjgZnjgZPjgajjgafjgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jjgYzplonjgZjjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGFjdGlvbiBzaGVldCBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeODgOOCpOOCouODreOCsOOBr2Rpc2FibGVk54q25oWL44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBhY3Rpb24gc2hlZXQuIENhbiBiZSBlaXRoZXIgYFwibm9uZVwiYCBvciBgXCJkZWZhdWx0XCJgLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GZ44KL6Zqb44Gu44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJub25lXCLjgoLjgZfjgY/jga9cImRlZmF1bHRcIuOCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFuaW1hdGlvbi1vcHRpb25zXG4gICAqIEB0eXBlIHtFeHByZXNzaW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgdGltaW5nIGFuZCBkZWxheSB3aXRoIGFuIG9iamVjdCBsaXRlcmFsLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgdGltaW5nLCBkZWxheeOCkuOCquODluOCuOOCp+OCr+ODiOODquODhuODqeODq+OBp+aMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1hc2stY29sb3JcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlZmF1bHQgcmdiYSgwLCAwLCAwLCAwLjIpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kIG1hc2suIERlZmF1bHQgaXMgYFwicmdiYSgwLCAwLCAwLCAwLjIpXCJgLlsvZW5dXG4gICAqICBbamFd6IOM5pmv44Gu44Oe44K544Kv44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CCXCJyZ2JhKDAsIDAsIDAsIDAuMilcIuOBjOODh+ODleOCqeODq+ODiOWApOOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBnZXQgX21hc2soKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcuYWN0aW9uLXNoZWV0LW1hc2snKTtcbiAgfVxuXG4gIGdldCBfc2hlZXQoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcuYWN0aW9uLXNoZWV0Jyk7XG4gIH1cblxuICBnZXQgX3RpdGxlKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJy5hY3Rpb24tc2hlZXQtdGl0bGUnKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBBY3Rpb25TaGVldEFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ0FjdGlvblNoZWV0QW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAxO1xuXG4gICAgLyogRXhwZWN0ZWQgcmVzdWx0OlxuICAgICAqICAgPG9ucy1hY3Rpb24tc2hlZXQ+XG4gICAgICogICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tc2hlZXQtbWFza1wiPjwvZGl2PlxuICAgICAqICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLXNoZWV0XCI+XG4gICAgICogICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1zaGVldC10aXRsZT48L2Rpdj5cbiAgICAgKiAgICAgICAuLi5cbiAgICAgKiAgICAgPC9kaXY+XG4gICAgICogICA8L29ucy1hY3Rpb24tc2hlZXQ+XG4gICAgICovXG5cbiAgICBpZiAoIXRoaXMuX3NoZWV0KSB7XG4gICAgICBjb25zdCBzaGVldCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgc2hlZXQuY2xhc3NMaXN0LmFkZCgnYWN0aW9uLXNoZWV0Jyk7XG5cbiAgICAgIHdoaWxlICh0aGlzLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgc2hlZXQuYXBwZW5kQ2hpbGQodGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZChzaGVldCk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl90aXRsZSAmJiB0aGlzLmhhc0F0dHJpYnV0ZSgndGl0bGUnKSkge1xuICAgICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHRpdGxlLmlubmVySFRNTCA9IHRoaXMuZ2V0QXR0cmlidXRlKCd0aXRsZScpO1xuICAgICAgdGl0bGUuY2xhc3NMaXN0LmFkZCgnYWN0aW9uLXNoZWV0LXRpdGxlJyk7XG4gICAgICB0aGlzLl9zaGVldC5pbnNlcnRCZWZvcmUodGl0bGUsIHRoaXMuX3NoZWV0LmZpcnN0Q2hpbGQpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fbWFzaykge1xuICAgICAgY29uc3QgbWFzayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgbWFzay5jbGFzc0xpc3QuYWRkKCdhY3Rpb24tc2hlZXQtbWFzaycpO1xuICAgICAgdGhpcy5pbnNlcnRCZWZvcmUobWFzaywgdGhpcy5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zaGVldC5zdHlsZS56SW5kZXggPSAyMDAwMTtcbiAgICB0aGlzLl9tYXNrLnN0eWxlLnpJbmRleCA9IDIwMDAwO1xuXG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICB9XG5cbiAgX3VwZGF0ZVRpdGxlKCkge1xuICAgIGlmICh0aGlzLl90aXRsZSkge1xuICAgICAgdGhpcy5fdGl0bGUuaW5uZXJIVE1MID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3RpdGxlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkRldmljZUJhY2tCdXR0b25cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJhY2stYnV0dG9uIGhhbmRsZXIuWy9lbl1cbiAgICogICBbamFd44OQ44OD44Kv44Oc44K/44Oz44OP44Oz44OJ44Op44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2hvd1xuICAgKiBAc2lnbmF0dXJlIHNob3coW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJub25lXCJgIGFuZCBgXCJzbGlkZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJzbGlkZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1UaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgYWN0aW9uIHNoZWV0IGhhcyBiZWVuIHJldmVhbGVkLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOBjOihqOekuuOBleOCjOe1guOCj+OBo+OBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNob3cgdGhlIGFjdGlvbiBzaGVldC5bL2VuXVxuICAgKiAgW2phXeODgOOCpOOCouODreOCsOOCkumWi+OBjeOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IFJlc29sdmVzIHRvIHRoZSBkaXNwbGF5ZWQgZWxlbWVudC5cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJub25lXCJgIGFuZCBgXCJzbGlkZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJzbGlkZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb25zIGlzIGNhbGxlZCBhZnRlciB0aGUgYWN0aW9uIHNoZWV0IGhhcyBiZWVuIGhpZGRlbi5bL2VuXVxuICAgKiAgIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzpmqDjgozjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSGlkZSB0aGUgYWN0aW9uIHNoZWV0LlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOCkumWieOBmOOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXemaoOOCjOOBn+imgee0oOOCkuino+axuuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmlzaWJsZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBhY3Rpb24gc2hlZXQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGFjdGlvbiBzaGVldCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjYW5jZWxhYmxlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgYWN0aW9uIHNoZWV0IGlzIGNhbmNlbGFibGUgb3Igbm90LiBBIGNhbmNlbGFibGUgYWN0aW9uIHNoZWV0IGNhbiBiZSBjbG9zZWQgYnkgdGFwcGluZyB0aGUgYmFja2dyb3VuZCBvciBieSBwcmVzc2luZyB0aGUgYmFjayBidXR0b24gb24gQW5kcm9pZCBkZXZpY2VzLlsvZW5dXG4gICAqICAgW2phXeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBjOOCreODo+ODs+OCu+ODq+WPr+iDveOBi+OBqeOBhuOBi+OCkuioreWumuOBl+OBvuOBmeOAguOCreODo+ODs+OCu+ODq+WPr+iDveOBquOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBr+OAgeiDjOaZr+OCkuOCv+ODg+ODl+OBl+OBn+OCikFuZHJvaWTjg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7PjgpLmjqjjgZnjgZPjgajjgafplonjgZjjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWy4uLnN1cGVyLm9ic2VydmVkQXR0cmlidXRlcywgJ3RpdGxlJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIGlmIChuYW1lID09PSAndGl0bGUnKSB7XG4gICAgICB0aGlzLl91cGRhdGVUaXRsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7QWN0aW9uU2hlZXRBbmltYXRvcn0gQW5pbWF0b3JcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlckFuaW1hdG9yKG5hbWUsIEFuaW1hdG9yKSB7XG4gICAgaWYgKCEoQW5pbWF0b3IucHJvdG90eXBlIGluc3RhbmNlb2YgQWN0aW9uU2hlZXRBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignQWN0aW9uU2hlZXQnKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IEFjdGlvblNoZWV0QW5pbWF0b3IoKSB7XG4gICAgcmV0dXJuIEFjdGlvblNoZWV0QW5pbWF0b3I7XG4gIH1cbn1cblxub25zRWxlbWVudHMuQWN0aW9uU2hlZXQgPSBBY3Rpb25TaGVldEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1hY3Rpb24tc2hlZXQnLCBBY3Rpb25TaGVldEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UtZWxlbWVudCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gW3RoaXNdO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlQnV0dG9uRWxlbWVudCkge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX2NvbXBpbGUoKSk7XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxuXG4gIGdldCBfaWNvbigpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1pY29uJyk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuY2xhc3NMaXN0LmFkZCh0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lKTtcblxuICAgIGlmICghdGhpcy5faWNvbiAmJiB0aGlzLmhhc0F0dHJpYnV0ZSgnaWNvbicpKSB7XG4gICAgICB1dGlsLmNoZWNrTWlzc2luZ0ltcG9ydCgnSWNvbicpO1xuICAgICAgY29uc3QgaWNvbiA9IHV0aWwuY3JlYXRlRWxlbWVudChgPG9ucy1pY29uIGljb249XCIke3RoaXMuZ2V0QXR0cmlidXRlKCdpY29uJyl9XCI+PC9vbnMtaWNvbj5gKTtcbiAgICAgIGljb24uY2xhc3NMaXN0LmFkZCh0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lLnJlcGxhY2UoJ2J1dHRvbicsICdpY29uJykpO1xuICAgICAgdGhpcy5pbnNlcnRCZWZvcmUoaWNvbiwgdGhpcy5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVSaXBwbGUoKTtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgdGhpcy5fc2NoZW1lKTtcbiAgfVxuXG4gIF91cGRhdGVJY29uKCkge1xuICAgIGlmICh0aGlzLl9pY29uKSB7XG4gICAgICB0aGlzLl9pY29uLnNldEF0dHJpYnV0ZSgnaWNvbicsIHRoaXMuZ2V0QXR0cmlidXRlKCdpY29uJykpO1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVSaXBwbGUoKSB7XG4gICAgdGhpcy5fcmlwcGxlT3B0ICYmIHV0aWwudXBkYXRlUmlwcGxlKC4uLnRoaXMuX3JpcHBsZU9wdCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdjbGFzcycsICdpY29uJywgJ3JpcHBsZSddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgdGhpcy5fZGVmYXVsdENsYXNzTmFtZSwgdGhpcy5fc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ljb24nOlxuICAgICAgICB0aGlzLl91cGRhdGVJY29uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlwcGxlJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuY29udGFpbnModGhpcy5fZGVmYXVsdENsYXNzTmFtZSkgJiYgdGhpcy5fdXBkYXRlUmlwcGxlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUJ1dHRvbkVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtYnV0dG9uJztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtYWN0aW9uLXNoZWV0LWJ1dHRvblxuICogQGNhdGVnb3J5IGRpYWxvZ1xuICogQG1vZGlmaWVyIGRlc3RydWN0aXZlXG4gKiAgIFtlbl1TaG93cyBhIFwiZGVzdHJ1Y3RpdmVcIiBidXR0b24gKG9ubHkgZm9yIGlPUykuWy9lbl1cbiAqICAgW2phXVwiZGVzdHJ1Y3RpdmVcIuOBquODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmShpT1Pjgafjga7jgb/mnInlirkp44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dQ29tcG9uZW50IHRoYXQgcmVwcmVzZW50IGVhY2ggYnV0dG9uIG9mIHRoZSBhY3Rpb24gc2hlZXQuWy9lbl1cbiAqICAgW2phXeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOOBq+ihqOekuuOBleOCjOOCi+WQhOODnOOCv+ODs+OCkuihqOePvuOBmeOCi+OCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAglsvamFdXG4gKiBAc2VlYWxzbyBvbnMtYWN0aW9uLXNoZWV0XG4gKiAgIFtlbl1UaGUgYDxvbnMtYWN0aW9uLXNoZWV0PmAgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1hY3Rpb24tc2hlZXTjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLWxpc3QtaXRlbVxuICogICBbZW5dVGhlIGA8b25zLWxpc3QtaXRlbT5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1pdGVt44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1pY29uXG4gKiAgIFtlbl1UaGUgYDxvbnMtaWNvbj5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtaWNvbuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvYWN0aW9uLXNoZWV0XG4gKiBAZ3VpZGUgYXBwc2l6ZS5odG1sI3JlbW92aW5nLWljb24tcGFja3MgW2VuXVJlbW92aW5nIGljb24gcGFja3MuWy9lbl1bamFdWy9qYV1cbiAqIEBndWlkZSBmYXEuaHRtbCNob3ctY2FuLWktdXNlLWN1c3RvbS1pY29uLXBhY2tzIFtlbl1BZGRpbmcgY3VzdG9tIGljb24gcGFja3MuWy9lbl1bamFdWy9qYV1cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dRGlzcGxheSBhIE1hdGVyaWFsIERlc2lnbiBhY3Rpb24gc2hlZXQgYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV3jg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Pjga7jgqLjgq/jgrfjg6fjg7Pjgrfjg7zjg4jnlKjjga7jg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtYWN0aW9uLXNoZWV0IGlkPVwic2hlZXRcIj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqICAgPG9ucy1hY3Rpb24tc2hlZXQtYnV0dG9uPkxhYmVsPC9vbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbj5cbiAqIDwvb25zLWFjdGlvbi1zaGVldD5cbiAqXG4gKiA8c2NyaXB0PlxuICogICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2hlZXQnKS5zaG93KCk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWN0aW9uU2hlZXRCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUJ1dHRvbkVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGljb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ3JlYXRlcyBhbiBgb25zLWljb25gIGNvbXBvbmVudCB3aXRoIHRoaXMgc3RyaW5nLiBPbmx5IHZpc2libGUgb24gQW5kcm9pZC4gQ2hlY2sgW1NlZSBhbHNvXSgjc2VlYWxzbykgc2VjdGlvbiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5bL2VuXVxuICAgKiAgW2phXWBvbnMtaWNvbmDjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgpLmgqrmgKfjgZfjgb7jgZnjgIJBbmRyb2lk44Gn44Gu44G/6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBhY3Rpb24gc2hlZXQgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXeOCouOCr+OCt+ODp+ODs+OCt+ODvOODiOODnOOCv+ODs+OBruimi+OBn+ebruOCkuioreWumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnJzogJ2FjdGlvbi1zaGVldC1idXR0b24tLSonLFxuICAgICAgJy5hY3Rpb24tc2hlZXQtaWNvbic6ICdhY3Rpb24tc2hlZXQtaWNvbi0tKidcbiAgICB9O1xuICB9XG5cbiAgZ2V0IF9kZWZhdWx0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnYWN0aW9uLXNoZWV0LWJ1dHRvbic7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkFjdGlvblNoZWV0QnV0dG9uID0gQWN0aW9uU2hlZXRCdXR0b25FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYWN0aW9uLXNoZWV0LWJ1dHRvbicsIEFjdGlvblNoZWV0QnV0dG9uRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IEJhc2VBbmltYXRvciBmcm9tICcuLi8uLi9vbnMvYmFzZS1hbmltYXRvcic7XG5cbmV4cG9ydCBjbGFzcyBBbGVydERpYWxvZ0FuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBzaG93KGRpYWxvZywgZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZG9uZVxuICAgKi9cbiAgaGlkZShkaWFsb2csIGRvbmUpIHtcbiAgICBkb25lKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbmRyb2lkIHN0eWxlIGFuaW1hdG9yIGZvciBhbGVydCBkaWFsb2cuXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmRyb2lkQWxlcnREaWFsb2dBbmltYXRvciBleHRlbmRzIEFsZXJ0RGlhbG9nQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZHVyYXRpb24gPSAwLjIsIGRlbGF5ID0gMH0gPSB7fSkge1xuICAgIHN1cGVyKHtkdXJhdGlvbiwgdGltaW5nLCBkZWxheX0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHNob3coZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAwIH0sIHsgb3BhY2l0eTogMSB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSBzY2FsZTNkKC45LCAuOSwgMSknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSBzY2FsZTNkKDEsIDEsIDEpJywgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgaGlkZShkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2ssIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9kaWFsb2csIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC01MCUsIC01MCUsIDApIHNjYWxlM2QoMSwgMSwgMSknLCBvcGFjaXR5OiAxIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKSBzY2FsZTNkKC45LCAuOSwgMSknLCBvcGFjaXR5OiAwIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIGlPUyBzdHlsZSBhbmltYXRvciBmb3IgYWxlcnQgZGlhbG9nLlxuICovXG5leHBvcnQgY2xhc3MgSU9TQWxlcnREaWFsb2dBbmltYXRvciBleHRlbmRzIEFsZXJ0RGlhbG9nQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZHVyYXRpb24gPSAwLjIsIGRlbGF5ID0gMH0gPSB7fSkge1xuICAgIHN1cGVyKHtkdXJhdGlvbiwgdGltaW5nLCBkZWxheX0pO1xuICB9XG5cbiAgLypcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2ssIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9kaWFsb2csIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC01MCUsIC01MCUsIDApIHNjYWxlM2QoMS4zLCAxLjMsIDEpJywgb3BhY2l0eTogMCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCkgc2NhbGUzZCgxLCAxLCAxKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9hbmltYXRvci1mYWN0b3J5JztcbmltcG9ydCB7IEFsZXJ0RGlhbG9nQW5pbWF0b3IsIElPU0FsZXJ0RGlhbG9nQW5pbWF0b3IsIEFuZHJvaWRBbGVydERpYWxvZ0FuaW1hdG9yIH0gZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcuYWxlcnQtZGlhbG9nJzogJ2FsZXJ0LWRpYWxvZy0tKicsXG4gICcuYWxlcnQtZGlhbG9nLWNvbnRhaW5lcic6ICdhbGVydC1kaWFsb2ctY29udGFpbmVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctdGl0bGUnOiAnYWxlcnQtZGlhbG9nLXRpdGxlLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctY29udGVudCc6ICdhbGVydC1kaWFsb2ctY29udGVudC0tKicsXG4gICcuYWxlcnQtZGlhbG9nLWZvb3Rlcic6ICdhbGVydC1kaWFsb2ctZm9vdGVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctZm9vdGVyLS1yb3dmb290ZXInOiAnYWxlcnQtZGlhbG9nLWZvb3Rlci0tcm93Zm9vdGVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctYnV0dG9uLS1yb3dmb290ZXInOiAnYWxlcnQtZGlhbG9nLWJ1dHRvbi0tcm93Zm9vdGVyLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctYnV0dG9uLS1wcmltYWwnOiAnYWxlcnQtZGlhbG9nLWJ1dHRvbi0tcHJpbWFsLS0qJyxcbiAgJy5hbGVydC1kaWFsb2ctYnV0dG9uJzogJ2FsZXJ0LWRpYWxvZy1idXR0b24tLSonLFxuICAnb25zLWFsZXJ0LWRpYWxvZy1idXR0b24nOiAnYWxlcnQtZGlhbG9nLWJ1dHRvbi0tKicsXG4gICcuYWxlcnQtZGlhbG9nLW1hc2snOiAnYWxlcnQtZGlhbG9nLW1hc2stLSonLFxuICAnLnRleHQtaW5wdXQnOiAndGV4dC1pbnB1dC0tKidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdub25lJzogQWxlcnREaWFsb2dBbmltYXRvcixcbiAgJ2RlZmF1bHQnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IEFuZHJvaWRBbGVydERpYWxvZ0FuaW1hdG9yIDogSU9TQWxlcnREaWFsb2dBbmltYXRvcixcbiAgJ2ZhZGUnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IEFuZHJvaWRBbGVydERpYWxvZ0FuaW1hdG9yIDogSU9TQWxlcnREaWFsb2dBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtYWxlcnQtZGlhbG9nXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIEFsZXJ0IGRpYWxvZyB0aGF0IGlzIGRpc3BsYXllZCBvbiB0b3Agb2YgdGhlIGN1cnJlbnQgc2NyZWVuLiBVc2VmdWwgZm9yIGRpc3BsYXlpbmcgcXVlc3Rpb25zLCB3YXJuaW5ncyBvciBlcnJvciBtZXNzYWdlcyB0byB0aGUgdXNlci4gVGhlIHRpdGxlLCBjb250ZW50IGFuZCBidXR0b25zIGNhbiBiZSBlYXNpbHkgY3VzdG9taXplZCBhbmQgaXQgd2lsbCBhdXRvbWF0aWNhbGx5IHN3aXRjaCBzdHlsZSBiYXNlZCBvbiB0aGUgcGxhdGZvcm0uXG4gKlxuICogICAgIFRvIHVzZSB0aGUgZWxlbWVudCBpdCBjYW4gZWl0aGVyIGJlIGF0dGFjaGVkIGRpcmVjdGx5IHRvIHRoZSBgPGJvZHk+YCBlbGVtZW50IG9yIGR5bmFtaWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHRlbXBsYXRlIHVzaW5nIHRoZSBgb25zLmNyZWF0ZUFsZXJ0RGlhbG9nKHRlbXBsYXRlKWAgdXRpbGl0eSBmdW5jdGlvbiBhbmQgdGhlIGA8dGVtcGxhdGU+YCB0YWcuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICDnj77lnKjjga7jgrnjgq/jg6rjg7zjg7Pjga7kuIrjgavooajnpLrjgZnjgovjgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjgafjgZnjgILjg6bjg7zjgrbjgavlr77jgZnjgovllY/jgYTjgYvjgZHjgIHorablkYrjgIHjgqjjg6njg7zjg6Hjg4Pjgrvjg7zjgrjjgpLooajnpLrjgZnjgovjga7jgavliKnnlKjjgafjgY3jgb7jgZnjgILjgr/jgqTjg4jjg6vjgoTjgrPjg7Pjg4bjg7Pjg4TjgoTjg5zjgr/jg7Pjga/nsKHljZjjgavjgqvjgrnjgr/jg57jgqTjgrrjgafjgY3jgIHlrp/ooYzjgZfjgabjgYTjgovjg5fjg6njg4Pjg4jjg5Xjgqnjg7zjg6DjgavkvbXjgZvjgabjgrnjgr/jgqTjg6vjgYzoh6rli5XnmoTjgavliIfjgormm7/jgo/jgorjgb7jgZnjgIJcbiAqICAgWy9qYV1cbiAqIEBjb2RlcGVuIFF3d3h5cFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2FsZXJ0LWRpYWxvZ1xuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gc3R5bGVbL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44K544K/44Kk44OrWy9qYV1cbiAqIEBtb2RpZmllciByb3dmb290ZXJcbiAqICAgW2VuXUhvcml6b250YWxseSBhbGlnbnMgdGhlIGZvb3RlciBidXR0b25zLlsvZW5dXG4gKiAgIFtqYV3jg5Xjg4Pjgr/jg7zjga7opIfmlbDjga7jg5zjgr/jg7PjgpLmsLTlubPjgavphY3nva5bL2phXVxuICogQHNlZWFsc28gb25zLWRpYWxvZ1xuICogICBbZW5db25zLWRpYWxvZyBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWRpYWxvZ+OCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcG9wb3ZlclxuICogICBbZW5db25zLXBvcG92ZXIgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1kaWFsb2fjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLm5vdGlmaWNhdGlvblxuICogICBbZW5dVXNpbmcgb25zLm5vdGlmaWNhdGlvbiB1dGlsaXR5IGZ1bmN0aW9ucy5bL2VuXVxuICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GZ44KL44Gr44Gv44CBb25zLm5vdGlmaWNhdGlvbuOCquODluOCuOOCp+OCr+ODiOOBruODoeOCveODg+ODieOCkuS9v+OBhuOBk+OBqOOCguOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1hbGVydC1kaWFsb2cgaWQ9XCJhbGVydC1kaWFsb2dcIj5cbiAqICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy10aXRsZVwiPldhcm5pbmchPC9kaXY+XG4gKiAgIDxkaXYgY2xhc3M9XCJhbGVydC1kaWFsb2ctY29udGVudFwiPlxuICogICAgIEFuIGVycm9yIGhhcyBvY2N1cnJlZCFcbiAqICAgPC9kaXY+XG4gKiAgIDxkaXYgY2xhc3M9XCJhbGVydC1kaWFsb2ctZm9vdGVyXCI+XG4gKiAgICAgPGJ1dHRvbiBpZD1cImFsZXJ0LWRpYWxvZy1idXR0b25cIiBjbGFzcz1cImFsZXJ0LWRpYWxvZy1idXR0b25cIj5PSzwvYnV0dG9uPlxuICogICA8L2Rpdj5cbiAqIDwvb25zLWFsZXJ0LWRpYWxvZz5cbiAqIDxzY3JpcHQ+XG4gKiAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhbGVydC1kaWFsb2cnKS5zaG93KCk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWxlcnREaWFsb2dFbGVtZW50IGV4dGVuZHMgQmFzZURpYWxvZ0VsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIGFsZXJ0IGRpYWxvZyBpcyBkaXNwbGF5ZWQuWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44GM6KGo56S644GV44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmFsZXJ0RGlhbG9nXG4gICAqICAgW2VuXUFsZXJ0IGRpYWxvZyBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdG8gc3RvcCB0aGUgZGlhbG9nIGZyb20gc2hvd2luZy5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjgpLlrp/ooYzjgZnjgovjgajjgIHjgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjga7ooajnpLrjgpLmraLjgoHjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBhbGVydCBkaWFsb2cgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBjOihqOekuuOBleOCjOOBn+ebtOW+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5hbGVydERpYWxvZ1xuICAgKiAgIFtlbl1BbGVydCBkaWFsb2cgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIGFsZXJ0IGRpYWxvZyBpcyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44GM6Zqg44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmFsZXJ0RGlhbG9nXG4gICAqICAgW2VuXUFsZXJ0IGRpYWxvZyBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Ki44Op44O844OI44OA44Kk44Ki44Ot44Kw44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdG8gc3RvcCB0aGUgZGlhbG9nIGZyb20gaGlkaW5nLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWun+ihjOOBmeOCi+OBqOOAgeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBjOmWieOBmOOCiOOBhuOBqOOBmeOCi+OBruOCkuatouOCgeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdGhpZGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBhbGVydCBkaWFsb2cgaXMgaGlkZGVuLlsvZW5dXG4gICAqIFtqYV3jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjgYzpmqDjgozjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuYWxlcnREaWFsb2dcbiAgICogICBbZW5dQWxlcnQgZGlhbG9nIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg6njg7zjg4jjg4DjgqTjgqLjg63jgrDjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgZGlhbG9nLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44Gu6KaL44Gf55uu44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgY2FuY2VsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGRpYWxvZyBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OCkuioreWumuOBmeOCi+OBqOOAgeODgOOCpOOCouODreOCsOOBruiDjOaZr+OCkuOCv+ODg+ODl+OBl+OBn+OCikFuZHJvaWTjg4fjg5DjgqTjgrnjga7jg5Djg4Pjgq/jg5zjgr/jg7PjgpLmirzjgZnjgajjg4DjgqTjgqLjg63jgrDjgYzplonjgZjjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGRpYWxvZyBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeOCouODqeODvOODiOODgOOCpOOCouODreOCsOOBr2Rpc2FibGVk54q25oWL44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBkaWFsb2cuIENhbiBiZSBlaXRoZXIgYFwibm9uZVwiYCBvciBgXCJkZWZhdWx0XCJgLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GZ44KL6Zqb44Gu44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44Gn44GvXCJub25lXCLjgYtcImRlZmF1bHRcIuOBjOaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFuaW1hdGlvbi1vcHRpb25zXG4gICAqIEB0eXBlIHtFeHByZXNzaW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgdGltaW5nIGFuZCBkZWxheSB3aXRoIGFuIG9iamVjdCBsaXRlcmFsLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgdGltaW5nLCBkZWxheeOCkuOCquODluOCuOOCp+OCr+ODiOODquODhuODqeODq+OBp+aMh+WumuOBl+OBvuOBmeOAguS+i++8mntkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbWFzay1jb2xvclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCByZ2JhKDAsIDAsIDAsIDAuMilcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBcInJnYmEoMCwgMCwgMCwgMC4yKVwiLlsvZW5dXG4gICAqICBbamFd6IOM5pmv44Gu44Oe44K544Kv44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CCXCJyZ2JhKDAsIDAsIDAsIDAuMilcIuOBjOODh+ODleOCqeODq+ODiOWApOOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7RWxlbWVudH1cbiAgICovXG4gIGdldCBfbWFzaygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5hbGVydC1kaWFsb2ctbWFzaycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAqL1xuICBnZXQgX2RpYWxvZygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5hbGVydC1kaWFsb2cnKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAqL1xuICBnZXQgX3RpdGxlRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcy5fZGlhbG9nLmNoaWxkcmVuWzBdLCAnLmFsZXJ0LWRpYWxvZy10aXRsZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0VsZW1lbnR9XG4gICAqL1xuICBnZXQgX2NvbnRlbnRFbGVtZW50KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLl9kaWFsb2cuY2hpbGRyZW5bMF0sICcuYWxlcnQtZGlhbG9nLWNvbnRlbnQnKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBBbGVydERpYWxvZ0FuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ0FsZXJ0RGlhbG9nQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAxO1xuXG4gICAgLyoqXG4gICAgICogRXhwZWN0ZWQgcmVzdWx0IGFmdGVyIGNvbXBpbGU6XG4gICAgICpcbiAgICAgKiA8b25zLWFsZXJ0LWRpYWxvZyBzdHlsZT1cIm5vbmVcIj5cbiAgICAgKiAgIDxkaXYgY2xhc3M9XCJhbGVydC1kaWFsb2ctbWFza1wiPjwvZGl2PlxuICAgICAqICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZ1wiPlxuICAgICAqICAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWNvbnRhaW5lclwiPi4uLjwvZGl2PlxuICAgICAqICAgPC9kaXY+XG4gICAgICogPC9vbnMtYWxlcnQtZGlhbG9nPlxuICAgICAqL1xuXG4gICAgY29uc3QgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblxuICAgIGlmICghdGhpcy5fbWFzayAmJiAhdGhpcy5fZGlhbG9nKSB7XG4gICAgICB3aGlsZSAodGhpcy5maXJzdENoaWxkKSB7XG4gICAgICAgIGNvbnRlbnQuYXBwZW5kQ2hpbGQodGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX21hc2spIHtcbiAgICAgIGNvbnN0IG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIG1hc2suY2xhc3NMaXN0LmFkZCgnYWxlcnQtZGlhbG9nLW1hc2snKTtcbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKG1hc2ssIHRoaXMuY2hpbGRyZW5bMF0pO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fZGlhbG9nKSB7XG4gICAgICBjb25zdCBkaWFsb2cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGRpYWxvZy5jbGFzc0xpc3QuYWRkKCdhbGVydC1kaWFsb2cnKTtcbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGRpYWxvZywgbnVsbCk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZCh0aGlzLl9kaWFsb2csICcuYWxlcnQtZGlhbG9nLWNvbnRhaW5lcicpKSB7XG4gICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdhbGVydC1kaWFsb2ctY29udGFpbmVyJyk7XG4gICAgICB0aGlzLl9kaWFsb2cuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaWFsb2cuY2hpbGRyZW5bMF0uYXBwZW5kQ2hpbGQoY29udGVudCk7XG5cbiAgICB0aGlzLl9kaWFsb2cuc3R5bGUuekluZGV4ID0gMjAwMDE7XG4gICAgdGhpcy5fbWFzay5zdHlsZS56SW5kZXggPSAyMDAwMDtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgdGhpcy5fc2NoZW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBlbGVtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGNhbmNlbGFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgY2FuY2VsYWJsZSBvciBub3QuIEEgY2FuY2VsYWJsZSBkaWFsb2cgY2FuIGJlIGNsb3NlZCBieSB0YXBwaW5nIHRoZSBiYWNrZ3JvdW5kIG9yIGJ5IHByZXNzaW5nIHRoZSBiYWNrIGJ1dHRvbiBvbiBBbmRyb2lkIGRldmljZXMuWy9lbl1cbiAgICogICBbamFd44Gd44Gu44OA44Kk44Ki44Ot44Kw44GM44Kt44Oj44Oz44K744Or5Y+v6IO944GL44Gp44GG44GL44KS6KGo44GX44G+44GZ44CC44Kt44Oj44Oz44K744Or5Y+v6IO944Gq44OA44Kk44Ki44Ot44Kw44Gv44CB6IOM5pmv44KS44K/44OD44OX44GZ44KL44GLQW5kcm9pZOODh+ODkOOCpOOCueOBruODkOODg+OCr+ODnOOCv+ODs+OCkuaKvOOBmeOBk+OBqOOBp+mWieOBmOOCi+OBk+OBqOOBjOWHuuadpeOCi+OCiOOBhuOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dcbiAgICogQHNpZ25hdHVyZSBzaG93KFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUFuaW1hdGlvbiBuYW1lLiBBdmFpbGFibGUgYW5pbWF0aW9ucyBhcmUgYFwiZmFkZVwiYCBhbmQgYFwibm9uZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgILmjIflrprjgafjgY3jgovjga7jga/jgIFcImZhZGVcIiwgXCJub25lXCLjga7jgYTjgZrjgozjgYvjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gPGNvZGU+e2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfTwvY29kZT4gWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXUZ1bmN0aW9uIHRvIGV4ZWN1dGUgYWZ0ZXIgdGhlIGRpYWxvZyBoYXMgYmVlbiByZXZlYWxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozntYLjgo/jgaPjgZ/mmYLjgavlkbzjgbPlh7rjgZXjgozjgovjgrPjg7zjg6vjg5Djg4Pjgq/jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyB0aGUgYWxlcnQgZGlhbG9nLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXUEgYFByb21pc2VgIG9iamVjdCB0aGF0IHJlc29sdmVzIHRvIHRoZSBkaXNwbGF5ZWQgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV3ooajnpLrjgZXjgozjgovopoHntKDjgpLop6PmsbrjgZnjgotgUHJvbWlzZWDjgqrjg5bjgrjjgqfjgq/jg4jjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBoaWRlXG4gICAqIEBzaWduYXR1cmUgaGlkZShbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcImZhZGVcImAgYW5kIGBcIm5vbmVcImAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJmYWRlXCIsIFwibm9uZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuICA8Y29kZT57ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9PC9jb2RlPlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiA8Y29kZT57ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9PC9jb2RlPiBbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dRnVuY3Rpb24gdG8gZXhlY3V0ZSBhZnRlciB0aGUgZGlhbG9nIGhhcyBiZWVuIGhpZGRlbi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jg4DjgqTjgqLjg63jgrDjgYzplonjgZjjgZ/mmYLjgavlkbzjgbPlh7rjgZXjgozjgovjgrPjg7zjg6vjg5Djg4Pjgq/jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSGlkZSB0aGUgYWxlcnQgZGlhbG9nLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOCkumWieOBmOOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXemaoOOCjOOBn+imgee0oOOCkuino+axuuOBmeOCi2BQcm9taXNlYOOCquODluOCuOOCp+OCr+ODiOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmlzaWJsZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkRldmljZUJhY2tCdXR0b25cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJhY2stYnV0dG9uIGhhbmRsZXIuWy9lbl1cbiAgICogICBbamFd44OQ44OD44Kv44Oc44K/44Oz44OP44Oz44OJ44Op44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7RGlhbG9nQW5pbWF0b3J9IEFuaW1hdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yLnByb3RvdHlwZSBpbnN0YW5jZW9mIEFsZXJ0RGlhbG9nQW5pbWF0b3IpKSB7XG4gICAgICB1dGlsLnRocm93QW5pbWF0b3IoJ0FsZXJ0RGlhbG9nJyk7XG4gICAgfVxuICAgIF9hbmltYXRvckRpY3RbbmFtZV0gPSBBbmltYXRvcjtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgYW5pbWF0b3JzKCkge1xuICAgIHJldHVybiBfYW5pbWF0b3JEaWN0O1xuICB9XG5cbiAgc3RhdGljIGdldCBBbGVydERpYWxvZ0FuaW1hdG9yKCkge1xuICAgIHJldHVybiBBbGVydERpYWxvZ0FuaW1hdG9yO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkFsZXJ0RGlhbG9nID0gQWxlcnREaWFsb2dFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYWxlcnQtZGlhbG9nJywgQWxlcnREaWFsb2dFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VCdXR0b25FbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWJ1dHRvbic7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWFsZXJ0LWRpYWxvZy1idXR0b25cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dTWF0ZXJpYWwgRGVzaWduIGFsZXJ0LWRpYWxvZyBidXR0b24uWy9lbl1cbiAqICAgW2phXeODnuODhuODquOCouODq+ODh+OCtuOCpOODs+OBruODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWFsZXJ0LWRpYWxvZ1xuICogICBbZW5dVGhlIGA8b25zLWFsZXJ0LWRpYWxvZz5gIGNvbXBvbmVudCBkaXNwbGF5cyBhIGFsZXJ0IGRpYWxvZy5bL2VuXVxuICogICBbamFdb25zLWFsZXJ0LWRpYWxvZ+OCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogIDxvbnMtYWxlcnQtZGlhbG9nPlxuICogICAgPGRpdiBjbGFzcz1cImFsZXJ0LWRpYWxvZy10aXRsZVwiPldhcm5pbmchPC9kaXY+XG4gKiAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWNvbnRlbnRcIj5cbiAqICAgICAgQW4gZXJyb3IgaGFzIG9jY3VycmVkIVxuICogICAgPC9kaXY+XG4gKiAgICA8ZGl2IGNsYXNzPVwiYWxlcnQtZGlhbG9nLWZvb3RlclwiPlxuICogICAgICA8YWxlcnQtZGlhbG9nLWJ1dHRvbiBvbmNsaWNrPVwiYXBwLmNsb3NlKClcIj5DYW5jZWw8L2FsZXJ0LWRpYWxvZy1idXR0b24+XG4gKiAgICAgIDxhbGVydC1kaWFsb2ctYnV0dG9uIGNsYXNzPVwiYWxlcnQtZGlhbG9nLWJ1dHRvblwiIG9uY2xpY2s9XCJhcHAuY2xvc2UoKVwiPk9LPC9hbGVydC1kaWFsb2ctYnV0dG9uPlxuICogICAgPC9kaXY+XG4gKiAgPC9vbnMtYWxlcnQtZGlhbG9nPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBbGVydERpYWxvZ0J1dHRvbkVsZW1lbnQgZXh0ZW5kcyBCYXNlQnV0dG9uRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBidXR0b24uWy9lbl1cbiAgICogICBbamFd44Oc44K/44Oz44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgaWYgYnV0dG9uIHNob3VsZCBiZSBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg5zjgr/jg7PjgpLnhKHlirnljJbjgZnjgovloLTlkIjjga/mjIflrprjgZfjgabjgY/jgaDjgZXjgYTjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHsgJyc6ICdhbGVydC1kaWFsb2ctYnV0dG9uLS0qJyB9O1xuICB9XG5cbiAgZ2V0IF9kZWZhdWx0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnYWxlcnQtZGlhbG9nLWJ1dHRvbic7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gW3RoaXMsIHVuZGVmaW5lZCwgeyAnbW9kaWZpZXInOiAnbGlnaHQtZ3JheScgfV07XG4gIH1cbn1cblxub25zRWxlbWVudHMuQWxlcnREaWFsb2dCdXR0b24gPSBBbGVydERpYWxvZ0J1dHRvbkVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1hbGVydC1kaWFsb2ctYnV0dG9uJywgQWxlcnREaWFsb2dCdXR0b25FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgaW9zQmFja0J1dHRvbkljb24gZnJvbSAnLi4vLi4vaW1hZ2VzL2lvcy1iYWNrLWJ1dHRvbi1pY29uLnN2Zyc7XG5pbXBvcnQgbWRCYWNrQnV0dG9uSWNvbiBmcm9tICcuLi8uLi9pbWFnZXMvbWQtYmFjay1idXR0b24taWNvbi5zdmcnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2JhY2stYnV0dG9uJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ2JhY2stYnV0dG9uLS0qJyxcbiAgJy5iYWNrLWJ1dHRvbl9faWNvbic6ICdiYWNrLWJ1dHRvbi0tKl9faWNvbicsXG4gICcuYmFjay1idXR0b25fX2xhYmVsJzogJ2JhY2stYnV0dG9uLS0qX19sYWJlbCdcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWJhY2stYnV0dG9uXG4gKiBAY2F0ZWdvcnkgbmF2aWdhdGlvblxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBCYWNrIGJ1dHRvbiBjb21wb25lbnQgZm9yIGA8b25zLXRvb2xiYXI+YC4gUHV0IGl0IGluIHRoZSBsZWZ0IHBhcnQgb2YgdGhlIGA8b25zLXRvb2xiYXI+YC5cbiAqXG4gKiAgICAgSXQgd2lsbCBmaW5kIHRoZSBwYXJlbnQgYDxvbnMtbmF2aWdhdG9yPmAgZWxlbWVudCBhbmQgcG9wIGEgcGFnZSB3aGVuIGNsaWNrZWQuIFRoaXMgYmVoYXZpb3IgY2FuIGJlIG92ZXJyaWRlbiBieSBzcGVjaWZ5aW5nIHRoZSBgb25DbGlja2AgcHJvcGVydHkuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4gYUhtR0xcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9iYWNrLWJ1dHRvblxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gc3R5bGVbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy10b29sYmFyXG4gKiAgIFtlbl1vbnMtdG9vbGJhciBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLXRvb2xiYXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLW5hdmlnYXRvclxuICogICBbZW5db25zLW5hdmlnYXRvciBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLW5hdmlnYXRvcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy10b29sYmFyPlxuICogICA8ZGl2IGNsYXNzPVwibGVmdFwiPlxuICogICAgIDxvbnMtYmFjay1idXR0b24+QmFjazwvb25zLWJhY2stYnV0dG9uPlxuICogICA8L2Rpdj5cbiAqICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlxuICogICAgIFRpdGxlXG4gKiAgIDxkaXY+XG4gKiA8L29ucy10b29sYmFyPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhY2tCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgYmFjayBidXR0b24uWy9lbl1cbiAgICogIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjga7opovjgZ/nm67jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2NvbXBpbGUoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX29wdGlvbnMgPSB7fTtcbiAgICB0aGlzLl9ib3VuZE9uQ2xpY2sgPSB0aGlzLl9vbkNsaWNrLmJpbmQodGhpcyk7XG4gIH1cblxuICBfdXBkYXRlSWNvbihpY29uID0gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5iYWNrLWJ1dHRvbl9faWNvbicpKSB7XG4gICAgaWNvbi5pbm5lckhUTUwgPSBhdXRvU3R5bGUuZ2V0UGxhdGZvcm0odGhpcykgPT09ICdhbmRyb2lkJyB8fCB1dGlsLmhhc01vZGlmaWVyKHRoaXMsICdtYXRlcmlhbCcpID8gbWRCYWNrQnV0dG9uSWNvbiA6IGlvc0JhY2tCdXR0b25JY29uO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG5cbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHRoaXMsICcuYmFjay1idXR0b25fX2xhYmVsJykpIHtcbiAgICAgIGNvbnN0IGxhYmVsID0gdXRpbC5jcmVhdGUoJ3NwYW4uYmFjay1idXR0b25fX2xhYmVsJyk7XG5cbiAgICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgICAgbGFiZWwuYXBwZW5kQ2hpbGQodGhpcy5jaGlsZE5vZGVzWzBdKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQobGFiZWwpO1xuICAgIH1cblxuICAgIGlmICghdXRpbC5maW5kQ2hpbGQodGhpcywgJy5iYWNrLWJ1dHRvbl9faWNvbicpKSB7XG4gICAgICBjb25zdCBpY29uID0gdXRpbC5jcmVhdGUoJ3NwYW4uYmFjay1idXR0b25fX2ljb24nKTtcbiAgICAgIHRoaXMuX3VwZGF0ZUljb24oaWNvbik7XG5cbiAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGljb24sIHRoaXMuY2hpbGRyZW5bMF0pO1xuICAgIH1cblxuICAgIHV0aWwudXBkYXRlUmlwcGxlKHRoaXMsIHVuZGVmaW5lZCwge2NlbnRlcjogJycsICdzaXplJzogJ2NvbnRhaW4nLCAnYmFja2dyb3VuZCc6ICd0cmFuc3BhcmVudCd9KTtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb3B0aW9uc1xuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dT3B0aW9ucyBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBcInNsaWRlXCIsIFwibGlmdFwiLCBcImZhZGVcIiBhbmQgXCJub25lXCIuXG4gICAqICAgICBUaGVzZSBhcmUgcGxhdGZvcm0gYmFzZWQgYW5pbWF0aW9ucy4gRm9yIGZpeGVkIGFuaW1hdGlvbnMsIGFkZCBcIi1pb3NcIiBvciBcIi1tZFwiXG4gICAqICAgICBzdWZmaXggdG8gdGhlIGFuaW1hdGlvbiBuYW1lLiBFLmcuIFwibGlmdC1pb3NcIiwgXCJsaWZ0LW1kXCIuIERlZmF1bHRzIHZhbHVlcyBhcmUgXCJzbGlkZS1pb3NcIiBhbmQgXCJmYWRlLW1kXCIuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuICBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb3B0aW9ucy5jYWxsYmFja1xuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgdHJhbnNpdGlvbiBoYXMgZW5kZWQuWy9lbl1cbiAgICogICBbamFd44GT44Gu44Oh44K944OD44OJ44Gr44KI44KL55S76Z2i6YG356e744GM57WC5LqG44GX44Gf6Zqb44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XG4gIH1cblxuICBzZXQgb3B0aW9ucyhvYmplY3QpIHtcbiAgICB0aGlzLl9vcHRpb25zID0gb2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkNsaWNrXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVVzZWQgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgYmFjayBidXR0b24gYmVoYXZpb3IuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIF9vbkNsaWNrKCkge1xuICAgIGlmICh0aGlzLm9uQ2xpY2spIHtcbiAgICAgIHRoaXMub25DbGljay5hcHBseSh0aGlzKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBuYXZpZ2F0b3IgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1uYXZpZ2F0b3InKTtcbiAgICAgIGlmIChuYXZpZ2F0b3IpIHtcbiAgICAgICAgbmF2aWdhdG9yLnBvcFBhZ2UodGhpcy5vcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrLCBmYWxzZSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdjbGFzcyddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21vZGlmaWVyJzoge1xuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKSAmJiB0aGlzLl91cGRhdGVJY29uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9ib3VuZE9uQ2xpY2ssIGZhbHNlKTtcbiAgfVxuXG4gIHNob3coKSB7XG4gICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gIH1cblxuICBoaWRlKCkge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5CYWNrQnV0dG9uID0gQmFja0J1dHRvbkVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1iYWNrLWJ1dHRvbicsIEJhY2tCdXR0b25FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2JvdHRvbS1iYXInO1xuY29uc3Qgc2NoZW1lID0geycnOiAnYm90dG9tLWJhci0tKid9O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1ib3R0b20tdG9vbGJhclxuICogQGNhdGVnb3J5IHBhZ2VcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dVG9vbGJhciBjb21wb25lbnQgdGhhdCBpcyBwb3NpdGlvbmVkIGF0IHRoZSBib3R0b20gb2YgdGhlIHBhZ2UuIFNpbmNlIGJvdHRvbSB0b29sYmFycyBhcmUgdmVyeSB2ZXJzYXRpbGUgZWxlbWVudHMsIGBvbnMtYm90dG9tLXRvb2xiYXJgIGRvZXMgbm90IHByb3ZpZGUgYW55IHNwZWNpZmljIGxheW91dCBzeW50YXggZm9yIGl0cyBjaGlsZHJlbi4gTW9kaWZpZXJzIG9yIGN1c3RvbSBDU1MgbXVzdCBiZSB1c2VkLlsvZW5dXG4gKiAgIFtqYV3jg5rjg7zjgrjkuIvpg6jjgavphY3nva7jgZXjgozjgovjg4Tjg7zjg6vjg5Djg7znlKjjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgafjgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIHRyYW5zcGFyZW50XG4gKiAgIFtlbl1NYWtlIHRoZSB0b29sYmFyIHRyYW5zcGFyZW50LlsvZW5dXG4gKiAgIFtqYV3jg4Tjg7zjg6vjg5Djg7zjga7og4zmma/jgpLpgI/mmI7jgavjgZfjgabooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIGFsaWduZWRcbiAqICAgW2VuXVZlcnRpY2FsbHkgYWxpZ25zIGl0cyBjaGlsZHJlbiBhbmQgYXBwbGllcyBmbGV4Ym94IGZvciBibG9jayBlbGVtZW50cy4gYGp1c3RpZnktY29udGVudGAgQ1NTIHJ1bGUgY2FuIGJlIHVzZWQgdG8gY2hhbmdlIGhvcml6b250YWwgYWxpZ24uWy9lbl1cbiAqICAgW2phXeODhOODvOODq+ODkOODvOOBruiDjOaZr+OCkumAj+aYjuOBq+OBl+OBpuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAc2VlYWxzbyBvbnMtdG9vbGJhciBbZW5db25zLXRvb2xiYXIgY29tcG9uZW50Wy9lbl1bamFdb25zLXRvb2xiYXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtYm90dG9tLXRvb2xiYXI+XG4gKiAgIENvbnRlbnRcbiAqIDwvb25zLWJvdHRvbS10b29sYmFyPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCb3R0b21Ub29sYmFyRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSB0b29sYmFyLlsvZW5dXG4gICAqICAgW2phXeODhOODvOODq+ODkOODvOOBruimi+OBn+ebruOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbn1cblxub25zRWxlbWVudHMuQm90dG9tVG9vbGJhciA9IEJvdHRvbVRvb2xiYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYm90dG9tLXRvb2xiYXInLCBCb3R0b21Ub29sYmFyRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBCYXNlQnV0dG9uRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1idXR0b24nO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1idXR0b25cbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgb3V0bGluZVxuICogICBbZW5dQnV0dG9uIHdpdGggb3V0bGluZSBhbmQgdHJhbnNwYXJlbnQgYmFja2dyb3VuZFsvZW5dXG4gKiAgIFtqYV3jgqLjgqbjg4jjg6njgqTjg7PjgpLmjIHjgaPjgZ/jg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIGxpZ2h0XG4gKiAgIFtlbl1CdXR0b24gdGhhdCBkb2Vzbid0IHN0YW5kIG91dC5bL2VuXVxuICogICBbamFd55uu56uL44Gf44Gq44GE44Oc44K/44Oz44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBxdWlldFxuICogICBbZW5dQnV0dG9uIHdpdGggbm8gb3V0bGluZSBhbmQgb3IgYmFja2dyb3VuZC4uWy9lbl1cbiAqICAgW2phXeaeoOe3muOChOiDjOaZr+OBjOeEoeOBhOaWh+Wtl+OBoOOBkeOBruODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAbW9kaWZpZXIgY3RhXG4gKiAgIFtlbl1CdXR0b24gdGhhdCByZWFsbHkgc3RhbmRzIG91dC5bL2VuXVxuICogICBbamFd55uu56uL44Gk44Oc44K/44Oz44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBsYXJnZVxuICogICBbZW5dTGFyZ2UgYnV0dG9uIHRoYXQgY292ZXJzIHRoZSB3aWR0aCBvZiB0aGUgc2NyZWVuLlsvZW5dXG4gKiAgIFtqYV3mqKrjgYTjgaPjgbHjgYTjgavluoPjgYzjgovlpKfjgY3jgarjg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIGxhcmdlLS1xdWlldFxuICogICBbZW5dTGFyZ2UgcXVpZXQgYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV3mqKrjgYTjgaPjgbHjgYTjgavluoPjgYzjgotxdWlldOODnOOCv+ODs+OCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAbW9kaWZpZXIgbGFyZ2UtLWN0YVxuICogICBbZW5dTGFyZ2UgY2FsbCB0byBhY3Rpb24gYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV3mqKrjgYTjgaPjgbHjgYTjgavluoPjgYzjgotjdGHjg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gYnV0dG9uWy9lbl1cbiAqICAgW2phXeODnuODhuODquOCouODq+ODh+OCtuOCpOODs+OBruODnOOCv+ODs1svamFdXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWwtLWZsYXRcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBmbGF0IGJ1dHRvblsvZW5dXG4gKiAgIFtqYV3jg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Pjga7jg5Xjg6njg4Pjg4jjg5zjgr/jg7NbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBCdXR0b24gY29tcG9uZW50LiBJZiB5b3Ugd2FudCB0byBwbGFjZSBhIGJ1dHRvbiBpbiBhIHRvb2xiYXIsIHVzZSBgPG9ucy10b29sYmFyLWJ1dHRvbj5gIG9yIGA8b25zLWJhY2stYnV0dG9uPmAgaW5zdGVhZC5cbiAqXG4gKiAgICAgV2lsbCBhdXRvbWF0aWNhbGx5IGRpc3BsYXkgYXMgYSBNYXRlcmlhbCBEZXNpZ24gYnV0dG9uIHdpdGggYSByaXBwbGUgZWZmZWN0IG9uIEFuZHJvaWQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg5zjgr/jg7PnlKjjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgILjg4Tjg7zjg6vjg5Djg7zjgavjg5zjgr/jg7PjgpLoqK3nva7jgZnjgovloLTlkIjjga/jgIFvbnMtdG9vbGJhci1idXR0b27jgoLjgZfjgY/jga9vbnMtYmFjay1idXR0b27jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgpLkvb/nlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gaExheXhcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9idXR0b25cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1idXR0b24gbW9kaWZpZXI9XCJsYXJnZS0tY3RhXCI+XG4gKiAgIFRhcCBNZVxuICogPC9vbnMtYnV0dG9uPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJ1dHRvbkVsZW1lbnQgZXh0ZW5kcyBCYXNlQnV0dG9uRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGJ1dHRvbi5bL2VuXVxuICAgKiAgW2phXeODnOOCv+ODs+OBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJpcHBsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBkZWZpbmVkLCB0aGUgYnV0dG9uIHdpbGwgaGF2ZSBhIHJpcHBsZSBlZmZlY3QuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeODnOOCv+ODs+OCkueEoeWKueWMluOBmeOCi+WgtOWQiOOBr+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBidXR0b24gaXMgZGlzYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBleOCjOOBpuOBhOOCi+WgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiB7ICcnOiAnYnV0dG9uLS0qJyB9O1xuICB9XG5cbiAgZ2V0IF9kZWZhdWx0Q2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnYnV0dG9uJztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5CdXR0b24gPSBCdXR0b25FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtYnV0dG9uJywgQnV0dG9uRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2NhcmQnO1xuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ2NhcmQtLSonLFxuICAnLmNhcmRfX3RpdGxlJzogJ2NhcmQtLSpfX3RpdGxlJyxcbiAgJy5jYXJkX19jb250ZW50JzogJ2NhcmQtLSpfX2NvbnRlbnQnXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1jYXJkXG4gKiBAY2F0ZWdvcnkgdmlzdWFsXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXUEgY2FyZCB3aXRoIG1hdGVyaWFsIGRlc2lnbi5bL2VuXVxuICogICBbamFd44Oq44K544OI44Gu5LiK5LiL44Gu44Oc44O844OA44O844GM54Sh44GE44Oq44K544OI44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICBDb21wb25lbnQgdG8gY3JlYXRlIGEgY2FyZCB0aGF0IGRpc3BsYXlzIHNvbWUgaW5mb3JtYXRpb24uXG4gKlxuICogICAgVGhlIGNhcmQgbWF5IGJlIGNvbXBvc2VkIGJ5IGRpdnMgd2l0aCBzcGVjaWFsbHkgcHJlcGFyZWQgY2xhc3NlcyBgdGl0bGVgIGFuZC9vciBgY29udGVudGAuIFlvdSBjYW4gYWxzbyBhZGQgeW91ciBvd24gY29udGVudCBhcyB5b3UgcGxlYXNlLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2NhcmRcbiAqIEBleGFtcGxlXG4gKiA8b25zLWNhcmQ+XG4gKiAgIDxwPlNvbWUgY29udGVudDwvcD5cbiAqIDwvb25zLWNhcmQ+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENhcmRFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgY2FyZC5bL2VuXVxuICAgKiAgIFtqYV3jg6rjgrnjg4jjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2NvbXBpbGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGxldCB0aXRsZSwgY29udGVudDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmNoaWxkcmVuW2ldO1xuXG4gICAgICBpZiAoZWwuY2xhc3NMaXN0LmNvbnRhaW5zKCd0aXRsZScpKSB7XG4gICAgICAgIGVsLmNsYXNzTGlzdC5hZGQoJ2NhcmRfX3RpdGxlJyk7XG4gICAgICAgIHRpdGxlID0gZWw7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoJ2NvbnRlbnQnKSkge1xuICAgICAgICBlbC5jbGFzc0xpc3QuYWRkKCdjYXJkX19jb250ZW50Jyk7XG4gICAgICAgIGNvbnRlbnQgPSBlbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLkNhcmQgPSBDYXJkRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNhcmQnLCBDYXJkRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuY29uc3Qgc2NoZW1lID0geycnOiAnY2Fyb3VzZWwtaXRlbS0tKid9O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1jYXJvdXNlbC1pdGVtXG4gKiBAY2F0ZWdvcnkgY2Fyb3VzZWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQ2Fyb3VzZWwgaXRlbSBjb21wb25lbnQuIFVzZWQgYXMgYSBjaGlsZCBvZiB0aGUgYDxvbnMtY2Fyb3VzZWw+YCBlbGVtZW50LlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIHhiYnpPUVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2Nhcm91c2VsXG4gKiBAc2VlYWxzbyBvbnMtY2Fyb3VzZWxcbiAqICAgW2VuXWA8b25zLWNhcm91c2VsPmAgY29tcG9uZW50c1svZW5dXG4gKiAgIFtqYV08b25zLWNhcm91c2VsPuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1jYXJvdXNlbCBzdHlsZT1cIndpZHRoOiAxMDAlOyBoZWlnaHQ6IDIwMHB4XCI+XG4gKiAgIDxvbnMtY2Fyb3VzZWwtaXRlbT5cbiAqICAgIC4uLlxuICogICA8L29ucy1jYXJvdXNlbC1pdGVtPlxuICogICA8b25zLWNhcm91c2VsLWl0ZW0+XG4gKiAgICAuLi5cbiAqICAgPC9vbnMtY2Fyb3VzZWwtaXRlbT5cbiAqIDwvb25zLWNhcm91c2VsPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDYXJvdXNlbEl0ZW1FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJ11cbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIHJldHVybiBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICB9XG4gIH1cbn1cblxub25zRWxlbWVudHMuQ2Fyb3VzZWxJdGVtID0gQ2Fyb3VzZWxJdGVtRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNhcm91c2VsLWl0ZW0nLCBDYXJvdXNlbEl0ZW1FbGVtZW50KTtcbiIsImltcG9ydCB1dGlsIGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL3BsYXRmb3JtJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vYW5pbWl0JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vZ2VzdHVyZS1kZXRlY3Rvcic7XG5cbmNvbnN0IGRpcmVjdGlvbk1hcCA9IHtcbiAgdmVydGljYWw6IHtcbiAgICBheGlzOiAnWScsXG4gICAgc2l6ZTogJ0hlaWdodCcsXG4gICAgZGlyOiBbJ3VwJywgJ2Rvd24nXSxcbiAgICB0M2Q6IFsnMHB4LCAnLCAncHgsIDBweCddXG4gIH0sXG4gIGhvcml6b250YWw6IHtcbiAgICBheGlzOiAnWCcsXG4gICAgc2l6ZTogJ1dpZHRoJyxcbiAgICBkaXI6IFsnbGVmdCcsICdyaWdodCddLFxuICAgIHQzZDogWycnLCAncHgsIDBweCwgMHB4J11cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3dpcGVyIHtcbiAgY29uc3RydWN0b3IocGFyYW1zKSB7XG4gICAgLy8gUGFyYW1ldGVyc1xuICAgIGNvbnN0IEZBTFNFID0gKCgpID0+IGZhbHNlKTtcbiAgICBgZ2V0SW5pdGlhbEluZGV4IGdldEJ1YmJsZVdpZHRoIGlzVmVydGljYWwgaXNPdmVyU2Nyb2xsYWJsZSBpc0NlbnRlcmVkXG4gICAgaXNBdXRvU2Nyb2xsYWJsZSByZWZyZXNoSG9vayBwcmVDaGFuZ2VIb29rIHBvc3RDaGFuZ2VIb29rIG92ZXJTY3JvbGxIb29rYFxuICAgICAgLnNwbGl0KC9cXHMrLylcbiAgICAgIC5mb3JFYWNoKGtleSA9PiB0aGlzW2tleV0gPSBwYXJhbXNba2V5XSB8fCBGQUxTRSk7XG5cbiAgICB0aGlzLmdldEVsZW1lbnQgPSBwYXJhbXMuZ2V0RWxlbWVudDsgLy8gUmVxdWlyZWRcbiAgICB0aGlzLnNjcm9sbEhvb2sgPSBwYXJhbXMuc2Nyb2xsSG9vazsgLy8gT3B0aW9uYWxcbiAgICB0aGlzLml0ZW1TaXplID0gcGFyYW1zLml0ZW1TaXplIHx8ICcxMDAlJztcblxuICAgIHRoaXMuZ2V0QXV0b1Njcm9sbFJhdGlvID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgIGxldCByYXRpbyA9IHBhcmFtcy5nZXRBdXRvU2Nyb2xsUmF0aW8gJiYgcGFyYW1zLmdldEF1dG9TY3JvbGxSYXRpbyguLi5hcmdzKTtcbiAgICAgIHJhdGlvID0gdHlwZW9mIHJhdGlvID09PSAnbnVtYmVyJyAmJiByYXRpbyA9PT0gcmF0aW8gPyByYXRpbyA6IC41O1xuICAgICAgaWYgKHJhdGlvIDwgMC4wIHx8IHJhdGlvID4gMS4wKSB7XG4gICAgICAgIHV0aWwudGhyb3coJ0ludmFsaWQgYXV0by1zY3JvbGwtcmF0aW8gJyArIHJhdGlvICsgJy4gTXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDEnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByYXRpbztcbiAgICB9O1xuXG4gICAgLy8gUHJldmVudCBjbGlja3Mgb25seSBvbiBkZXNrdG9wXG4gICAgdGhpcy5zaG91bGRCbG9jayA9IHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ290aGVyJztcblxuICAgIC8vIEJpbmQgaGFuZGxlcnNcbiAgICB0aGlzLm9uRHJhZ1N0YXJ0ID0gdGhpcy5vbkRyYWdTdGFydC5iaW5kKHRoaXMpO1xuICAgIHRoaXMub25EcmFnID0gdGhpcy5vbkRyYWcuYmluZCh0aGlzKTtcbiAgICB0aGlzLm9uRHJhZ0VuZCA9IHRoaXMub25EcmFnRW5kLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vblJlc2l6ZSA9IHRoaXMub25SZXNpemUuYmluZCh0aGlzKTtcblxuICAgIHRoaXMuX3Nob3VsZEZpeFNjcm9sbCA9IHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ2lvcyc7XG4gIH1cblxuICBpbml0KHsgc3dpcGVhYmxlLCBhdXRvUmVmcmVzaCB9ID0ge30pIHtcbiAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLnRhcmdldCA9IHRoaXMuZ2V0RWxlbWVudCgpLmNoaWxkcmVuWzBdO1xuICAgIHRoaXMuYmxvY2tlciA9IHRoaXMuZ2V0RWxlbWVudCgpLmNoaWxkcmVuWzFdO1xuICAgIGlmICghdGhpcy50YXJnZXQgfHwgIXRoaXMuYmxvY2tlcikge1xuICAgICAgdXRpbC50aHJvdygnRXhwZWN0ZWQgXCJ0YXJnZXRcIiBhbmQgXCJibG9ja2VyXCIgZWxlbWVudHMgdG8gZXhpc3QgYmVmb3JlIGluaXRpYWxpemluZyBTd2lwZXInKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuc2hvdWxkQmxvY2spIHtcbiAgICAgIHRoaXMuYmxvY2tlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIH1cblxuICAgIC8vIEFkZCBjbGFzc2VzXG4gICAgdGhpcy5nZXRFbGVtZW50KCkuY2xhc3NMaXN0LmFkZCgnb25zLXN3aXBlcicpO1xuICAgIHRoaXMudGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ29ucy1zd2lwZXItdGFyZ2V0Jyk7XG4gICAgdGhpcy5ibG9ja2VyLmNsYXNzTGlzdC5hZGQoJ29ucy1zd2lwZXItYmxvY2tlcicpO1xuXG4gICAgLy8gU2V0dXAgbGlzdGVuZXJzXG4gICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yID0gbmV3IEdlc3R1cmVEZXRlY3Rvcih0aGlzLmdldEVsZW1lbnQoKSxcbiAgICAgIHsgZHJhZ01pbkRpc3RhbmNlOiAxLCBkcmFnTG9ja1RvQXhpczogdHJ1ZSwgcGFzc2l2ZTogIXRoaXMuX3Nob3VsZEZpeFNjcm9sbCB9XG4gICAgKTtcbiAgICB0aGlzLl9tdXRhdGlvbk9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoKCkgPT4gdGhpcy5yZWZyZXNoKCkpO1xuICAgIHRoaXMudXBkYXRlU3dpcGVhYmxlKHN3aXBlYWJsZSk7XG4gICAgdGhpcy51cGRhdGVBdXRvUmVmcmVzaChhdXRvUmVmcmVzaCk7XG5cbiAgICAvLyBTZXR1cCBpbml0aWFsIGxheW91dFxuICAgIHRoaXMuX3Njcm9sbCA9IHRoaXMuX29mZnNldCA9IHRoaXMuX2xhc3RBY3RpdmVJbmRleCA9IDA7XG4gICAgdGhpcy5fdXBkYXRlTGF5b3V0KCk7XG4gICAgdGhpcy5fc2V0dXBJbml0aWFsSW5kZXgoKTtcbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4gdGhpcy5pbml0aWFsaXplZCAmJiB0aGlzLl9zZXR1cEluaXRpYWxJbmRleCgpKTtcblxuICAgIC8vIEZpeCByZW5kZXJpbmcgZ2xpdGNoIG9uIEFuZHJvaWQgNC4xXG4gICAgLy8gRml4IGZvciBpZnJhbWVzIHdoZXJlIHRoZSB3aWR0aCBpcyBpbmNvbnNpc3RlbnQgYXQgdGhlIGJlZ2lubmluZ1xuICAgIGlmICh3aW5kb3cgIT09IHdpbmRvdy5wYXJlbnQgfHwgdGhpcy5vZmZzZXRIZWlnaHQgPT09IDApIHtcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5pbml0aWFsaXplZCAmJiB0aGlzLm9uUmVzaXplKCkpO1xuICAgIH1cbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMudXBkYXRlU3dpcGVhYmxlKGZhbHNlKTtcbiAgICB0aGlzLnVwZGF0ZUF1dG9SZWZyZXNoKGZhbHNlKTtcblxuICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciAmJiB0aGlzLl9nZXN0dXJlRGV0ZWN0b3IuZGlzcG9zZSgpO1xuICAgIHRoaXMudGFyZ2V0ID0gdGhpcy5ibG9ja2VyID0gdGhpcy5fZ2VzdHVyZURldGVjdG9yID0gdGhpcy5fbXV0YXRpb25PYnNlcnZlciA9IG51bGw7XG5cbiAgICB0aGlzLnNldHVwUmVzaXplKGZhbHNlKTtcbiAgfVxuXG4gIG9uUmVzaXplKCkge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9zY3JvbGwgLyB0aGlzLnRhcmdldFNpemU7XG4gICAgdGhpcy5fcmVzZXQoKTtcbiAgICB0aGlzLnNldEFjdGl2ZUluZGV4KGkpO1xuICAgIHRoaXMucmVmcmVzaCgpO1xuICB9XG5cbiAgZ2V0IGl0ZW1Db3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy50YXJnZXQuY2hpbGRyZW4ubGVuZ3RoO1xuICB9XG5cbiAgZ2V0IGl0ZW1OdW1TaXplKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5faXRlbU51bVNpemUgIT09ICdudW1iZXInIHx8IHRoaXMuX2l0ZW1OdW1TaXplICE9PSB0aGlzLl9pdGVtTnVtU2l6ZSkge1xuICAgICAgdGhpcy5faXRlbU51bVNpemUgPSB0aGlzLl9jYWxjdWxhdGVJdGVtU2l6ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5faXRlbU51bVNpemU7XG4gIH1cblxuICBnZXQgbWF4U2Nyb2xsKCkge1xuICAgIGNvbnN0IG1heCA9IHRoaXMuaXRlbUNvdW50ICogdGhpcy5pdGVtTnVtU2l6ZSAtIHRoaXMudGFyZ2V0U2l6ZTtcbiAgICByZXR1cm4gTWF0aC5jZWlsKG1heCA8IDAgPyAwIDogbWF4KTsgLy8gTmVlZCB0byByZXR1cm4gYW4gaW50ZWdlciB2YWx1ZS5cbiAgfVxuXG4gIF9jYWxjdWxhdGVJdGVtU2l6ZSgpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5pdGVtU2l6ZS5tYXRjaCgvXihcXGQrKShweHwlKS8pO1xuXG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICB1dGlsLnRocm93KGBJbnZhbGlkIHN0YXRlOiBzd2lwZXIncyBzaXplIHVuaXQgbXVzdCBiZSAnJScgb3IgJ3B4J2ApO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gcGFyc2VJbnQobWF0Y2hlc1sxXSwgMTApO1xuICAgIHJldHVybiBtYXRjaGVzWzJdID09PSAnJScgPyBNYXRoLnJvdW5kKHZhbHVlIC8gMTAwICogdGhpcy50YXJnZXRTaXplKSA6IHZhbHVlO1xuICB9XG5cbiAgX3NldHVwSW5pdGlhbEluZGV4KCkge1xuICAgIHRoaXMuX3Jlc2V0KCk7XG4gICAgdGhpcy5fbGFzdEFjdGl2ZUluZGV4ID0gTWF0aC5tYXgoTWF0aC5taW4oTnVtYmVyKHRoaXMuZ2V0SW5pdGlhbEluZGV4KCkpLCB0aGlzLml0ZW1Db3VudCksIDApO1xuICAgIHRoaXMuX3Njcm9sbCA9IHRoaXMuX29mZnNldCArIHRoaXMuaXRlbU51bVNpemUgKiB0aGlzLl9sYXN0QWN0aXZlSW5kZXg7XG4gICAgdGhpcy5fc2Nyb2xsVG8odGhpcy5fc2Nyb2xsKTtcbiAgfVxuXG4gIF9zZXRTd2lwaW5nKHRvZ2dsZSkge1xuICAgIHRoaXMudGFyZ2V0LmNsYXNzTGlzdC50b2dnbGUoJ3N3aXBpbmcnLCB0b2dnbGUpOyAvLyBIaWRlcyBldmVyeXRoaW5nIGV4Y2VwdCBzaG93biBwYWdlc1xuICB9XG5cbiAgc2V0QWN0aXZlSW5kZXgoaW5kZXgsIG9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuX3NldFN3aXBpbmcodHJ1ZSk7XG4gICAgaW5kZXggPSBNYXRoLm1heCgwLCBNYXRoLm1pbihpbmRleCwgdGhpcy5pdGVtQ291bnQgLSAxKSk7XG4gICAgY29uc3Qgc2Nyb2xsID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy5tYXhTY3JvbGwsIHRoaXMuX29mZnNldCArIHRoaXMuaXRlbU51bVNpemUgKiBpbmRleCkpO1xuXG4gICAgaWYgKHBsYXRmb3JtLmlzVUlXZWJWaWV3KCkpIHtcbiAgICAgIC8qIERpcnR5IGZpeCBmb3IgIzIyMzEoaHR0cHM6Ly9naXRodWIuY29tL09uc2VuVUkvT25zZW5VSS9pc3N1ZXMvMjIzMSkuIGJlZ2luICovXG4gICAgICBjb25zdCBjb25jYXQgPSBhcnJheU9mQXJyYXkgPT4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShbXSwgYXJyYXlPZkFycmF5KTtcbiAgICAgIGNvbnN0IGNvbnRlbnRzID0gY29uY2F0KFxuICAgICAgICB1dGlsLmFycmF5RnJvbSh0aGlzLnRhcmdldC5jaGlsZHJlbikubWFwKHBhZ2UgPT4ge1xuICAgICAgICAgIHJldHVybiB1dGlsLmFycmF5RnJvbShwYWdlLmNoaWxkcmVuKVxuICAgICAgICAgICAgLmZpbHRlcihjaGlsZCA9PiBjaGlsZC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhZ2VfX2NvbnRlbnQnKSk7XG4gICAgICAgIH0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICBjb250ZW50cy5mb3JFYWNoKGNvbnRlbnQgPT4ge1xuICAgICAgICAgICAgbWFwLnNldChjb250ZW50LCBjb250ZW50LmdldEF0dHJpYnV0ZSgnY2xhc3MnKSk7XG4gICAgICAgICAgICBjb250ZW50LmNsYXNzTGlzdC5hZGQoJ3BhZ2VfX2NvbnRlbnQtLXN1cHByZXNzLWxheWVyLWNyZWF0aW9uJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzb2x2ZSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHRoaXMuX2NoYW5nZVRvKHNjcm9sbCwgb3B0aW9ucykpXG4gICAgICAgIC50aGVuKCgpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIGNvbnRlbnRzLmZvckVhY2goY29udGVudCA9PiB7XG4gICAgICAgICAgICBjb250ZW50LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBtYXAuZ2V0KGNvbnRlbnQpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzb2x2ZSk7XG4gICAgICAgIH0pKVxuICAgICAgKTtcbiAgICAgIC8qIGVuZCAqL1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5fY2hhbmdlVG8oc2Nyb2xsLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICBnZXRBY3RpdmVJbmRleChzY3JvbGwgPSB0aGlzLl9zY3JvbGwpIHtcbiAgICBzY3JvbGwgLT0gdGhpcy5fb2Zmc2V0O1xuICAgIGNvbnN0IGNvdW50ID0gdGhpcy5pdGVtQ291bnQsXG4gICAgICBzaXplID0gdGhpcy5pdGVtTnVtU2l6ZTtcblxuICAgIGlmICh0aGlzLml0ZW1OdW1TaXplID09PSAwIHx8ICF1dGlsLmlzSW50ZWdlcihzY3JvbGwpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGFzdEFjdGl2ZUluZGV4O1xuICAgIH1cblxuICAgIGlmIChzY3JvbGwgPD0gMCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICBpZiAoc2l6ZSAqIGkgPD0gc2Nyb2xsICYmIHNpemUgKiAoaSArIDEpID4gc2Nyb2xsKSB7XG4gICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb3VudCAtIDE7XG4gIH1cblxuICBzZXR1cFJlc2l6ZShhZGQpIHtcbiAgICB3aW5kb3dbKGFkZCA/ICdhZGQnIDogJ3JlbW92ZScpICsgJ0V2ZW50TGlzdGVuZXInXSgncmVzaXplJywgdGhpcy5vblJlc2l6ZSwgdHJ1ZSk7XG4gIH1cblxuICBzaG93KCkge1xuICAgIHRoaXMuc2V0dXBSZXNpemUodHJ1ZSk7XG4gICAgdGhpcy5vblJlc2l6ZSgpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50YXJnZXQgJiYgdGhpcy50YXJnZXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyksIDEwMDAvNjApOyAvLyBIaWRlIGVsZW1lbnRzIGFmdGVyIGFuaW1hdGlvbnNcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgdGhpcy5zZXR1cFJlc2l6ZShmYWxzZSk7XG4gICAgdGhpcy50YXJnZXQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7IC8vIFNob3cgZWxlbWVudHMgYmVmb3JlIGFuaW1hdGlvbnNcbiAgfVxuXG4gIHVwZGF0ZVN3aXBlYWJsZShzaG91bGRVcGRhdGUpIHtcbiAgICBpZiAodGhpcy5fZ2VzdHVyZURldGVjdG9yKSB7XG4gICAgICBjb25zdCBhY3Rpb24gPSBzaG91bGRVcGRhdGUgPyAnb24nIDogJ29mZic7XG4gICAgICB0aGlzLl9nZXN0dXJlRGV0ZWN0b3JbYWN0aW9uXSgnZHJhZycsIHRoaXMub25EcmFnKTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvclthY3Rpb25dKCdkcmFnc3RhcnQnLCB0aGlzLm9uRHJhZ1N0YXJ0KTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvclthY3Rpb25dKCdkcmFnZW5kJywgdGhpcy5vbkRyYWdFbmQpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUF1dG9SZWZyZXNoKHNob3VsZFdhdGNoKSB7XG4gICAgaWYgKHRoaXMuX211dGF0aW9uT2JzZXJ2ZXIpIHtcbiAgICAgIHNob3VsZFdhdGNoXG4gICAgICAgID8gdGhpcy5fbXV0YXRpb25PYnNlcnZlci5vYnNlcnZlKHRoaXMudGFyZ2V0LCB7IGNoaWxkTGlzdDogdHJ1ZSB9KVxuICAgICAgICA6IHRoaXMuX211dGF0aW9uT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUl0ZW1TaXplKG5ld1NpemUpIHtcbiAgICB0aGlzLml0ZW1TaXplID0gbmV3U2l6ZSB8fCAnMTAwJSc7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cblxuICB0b2dnbGVCbG9ja2VyKGJsb2NrKSB7XG4gICAgdGhpcy5ibG9ja2VyLnN0eWxlLnBvaW50ZXJFdmVudHMgPSBibG9jayA/ICdhdXRvJyA6ICdub25lJztcbiAgfVxuXG4gIF9jYW5Db25zdW1lR2VzdHVyZShnZXN0dXJlKSB7XG4gICAgY29uc3QgZCA9IGdlc3R1cmUuZGlyZWN0aW9uO1xuICAgIGNvbnN0IGlzRmlyc3QgPSB0aGlzLl9zY3JvbGwgPT09IDAgJiYgIXRoaXMuaXNPdmVyU2Nyb2xsYWJsZSgpO1xuICAgIGNvbnN0IGlzTGFzdCA9IHRoaXMuX3Njcm9sbCA9PT0gdGhpcy5tYXhTY3JvbGwgJiYgIXRoaXMuaXNPdmVyU2Nyb2xsYWJsZSgpO1xuXG4gICAgcmV0dXJuIHRoaXMuaXNWZXJ0aWNhbCgpXG4gICAgICA/ICgoZCA9PT0gJ2Rvd24nICYmICFpc0ZpcnN0KSB8fCAoZCA9PT0gJ3VwJyAmJiAhaXNMYXN0KSlcbiAgICAgIDogKChkID09PSAncmlnaHQnICYmICFpc0ZpcnN0KSB8fCAoZCA9PT0gJ2xlZnQnICYmICFpc0xhc3QpKTtcbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGV2ZW50KSB7XG4gICAgdGhpcy5faWdub3JlRHJhZyA9IGV2ZW50LmNvbnN1bWVkIHx8ICF1dGlsLmlzVmFsaWRHZXN0dXJlKGV2ZW50KTtcblxuICAgIGlmICghdGhpcy5faWdub3JlRHJhZykge1xuICAgICAgY29uc3QgY29uc3VtZSA9IGV2ZW50LmNvbnN1bWU7XG4gICAgICBldmVudC5jb25zdW1lID0gKCkgPT4geyBjb25zdW1lICYmIGNvbnN1bWUoKTsgdGhpcy5faWdub3JlRHJhZyA9IHRydWU7IH07XG5cbiAgICAgIGlmICh0aGlzLl9jYW5Db25zdW1lR2VzdHVyZShldmVudC5nZXN0dXJlKSkge1xuICAgICAgICBjb25zdCBzdGFydFggPSBldmVudC5nZXN0dXJlLmNlbnRlciAmJiBldmVudC5nZXN0dXJlLmNlbnRlci5jbGllbnRYIHx8IDAsXG4gICAgICAgICAgZGlzdEZyb21FZGdlID0gdGhpcy5nZXRCdWJibGVXaWR0aCgpIHx8IDAsXG4gICAgICAgICAgc3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdW1lICYmIGNvbnN1bWUoKTtcbiAgICAgICAgICAgIGV2ZW50LmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlOyAvLyBBdm9pZCBzdGFydGluZyBkcmFnIGZyb20gb3V0c2lkZVxuICAgICAgICAgICAgdGhpcy5zaG91bGRCbG9jayAmJiB0aGlzLnRvZ2dsZUJsb2NrZXIodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLl9zZXRTd2lwaW5nKHRydWUpO1xuICAgICAgICAgICAgdXRpbC5pb3NQcmV2ZW50U2Nyb2xsKHRoaXMuX2dlc3R1cmVEZXRlY3Rvcik7XG4gICAgICAgICAgfTtcblxuICAgICAgICAvLyBMZXQgcGFyZW50IGVsZW1lbnRzIGNvbnN1bWUgdGhlIGdlc3R1cmUgb3IgY29uc3VtZSBpdCByaWdodCBhd2F5XG4gICAgICAgIHN0YXJ0WCA8IGRpc3RGcm9tRWRnZSB8fCBzdGFydFggPiAodGhpcy50YXJnZXRTaXplIC0gZGlzdEZyb21FZGdlKVxuICAgICAgICAgID8gc2V0SW1tZWRpYXRlKCgpID0+ICF0aGlzLl9pZ25vcmVEcmFnICYmIHN0YXJ0KCkpXG4gICAgICAgICAgOiBzdGFydCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uRHJhZyhldmVudCkge1xuICAgIGlmICghZXZlbnQuZ2VzdHVyZSB8fCB0aGlzLl9pZ25vcmVEcmFnIHx8ICF0aGlzLl9zdGFydGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY29udGludWVkID0gdHJ1ZTsgLy8gRml4IGZvciByYW5kb20gJ2RyYWdlbmQnIHdpdGhvdXQgJ2RyYWcnXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICB0aGlzLl9zY3JvbGxUbyh0aGlzLl9zY3JvbGwgLSB0aGlzLl9nZXREZWx0YShldmVudCksIHsgdGhyb3R0bGU6IHRydWUgfSk7XG4gIH1cblxuICBvbkRyYWdFbmQoZXZlbnQpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgaWYgKCFldmVudC5nZXN0dXJlIHx8IHRoaXMuX2lnbm9yZURyYWcgfHwgIXRoaXMuX2NvbnRpbnVlZCkge1xuICAgICAgdGhpcy5faWdub3JlRHJhZyA9IHRydWU7IC8vIG9uRHJhZ0VuZCBtaWdodCBmaXJlIGJlZm9yZSBvbkRyYWdTdGFydCdzIHNldEltbWVkaWF0ZVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2NvbnRpbnVlZCA9IGZhbHNlO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgY29uc3Qgc2Nyb2xsID0gdGhpcy5fc2Nyb2xsIC0gdGhpcy5fZ2V0RGVsdGEoZXZlbnQpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTY3JvbGwgPSB0aGlzLl9ub3JtYWxpemVTY3JvbGwoc2Nyb2xsKTtcbiAgICBzY3JvbGwgPT09IG5vcm1hbGl6ZWRTY3JvbGwgPyB0aGlzLl9zdGFydE1vbWVudHVtU2Nyb2xsKHNjcm9sbCwgZXZlbnQpIDogdGhpcy5fa2lsbE92ZXJTY3JvbGwobm9ybWFsaXplZFNjcm9sbCk7XG4gICAgdGhpcy5zaG91bGRCbG9jayAmJiB0aGlzLnRvZ2dsZUJsb2NrZXIoZmFsc2UpO1xuICB9XG5cbiAgX3N0YXJ0TW9tZW50dW1TY3JvbGwoc2Nyb2xsLCBldmVudCkge1xuICAgIGNvbnN0IHZlbG9jaXR5ID0gdGhpcy5fZ2V0VmVsb2NpdHkoZXZlbnQpLFxuICAgICAgbWF0Y2hlc0RpcmVjdGlvbiA9IGV2ZW50Lmdlc3R1cmUuaW50ZXJpbURpcmVjdGlvbiA9PT0gdGhpcy5kTS5kaXJbdGhpcy5fZ2V0RGVsdGEoZXZlbnQpIDwgMCA/IDAgOiAxXTtcblxuICAgIGNvbnN0IG5leHRTY3JvbGwgPSB0aGlzLl9nZXRBdXRvU2Nyb2xsKHNjcm9sbCwgdmVsb2NpdHksIG1hdGNoZXNEaXJlY3Rpb24pO1xuICAgIGxldCBkdXJhdGlvbiA9IE1hdGguYWJzKG5leHRTY3JvbGwgLSBzY3JvbGwpIC8gKHZlbG9jaXR5ICsgMC4wMSkgLyAxMDAwO1xuICAgIGR1cmF0aW9uID0gTWF0aC5taW4oLjI1LCBNYXRoLm1heCguMSwgZHVyYXRpb24pKTtcblxuICAgIHRoaXMuX2NoYW5nZVRvKG5leHRTY3JvbGwsIHsgc3dpcGU6IHRydWUsIGFuaW1hdGlvbk9wdGlvbnM6IHsgZHVyYXRpb24sIHRpbWluZzogJ2N1YmljLWJlemllciguNCwgLjcsIC41LCAxKScgfSB9KTtcbiAgfVxuXG4gIF9raWxsT3ZlclNjcm9sbChzY3JvbGwpIHtcbiAgICB0aGlzLl9zY3JvbGwgPSBzY3JvbGw7XG4gICAgY29uc3QgZGlyZWN0aW9uID0gdGhpcy5kTS5kaXJbTnVtYmVyKHNjcm9sbCA+IDApXTtcbiAgICBjb25zdCBraWxsT3ZlclNjcm9sbCA9ICgpID0+IHRoaXMuX2NoYW5nZVRvKHNjcm9sbCwgeyBhbmltYXRpb25PcHRpb25zOiB7IGR1cmF0aW9uOiAuNCwgdGltaW5nOiAnY3ViaWMtYmV6aWVyKC4xLCAuNCwgLjEsIDEpJyB9IH0pO1xuICAgIHRoaXMub3ZlclNjcm9sbEhvb2soeyBkaXJlY3Rpb24sIGtpbGxPdmVyU2Nyb2xsIH0pIHx8IGtpbGxPdmVyU2Nyb2xsKCk7XG4gIH1cblxuICBfY2hhbmdlVG8oc2Nyb2xsLCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBlID0geyBhY3RpdmVJbmRleDogdGhpcy5nZXRBY3RpdmVJbmRleChzY3JvbGwpLCBsYXN0QWN0aXZlSW5kZXg6IHRoaXMuX2xhc3RBY3RpdmVJbmRleCwgc3dpcGU6IG9wdGlvbnMuc3dpcGUgfHwgZmFsc2UgfTtcbiAgICBjb25zdCBjaGFuZ2UgPSBlLmFjdGl2ZUluZGV4ICE9PSBlLmxhc3RBY3RpdmVJbmRleDtcbiAgICBjb25zdCBjYW5jZWxlZCA9IGNoYW5nZSA/IHRoaXMucHJlQ2hhbmdlSG9vayhlKSA6IGZhbHNlO1xuXG4gICAgdGhpcy5fc2Nyb2xsID0gY2FuY2VsZWQgPyB0aGlzLl9vZmZzZXQgKyBlLmxhc3RBY3RpdmVJbmRleCAqIHRoaXMuaXRlbU51bVNpemUgOiBzY3JvbGw7XG4gICAgdGhpcy5fbGFzdEFjdGl2ZUluZGV4ID0gY2FuY2VsZWQgPyBlLmxhc3RBY3RpdmVJbmRleCA6IGUuYWN0aXZlSW5kZXg7XG5cbiAgICByZXR1cm4gdGhpcy5fc2Nyb2xsVG8odGhpcy5fc2Nyb2xsLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChzY3JvbGwgPT09IHRoaXMuX3Njcm9sbCAmJiAhY2FuY2VsZWQpIHtcbiAgICAgICAgdGhpcy5fc2V0U3dpcGluZyhmYWxzZSk7XG4gICAgICAgIGNoYW5nZSAmJiB0aGlzLnBvc3RDaGFuZ2VIb29rKGUpO1xuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLnJlamVjdCkge1xuICAgICAgICB0aGlzLl9zZXRTd2lwaW5nKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDYW5jZWxlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgX3Njcm9sbFRvKHNjcm9sbCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKG9wdGlvbnMudGhyb3R0bGUpIHtcbiAgICAgIGNvbnN0IHJhdGlvID0gMC4zNTtcbiAgICAgIGlmIChzY3JvbGwgPCAwKSB7XG4gICAgICAgIHNjcm9sbCA9IHRoaXMuaXNPdmVyU2Nyb2xsYWJsZSgpID8gTWF0aC5yb3VuZChzY3JvbGwgKiByYXRpbykgOiAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbWF4U2Nyb2xsID0gdGhpcy5tYXhTY3JvbGw7XG4gICAgICAgIGlmIChtYXhTY3JvbGwgPCBzY3JvbGwpIHtcbiAgICAgICAgICBzY3JvbGwgPSB0aGlzLmlzT3ZlclNjcm9sbGFibGUoKSA/IG1heFNjcm9sbCArIE1hdGgucm91bmQoKHNjcm9sbCAtIG1heFNjcm9sbCkgKiByYXRpbykgOiBtYXhTY3JvbGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvcHQgPSBvcHRpb25zLmFuaW1hdGlvbiAgPT09ICdub25lJyA/IHt9IDogb3B0aW9ucy5hbmltYXRpb25PcHRpb25zO1xuICAgIHRoaXMuc2Nyb2xsSG9vayAmJiB0aGlzLml0ZW1OdW1TaXplID4gMCAmJiB0aGlzLnNjcm9sbEhvb2soKHNjcm9sbCAvIHRoaXMuaXRlbU51bVNpemUpLnRvRml4ZWQoMiksIG9wdGlvbnMuYW5pbWF0aW9uT3B0aW9ucyB8fCB7fSk7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PlxuICAgICAgYW5pbWl0KHRoaXMudGFyZ2V0KVxuICAgICAgICAucXVldWUoeyB0cmFuc2Zvcm06IHRoaXMuX2dldFRyYW5zZm9ybShzY3JvbGwpIH0sIG9wdClcbiAgICAgICAgLnBsYXkocmVzb2x2ZSlcbiAgICApO1xuICB9XG5cbiAgX2dldEF1dG9TY3JvbGwoc2Nyb2xsLCB2ZWxvY2l0eSwgbWF0Y2hlc0RpcmVjdGlvbikge1xuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4U2Nyb2xsLFxuICAgICAgb2Zmc2V0ID0gdGhpcy5fb2Zmc2V0LFxuICAgICAgc2l6ZSA9IHRoaXMuaXRlbU51bVNpemU7XG5cbiAgICBpZiAoIXRoaXMuaXNBdXRvU2Nyb2xsYWJsZSgpKSB7XG4gICAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obWF4LCBzY3JvbGwpKTtcbiAgICB9XG5cbiAgICBsZXQgYXJyID0gW107XG4gICAgZm9yIChsZXQgcyA9IG9mZnNldDsgcyA8IG1heDsgcyArPSBzaXplKSB7XG4gICAgICBhcnIucHVzaChzKTtcbiAgICB9XG4gICAgYXJyLnB1c2gobWF4KTtcblxuICAgIGFyciA9IGFyclxuICAgICAgLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiBNYXRoLmFicyhsZWZ0IC0gc2Nyb2xsKSAtIE1hdGguYWJzKHJpZ2h0IC0gc2Nyb2xsKSlcbiAgICAgIC5maWx0ZXIoKGl0ZW0sIHBvcykgPT4gIXBvcyB8fCBpdGVtICE9PSBhcnJbcG9zIC0gMV0pO1xuXG4gICAgbGV0IHJlc3VsdCA9IGFyclswXTtcbiAgICBjb25zdCBsYXN0U2Nyb2xsID0gdGhpcy5fbGFzdEFjdGl2ZUluZGV4ICogc2l6ZSArIG9mZnNldDtcbiAgICBjb25zdCBzY3JvbGxSYXRpbyA9IE1hdGguYWJzKHNjcm9sbCAtIGxhc3RTY3JvbGwpIC8gc2l6ZTtcblxuICAgIGlmIChzY3JvbGxSYXRpbyA8PSB0aGlzLmdldEF1dG9TY3JvbGxSYXRpbyhtYXRjaGVzRGlyZWN0aW9uLCB2ZWxvY2l0eSwgc2l6ZSkpIHtcbiAgICAgIHJlc3VsdCA9IGxhc3RTY3JvbGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY3JvbGxSYXRpbyA8IDEuMCAmJiBhcnJbMF0gPT09IGxhc3RTY3JvbGwgJiYgYXJyLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gYXJyWzFdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obWF4LCByZXN1bHQpKTtcbiAgfVxuXG4gIF9yZXNldCgpIHtcbiAgICB0aGlzLl90YXJnZXRTaXplID0gdGhpcy5faXRlbU51bVNpemUgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBfbm9ybWFsaXplU2Nyb2xsKHNjcm9sbCkge1xuICAgIHJldHVybiBNYXRoLm1heCggTWF0aC5taW4oc2Nyb2xsLCB0aGlzLm1heFNjcm9sbCksIDApXG4gIH1cblxuICByZWZyZXNoKCkge1xuICAgIHRoaXMuX3Jlc2V0KCk7XG4gICAgdGhpcy5fdXBkYXRlTGF5b3V0KCk7XG5cbiAgICBpZiAodXRpbC5pc0ludGVnZXIodGhpcy5fc2Nyb2xsKSkge1xuICAgICAgY29uc3Qgc2Nyb2xsID0gdGhpcy5fbm9ybWFsaXplU2Nyb2xsKHRoaXMuX3Njcm9sbCk7XG4gICAgICBzY3JvbGwgIT09IHRoaXMuX3Njcm9sbCA/IHRoaXMuX2tpbGxPdmVyU2Nyb2xsKHNjcm9sbCkgOiB0aGlzLl9jaGFuZ2VUbyhzY3JvbGwpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXR1cEluaXRpYWxJbmRleCgpO1xuICAgIH1cblxuICAgIHRoaXMucmVmcmVzaEhvb2soKTtcbiAgfVxuXG4gIGdldCB0YXJnZXRTaXplKCkge1xuICAgIGlmICghdGhpcy5fdGFyZ2V0U2l6ZSkge1xuICAgICAgdGhpcy5fdGFyZ2V0U2l6ZSA9IHRoaXMudGFyZ2V0W2BvZmZzZXQke3RoaXMuZE0uc2l6ZX1gXTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RhcmdldFNpemU7XG4gIH1cblxuICBfZ2V0RGVsdGEoZXZlbnQpIHtcbiAgICByZXR1cm4gZXZlbnQuZ2VzdHVyZVtgZGVsdGEke3RoaXMuZE0uYXhpc31gXTtcbiAgfVxuXG4gIF9nZXRWZWxvY2l0eShldmVudCkge1xuICAgIHJldHVybiBldmVudC5nZXN0dXJlW2B2ZWxvY2l0eSR7dGhpcy5kTS5heGlzfWBdO1xuICB9XG5cbiAgX2dldFRyYW5zZm9ybShzY3JvbGwpIHtcbiAgICByZXR1cm4gYHRyYW5zbGF0ZTNkKCR7dGhpcy5kTS50M2RbMF19JHstc2Nyb2xsfSR7dGhpcy5kTS50M2RbMV19KWA7XG4gIH1cblxuICBfdXBkYXRlTGF5b3V0KCkge1xuICAgIHRoaXMuZE0gPSBkaXJlY3Rpb25NYXBbdGhpcy5pc1ZlcnRpY2FsKCkgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnXTtcbiAgICB0aGlzLnRhcmdldC5jbGFzc0xpc3QudG9nZ2xlKCdvbnMtc3dpcGVyLXRhcmdldC0tdmVydGljYWwnLCB0aGlzLmlzVmVydGljYWwoKSk7XG5cbiAgICBmb3IgKGxldCBjID0gdGhpcy50YXJnZXQuY2hpbGRyZW5bMF07IGM7IGMgPSBjLm5leHRFbGVtZW50U2libGluZykge1xuICAgICAgYy5zdHlsZVt0aGlzLmRNLnNpemUudG9Mb3dlckNhc2UoKV0gPSB0aGlzLml0ZW1TaXplO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzQ2VudGVyZWQoKSkge1xuICAgICAgdGhpcy5fb2Zmc2V0ID0gKHRoaXMudGFyZ2V0U2l6ZSAtIHRoaXMuaXRlbU51bVNpemUpIC8gLTIgfHwgMDtcbiAgICB9XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBTd2lwZXIgZnJvbSAnLi4vb25zL2ludGVybmFsL3N3aXBlcic7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWNhcm91c2VsXG4gKiBAY2F0ZWdvcnkgY2Fyb3VzZWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQ2Fyb3VzZWwgY29tcG9uZW50LiBBIGNhcm91c2VsIGNhbiBiZSB1c2VkIHRvIGRpc3BsYXkgc2V2ZXJhbCBpdGVtcyBpbiB0aGUgc2FtZSBzcGFjZS5cbiAqXG4gKiAgICAgVGhlIGNvbXBvbmVudCBzdXBwb3J0cyBkaXNwbGF5aW5nIGNvbnRlbnQgYm90aCBob3Jpem9udGFsbHkgYW5kIHZlcnRpY2FsbHkuIFRoZSB1c2VyIGNhbiBzY3JvbGwgdGhyb3VnaCB0aGUgaXRlbXMgYnkgZHJhZ2dpbmcgYW5kIGl0IGNhbiBhbHNvIGJlIGNvbnRyb2xsZXIgcHJvZ3JhbW1hdGljYWxseS5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiB4YmJ6T1FcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9jYXJvdXNlbFxuICogQHNlZWFsc28gb25zLWNhcm91c2VsLWl0ZW1cbiAqICAgW2VuXWA8b25zLWNhcm91c2VsLWl0ZW0+YCBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWNhcm91c2VsLWl0ZW3jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtY2Fyb3VzZWwgc3R5bGU9XCJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAyMDBweFwiPlxuICogICA8b25zLWNhcm91c2VsLWl0ZW0+XG4gKiAgICAuLi5cbiAqICAgPC9vbnMtY2Fyb3VzZWwtaXRlbT5cbiAqICAgPG9ucy1jYXJvdXNlbC1pdGVtPlxuICogICAgLi4uXG4gKiAgIDwvb25zLWNhcm91c2VsLWl0ZW0+XG4gKiA8L29ucy1jYXJvdXNlbD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2Fyb3VzZWxFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdGNoYW5nZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgY3VycmVudCBjYXJvdXNlbCBpdGVtIGhhcyBjaGFuZ2VkLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOihqOekuuOBl+OBpuOBhOOCi+OCq+ODq+ODvOOCu+ODq+OBruimgee0oOOBjOWkieOCj+OBo+OBn+aZguOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgKiAgIFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmNhcm91c2VsXG4gICAqICAgW2VuXUNhcm91c2VsIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgYznmbrngavjgZfjgZ9DYXJvdXNlbOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5hY3RpdmVJbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGFjdGl2ZSBpbmRleC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovopoHntKDjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgIJbL2phXVxuICAgKiBAcGFyYW0ge051bWJlcn0gZXZlbnQubGFzdEFjdGl2ZUluZGV4XG4gICAqICAgW2VuXVByZXZpb3VzIGFjdGl2ZSBpbmRleC5bL2VuXVxuICAgKiAgIFtqYV3ku6XliY3jgqLjgq/jg4bjgqPjg5bjgaDjgaPjgZ/opoHntKDjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHJlZnJlc2hcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHdoZW4gdGhlIGNhcm91c2VsIGhhcyBiZWVuIHJlZnJlc2hlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqvjg6vjg7zjgrvjg6vjgYzmm7TmlrDjgZXjgozjgZ/mmYLjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jYXJvdXNlbFxuICAgKiAgIFtlbl1DYXJvdXNlbCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44GM55m654Gr44GX44GfQ2Fyb3VzZWzjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IG92ZXJzY3JvbGxcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHdoZW4gdGhlIGNhcm91c2VsIGhhcyBiZWVuIG92ZXJzY3JvbGxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqvjg6vjg7zjgrvjg6vjgYzjgqrjg7zjg5Djg7zjgrnjgq/jg63jg7zjg6vjgZfjgZ/mmYLjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jYXJvdXNlbFxuICAgKiAgIFtlbl1GaXJlZCB3aGVuIHRoZSBjYXJvdXNlbCBoYXMgYmVlbiByZWZyZXNoZWQuWy9lbl1cbiAgICogICBbamFd44Kr44Or44O844K744Or44GM5pu05paw44GV44KM44Gf5pmC44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV2ZW50LmFjdGl2ZUluZGV4XG4gICAqICAgW2VuXUN1cnJlbnQgYWN0aXZlIGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi+imgee0oOOBruOCpOODs+ODh+ODg+OCr+OCueOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudC5kaXJlY3Rpb25cbiAgICogICBbZW5dQ2FuIGJlIG9uZSBvZiBlaXRoZXIgXCJ1cFwiLCBcImRvd25cIiwgXCJsZWZ0XCIgb3IgXCJyaWdodFwiLlsvZW5dXG4gICAqICAgW2phXeOCquODvOODkOODvOOCueOCr+ODreODvOODq+OBleOCjOOBn+aWueWQkeOBjOW+l+OCieOCjOOBvuOBmeOAglwidXBcIiwgXCJkb3duXCIsIFwibGVmdFwiLCBcInJpZ2h0XCLjga7jgYTjgZrjgozjgYvjga7mlrnlkJHjgYzmuKHjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC53YWl0VG9SZXR1cm5cbiAgICogICBbZW5dVGFrZXMgYSA8Y29kZT5Qcm9taXNlPC9jb2RlPiBvYmplY3QgYXMgYW4gYXJndW1lbnQuIFRoZSBjYXJvdXNlbCB3aWxsIG5vdCBzY3JvbGwgYmFjayB1bnRpbCB0aGUgcHJvbWlzZSBoYXMgYmVlbiByZXNvbHZlZCBvciByZWplY3RlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjga9Qcm9taXNl44Kq44OW44K444Kn44Kv44OI44KS5byV5pWw44Go44GX44Gm5Y+X44GR5Y+W44KK44G+44GZ44CC5rih44GX44GfUHJvbWlzZeOCquODluOCuOOCp+OCr+ODiOOBjHJlc29sdmXjgZXjgozjgovjgYtyZWplY3TjgZXjgozjgovjgb7jgafjgIHjgqvjg6vjg7zjgrvjg6vjga/jgrnjgq/jg63jg7zjg6vjg5Djg4Pjgq/jgZfjgb7jgZvjgpPjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXJlY3Rpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBkaXJlY3Rpb24gb2YgdGhlIGNhcm91c2VsLiBDYW4gYmUgZWl0aGVyIFwiaG9yaXpvbnRhbFwiIG9yIFwidmVydGljYWxcIi4gRGVmYXVsdCBpcyBcImhvcml6b250YWxcIi5bL2VuXVxuICAgKiAgIFtqYV3jgqvjg6vjg7zjgrvjg6vjga7mlrnlkJHjgpLmjIflrprjgZfjgb7jgZnjgIJcImhvcml6b250YWxcIuOBi1widmVydGljYWxcIuOCkuaMh+WumuOBp+OBjeOBvuOBmeOAglwiaG9yaXpvbnRhbFwi44GM44OH44OV44Kp44Or44OI5YCk44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZnVsbHNjcmVlblxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCB3aWxsIGNvdmVyIHRoZSB3aG9sZSBzY3JlZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM44GC44KL44Go44CBYWJzb2x1dGXjg53jgrjjgrfjg6fjg7PjgpLkvb/jgaPjgabjgqvjg6vjg7zjgrvjg6vjgYzoh6rli5XnmoTjgavnlLvpnaLjgYTjgaPjgbHjgYTjgavluoPjgYzjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBvdmVyc2Nyb2xsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCB3aWxsIGJlIHNjcm9sbGFibGUgb3ZlciB0aGUgZWRnZS4gSXQgd2lsbCBib3VuY2UgYmFjayB3aGVuIHJlbGVhc2VkLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeOCv+ODg+ODgeOChOODieODqeODg+OCsOOBp+err+OBvuOBp+OCueOCr+ODreODvOODq+OBl+OBn+aZguOBq+OAgeODkOOCpuODs+ODieOBmeOCi+OCiOOBhuOBquWKueaenOOBjOW9k+OBn+OCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGNlbnRlcmVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGNhcm91c2VsIHRoZW4gdGhlIHNlbGVjdGVkIGl0ZW0gd2lsbCBiZSBpbiB0aGUgY2VudGVyIG9mIHRoZSBjYXJvdXNlbCBpbnN0ZWFkIG9mIHRoZSBiZWdpbm5pbmcuIFVzZWZ1bCBvbmx5IHdoZW4gdGhlIGl0ZW1zIGFyZSBzbWFsbGVyIHRoYW4gdGhlIGNhcm91c2VsLiBbL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHpgbjjgpPjgafjgYTjgotvbnMtY2Fyb3VzZWwtaXRlbeOBr+OCq+ODq+ODvOOCu+ODq+OBruecn+OCk+S4reOBuOihjOOBjeOBvuOBmeOAgumgheebruOBjOOCq+ODq+ODvOOCu+ODq+OCiOOCiuOCguWwj+OBleOBhOWgtOWQiOOBq+OBruOBv+OAgeOBk+OCjOOBr+S+v+WIqeOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGl0ZW0td2lkdGhcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgIFtlbl1vbnMtY2Fyb3VzZWwtaXRlbSdzIHdpZHRoLiBPbmx5IHdvcmtzIHdoZW4gdGhlIGRpcmVjdGlvbiBpcyBzZXQgdG8gXCJob3Jpem9udGFsXCIuWy9lbl1cbiAgICogICAgW2phXW9ucy1jYXJvdXNlbC1pdGVt44Gu5bmF44KS5oyH5a6a44GX44G+44GZ44CC44GT44Gu5bGe5oCn44Gv44CBZGlyZWN0aW9u5bGe5oCn44GrXCJob3Jpem9udGFsXCLjgpLmjIflrprjgZfjgZ/mmYLjga7jgb/mnInlirnjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpdGVtLWhlaWdodFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5db25zLWNhcm91c2VsLWl0ZW0ncyBoZWlnaHQuIE9ubHkgd29ya3Mgd2hlbiB0aGUgZGlyZWN0aW9uIGlzIHNldCB0byBcInZlcnRpY2FsXCIuWy9lbl1cbiAgICogICBbamFdb25zLWNhcm91c2VsLWl0ZW3jga7pq5jjgZXjgpLmjIflrprjgZfjgb7jgZnjgILjgZPjga7lsZ7mgKfjga/jgIFkaXJlY3Rpb27lsZ7mgKfjgatcInZlcnRpY2FsXCLjgpLmjIflrprjgZfjgZ/mmYLjga7jgb/mnInlirnjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhdXRvLXNjcm9sbFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgc2Nyb2xsZWQgdG8gdGhlIGNsb3Nlc3QgaXRlbSBib3JkZXIgd2hlbiByZWxlYXNlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHkuIDnlarov5HjgYRjYXJvdXNlbC1pdGVt44Gu5aKD55WM44G+44Gn6Ieq5YuV55qE44Gr44K544Kv44Ot44O844Or44GZ44KL44KI44GG44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYXV0by1zY3JvbGwtcmF0aW9cbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgIFtlbl1BIG51bWJlciBiZXR3ZWVuIDAuMCBhbmQgMS4wIHRoYXQgc3BlY2lmaWVzIGhvdyBtdWNoIHRoZSB1c2VyIG11c3QgZHJhZyB0aGUgY2Fyb3VzZWwgaW4gb3JkZXIgZm9yIGl0IHRvIGF1dG8gc2Nyb2xsIHRvIHRoZSBuZXh0IGl0ZW0uWy9lbl1cbiAgICogICAgW2phXTAuMOOBi+OCiTEuMOOBvuOBp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAguOCq+ODq+ODvOOCu+ODq+OBruimgee0oOOCkuOBqeOCjOOBkOOCieOBhOOBruWJsuWQiOOBvuOBp+ODieODqeODg+OCsOOBmeOCi+OBqOasoeOBruimgee0oOOBq+iHquWLleeahOOBq+OCueOCr+ODreODvOODq+OBmeOCi+OBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHN3aXBlYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCBjYW4gYmUgc2Nyb2xsZWQgYnkgZHJhZyBvciBzd2lwZS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHjgqvjg6vjg7zjgrvjg6vjgpLjgrnjg6/jgqTjg5fjgoTjg4njg6njg4PjgrDjgafnp7vli5XjgafjgY3jgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjYXJvdXNlbCBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIFkcmFn44KEdG91Y2jjgoRzd2lwZeOCkuWPl+OBkeS7mOOBkeOBquOBj+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGluaXRpYWwtaW5kZXhcbiAgICogQGluaXRvbmx5XG4gICAqIEBkZWZhdWx0IDBcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGluZGV4IG9mIHRoZSBvbnMtY2Fyb3VzZWwtaXRlbSB0byBzaG93IGluaXRpYWxseS4gRGVmYXVsdCBpcyAwLlsvZW5dXG4gICAqICAgW2phXeacgOWIneOBq+ihqOekuuOBmeOCi29ucy1jYXJvdXNlbC1pdGVt44KSMOWni+OBvuOCiuOBruOCpOODs+ODh+ODg+OCr+OCueOBp+aMh+WumuOBl+OBvuOBmeOAguODh+ODleOCqeODq+ODiOWApOOBryAwIOOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGF1dG8tcmVmcmVzaFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hlbiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGNhcm91c2VsIHdpbGwgYXV0b21hdGljYWxseSByZWZyZXNoIHdoZW4gdGhlIG51bWJlciBvZiBjaGlsZCBub2RlcyBjaGFuZ2UuWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM44GC44KL5pmC44CB5a2Q6KaB57Sg44Gu5pWw44GM5aSJ44KP44KL44Go44Kr44Or44O844K744Or44Gv6Ieq5YuV55qE44Gr5pu05paw44GV44KM44KL44KI44GG44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgdGltaW5nIGFuZCBkZWxheSB3aXRoIGFuIG9iamVjdCBsaXRlcmFsLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgILkvovvvJp7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuY2hpbGRyZW5bMF0gJiYgdGhpcy5jaGlsZHJlblswXS50YWdOYW1lICE9PSAnT05TLUNBUk9VU0VMLUlURU0nICYmIHRoaXMuY2hpbGRyZW5bMF0gfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgaWYgKCF0YXJnZXQucGFyZW50Tm9kZSkge1xuICAgICAgd2hpbGUgKHRoaXMuZmlyc3RDaGlsZCkge1xuICAgICAgICB0YXJnZXQuYXBwZW5kQ2hpbGQodGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodGFyZ2V0KTtcbiAgICB9XG5cbiAgICAhdGhpcy5jaGlsZHJlblsxXSAmJiB0aGlzLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcblxuICAgIHRoaXMuYXBwZW5kQ2hpbGQgPSB0aGlzLmFwcGVuZENoaWxkLmJpbmQodGFyZ2V0KTtcbiAgICB0aGlzLmluc2VydEJlZm9yZSA9IHRoaXMuaW5zZXJ0QmVmb3JlLmJpbmQodGFyZ2V0KTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICghdGhpcy5fc3dpcGVyKSB7XG4gICAgICB0aGlzLl9zd2lwZXIgPSBuZXcgU3dpcGVyKHtcbiAgICAgICAgZ2V0RWxlbWVudDogKCkgPT4gdGhpcyxcbiAgICAgICAgZ2V0SW5pdGlhbEluZGV4OiAoKSA9PiB0aGlzLmdldEF0dHJpYnV0ZSgnaW5pdGlhbC1pbmRleCcpLFxuICAgICAgICBnZXRBdXRvU2Nyb2xsUmF0aW86ICgpID0+IHRoaXMuYXV0b1Njcm9sbFJhdGlvLFxuICAgICAgICBpc1ZlcnRpY2FsOiAoKSA9PiB0aGlzLnZlcnRpY2FsLFxuICAgICAgICBpc092ZXJTY3JvbGxhYmxlOiAoKSA9PiB0aGlzLm92ZXJzY3JvbGxhYmxlLFxuICAgICAgICBpc0NlbnRlcmVkOiAoKSA9PiB0aGlzLmNlbnRlcmVkLFxuICAgICAgICBpc0F1dG9TY3JvbGxhYmxlOiAoKSA9PiB0aGlzLmF1dG9TY3JvbGwsXG4gICAgICAgIGl0ZW1TaXplOiB0aGlzLml0ZW1TaXplLFxuICAgICAgICBvdmVyU2Nyb2xsSG9vazogdGhpcy5fb25PdmVyU2Nyb2xsLmJpbmQodGhpcyksXG4gICAgICAgIHByZUNoYW5nZUhvb2s6IHRoaXMuX29uQ2hhbmdlLmJpbmQodGhpcywgJ3ByZWNoYW5nZScpLFxuICAgICAgICBwb3N0Q2hhbmdlSG9vazogdGhpcy5fb25DaGFuZ2UuYmluZCh0aGlzLCAncG9zdGNoYW5nZScpLFxuICAgICAgICByZWZyZXNoSG9vazogdGhpcy5fb25SZWZyZXNoLmJpbmQodGhpcyksXG4gICAgICAgIHNjcm9sbEhvb2s6ICguLi5hcmdzKSA9PiB0aGlzLl9vblN3aXBlICYmIHRoaXMuX29uU3dpcGUoLi4uYXJncylcbiAgICAgIH0pO1xuXG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fc3dpcGVyLmluaXQoe1xuICAgICAgICBzd2lwZWFibGU6IHRoaXMuaGFzQXR0cmlidXRlKCdzd2lwZWFibGUnKSxcbiAgICAgICAgYXV0b1JlZnJlc2g6IHRoaXMuaGFzQXR0cmlidXRlKCdhdXRvLXJlZnJlc2gnKVxuICAgICAgfSkpO1xuICAgIH1cbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICh0aGlzLl9zd2lwZXIgJiYgdGhpcy5fc3dpcGVyLmluaXRpYWxpemVkKSB7XG4gICAgICB0aGlzLl9zd2lwZXIuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5fc3dpcGVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydzd2lwZWFibGUnLCAnYXV0by1yZWZyZXNoJywgJ2RpcmVjdGlvbicsICdpdGVtLWhlaWdodCcsICdpdGVtLXdpZHRoJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIGlmICghdGhpcy5fc3dpcGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdzd2lwZWFibGUnOlxuICAgICAgICB0aGlzLl9zd2lwZXIudXBkYXRlU3dpcGVhYmxlKHRoaXMuaGFzQXR0cmlidXRlKCdzd2lwZWFibGUnKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYXV0by1yZWZyZXNoJzpcbiAgICAgICAgdGhpcy5fc3dpcGVyLnVwZGF0ZUF1dG9SZWZyZXNoKHRoaXMuaGFzQXR0cmlidXRlKCdhdXRvLXJlZnJlc2gnKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaXRlbS1oZWlnaHQnOlxuICAgICAgICB0aGlzLnZlcnRpY2FsICYmIHRoaXMuX3N3aXBlci51cGRhdGVJdGVtU2l6ZSh0aGlzLml0ZW1TaXplKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpdGVtLXdpZHRoJzpcbiAgICAgICAgdGhpcy52ZXJ0aWNhbCB8fCB0aGlzLl9zd2lwZXIudXBkYXRlSXRlbVNpemUodGhpcy5pdGVtU2l6ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZGlyZWN0aW9uJzpcbiAgICAgICAgdGhpcy5fc3dpcGVyLnJlZnJlc2goKTtcbiAgICB9XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICB0aGlzLl9zd2lwZXIuc2hvdygpO1xuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgdGhpcy5fc3dpcGVyLmhpZGUoKTtcbiAgfVxuXG4gIF9vbk92ZXJTY3JvbGwoeyBkaXJlY3Rpb24sIGtpbGxPdmVyU2Nyb2xsIH0pIHtcbiAgICBsZXQgd2FpdEZvckFjdGlvbiA9IGZhbHNlO1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAnb3ZlcnNjcm9sbCcsIHtcbiAgICAgIGNhcm91c2VsOiB0aGlzLFxuICAgICAgYWN0aXZlSW5kZXg6IHRoaXMuZ2V0QWN0aXZlSW5kZXgoKSxcbiAgICAgIGRpcmVjdGlvbixcbiAgICAgIHdhaXRUb1JldHVybjogcHJvbWlzZSA9PiB7XG4gICAgICAgIHdhaXRGb3JBY3Rpb24gPSB0cnVlO1xuICAgICAgICBwcm9taXNlLnRoZW4oa2lsbE92ZXJTY3JvbGwpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHdhaXRGb3JBY3Rpb247XG4gIH1cblxuICBfb25DaGFuZ2UoZXZlbnROYW1lLCB7IGFjdGl2ZUluZGV4LCBsYXN0QWN0aXZlSW5kZXggfSkge1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCBldmVudE5hbWUsIHsgY2Fyb3VzZWw6IHRoaXMsIGFjdGl2ZUluZGV4LCBsYXN0QWN0aXZlSW5kZXggfSk7XG4gIH1cblxuICBfb25SZWZyZXNoKCkge1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncmVmcmVzaCcsIHsgY2Fyb3VzZWw6IHRoaXMgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzZXRBY3RpdmVJbmRleFxuICAgKiBAc2lnbmF0dXJlIHNldEFjdGl2ZUluZGV4KGluZGV4LCBbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiAgIFtlbl1UaGUgaW5kZXggdGhhdCB0aGUgY2Fyb3VzZWwgc2hvdWxkIGJlIHNldCB0by5bL2VuXVxuICAgKiAgIFtqYV1jYXJvdXNlbOimgee0oOOBruOCpOODs+ODh+ODg+OCr+OCueOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dQSBmdW5jdGlvbiB0aGF0IHdpbGwgYmUgY2FsbGVkIGFmdGVyIHRoZSBhbmltYXRpb24gaXMgZmluaXNoZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRvIGBcIm5vbmVcImAgdGhlIHRyYW5zaXRpb25zIHdpbGwgbm90IGJlIGFuaW1hdGVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1BbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGluZGV4IG9mIHRoZSBgPG9ucy1jYXJvdXNlbC1pdGVtPmAgdG8gc2hvdy5bL2VuXVxuICAgKiAgIFtqYV3ooajnpLrjgZnjgotvbnMtY2Fyb3VzZWwtaXRlbeOCkmluZGV444Gn5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNldEFjdGl2ZUluZGV4KGluZGV4LCBvcHRpb25zID0ge30pIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgYW5pbWF0aW9uOiB0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uJyksXG4gICAgICBhbmltYXRpb25PcHRpb25zOiB0aGlzLmhhc0F0dHJpYnV0ZSgnYW5pbWF0aW9uLW9wdGlvbnMnKVxuICAgICAgICA/IHV0aWwuYW5pbWF0aW9uT3B0aW9uc1BhcnNlKHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpKVxuICAgICAgICA6IHsgZHVyYXRpb246IC4zLCB0aW1pbmc6ICdjdWJpYy1iZXppZXIoLjQsIC43LCAuNSwgMSknIH0sXG4gICAgICAuLi5vcHRpb25zXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9zd2lwZXIuc2V0QWN0aXZlSW5kZXgoaW5kZXgsIG9wdGlvbnMpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIG9wdGlvbnMuY2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiBvcHRpb25zLmNhbGxiYWNrKHRoaXMpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBnZXRBY3RpdmVJbmRleFxuICAgKiBAc2lnbmF0dXJlIGdldEFjdGl2ZUluZGV4KClcbiAgICogQHJldHVybiB7TnVtYmVyfVxuICAgKiAgIFtlbl1UaGUgY3VycmVudCBjYXJvdXNlbCBpdGVtIGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOihqOekuuOBl+OBpuOBhOOCi+OCq+ODq+ODvOOCu+ODq+imgee0oOOBruOCpOODs+ODh+ODg+OCr+OCueOBjOi/lOOBleOCjOOBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudGx5IHZpc2libGUgYDxvbnMtY2Fyb3VzZWwtaXRlbT5gLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOihqOekuuOBleOCjOOBpuOBhOOCi29ucy1jYXJvdXNlbC1pdGVt6KaB57Sg44Gu44Kk44Oz44OH44OD44Kv44K544KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGdldEFjdGl2ZUluZGV4KCkge1xuICAgIHJldHVybiB0aGlzLl9zd2lwZXIuZ2V0QWN0aXZlSW5kZXgoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIG5leHRcbiAgICogQHNpZ25hdHVyZSBuZXh0KFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1BIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXUFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBuZXh0IGA8b25zLWNhcm91c2VsLWl0ZW0+YC5bL2VuXVxuICAgKiAgIFtqYV3mrKHjga5vbnMtY2Fyb3VzZWwtaXRlbeOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBuZXh0KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5zZXRBY3RpdmVJbmRleCh0aGlzLmdldEFjdGl2ZUluZGV4KCkgKyAxLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHByZXZcbiAgICogQHNpZ25hdHVyZSBwcmV2KFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1BIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXUFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBwcmV2aW91cyBgPG9ucy1jYXJvdXNlbC1pdGVtPmAuWy9lbl1cbiAgICogICBbamFd5YmN44Gub25zLWNhcm91c2VsLWl0ZW3jgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcHJldihvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuc2V0QWN0aXZlSW5kZXgodGhpcy5nZXRBY3RpdmVJbmRleCgpIC0gMSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBmaXJzdFxuICAgKiBAc2lnbmF0dXJlIGZpcnN0KClcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1BIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1JZiB0aGlzIGlzIHNldCB0byBgXCJub25lXCJgLCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXUFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgdGhlIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nIGZ1bmN0aW9uIG9mIHRoZSBhbmltYXRpb24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGNhcm91c2VsIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBmaXJzdCBgPG9ucy1jYXJvdXNlbC1pdGVtPmAuWy9lbl1cbiAgICogICBbamFd5pyA5Yid44Gub25zLWNhcm91c2VsLWl0ZW3jgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZmlyc3Qob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnNldEFjdGl2ZUluZGV4KDAsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgbGFzdFxuICAgKiBAc2lnbmF0dXJlIGxhc3QoKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXUEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGFmdGVyIHRoZSBhbmltYXRpb24gaGFzIGZpbmlzaGVkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0byBgXCJub25lXCJgIHRoZSB0cmFuc2l0aW9ucyB3aWxsIG5vdCBiZSBhbmltYXRlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dQW4gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcgZnVuY3Rpb24gb2YgdGhlIGFuaW1hdGlvbi5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgY2Fyb3VzZWwgZWxlbWVudFsvZW5dXG4gICAqICAgW2phXVJlc29sdmVzIHRvIHRoZSBjYXJvdXNlbCBlbGVtZW50Wy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNob3cgbGFzdCBvbnMtY2Fyb3VzZWwgaXRlbS5bL2VuXVxuICAgKiAgIFtqYV3mnIDlvozjga5vbnMtY2Fyb3VzZWwtaXRlbeOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBsYXN0KG9wdGlvbnMpIHtcbiAgICB0aGlzLnNldEFjdGl2ZUluZGV4KE1hdGgubWF4KHRoaXMuaXRlbUNvdW50IC0gMSwgMCksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgcmVmcmVzaFxuICAgKiBAc2lnbmF0dXJlIHJlZnJlc2goKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVXBkYXRlIHRoZSBsYXlvdXQgb2YgdGhlIGNhcm91c2VsLiBVc2VkIHdoZW4gYWRkaW5nIGA8b25zLWNhcm91c2VsLWl0ZW1zPmAgZHluYW1pY2FsbHkgb3IgdG8gYXV0b21hdGljYWxseSBhZGp1c3QgdGhlIHNpemUuWy9lbl1cbiAgICogICBbamFd44Os44Kk44Ki44Km44OI44KE5YaF6YOo44Gu54q25oWL44KS5pyA5paw44Gu44KC44Gu44Gr5pu05paw44GX44G+44GZ44CCb25zLWNhcm91c2VsLWl0ZW3jgpLli5XnmoTjgavlopfjgoTjgZfjgZ/jgorjgIFvbnMtY2Fyb3VzZWzjga7lpKfjgY3jgZXjgpLli5XnmoTjgavlpInjgYjjgovpmpvjgavliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcmVmcmVzaCgpIHtcbiAgICB0aGlzLl9zd2lwZXIucmVmcmVzaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpdGVtQ291bnRcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgbnVtYmVyIG9mIGNhcm91c2VsIGl0ZW1zLlsvZW5dXG4gICAqICAgW2phXeOCq+ODq+ODvOOCu+ODq+imgee0oOOBruaVsOOBp+OBmeOAglsvamFdXG4gICAqL1xuICBnZXQgaXRlbUNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLl9zd2lwZXIuaXRlbUNvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzd2lwZWFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl10cnVlIGlmIHRoZSBjYXJvdXNlbCBpcyBzd2lwZWFibGUuWy9lbl1cbiAgICogICBbamFdc3dpcGVhYmxl44Gn44GC44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgc3dpcGVhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJyk7XG4gIH1cblxuICBzZXQgc3dpcGVhYmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdzd2lwZWFibGUnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uU3dpcGVcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIHVzZXIgc2xpZGVzIHRoZSBjYXJvdXNlbC4gSXQgZ2V0cyBhIGRlY2ltYWwgaW5kZXggYW5kIGFuIGFuaW1hdGlvbk9wdGlvbnMgb2JqZWN0IGFzIGFyZ3VtZW50cy5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IG9uU3dpcGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29uU3dpcGU7XG4gIH1cblxuICBzZXQgb25Td2lwZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB1dGlsLnRocm93KGBcIm9uU3dpcGVcIiBtdXN0IGJlIGEgZnVuY3Rpb25gKVxuICAgIH1cbiAgICB0aGlzLl9vblN3aXBlID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGF1dG9TY3JvbGxcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl10cnVlIGlmIGF1dG8gc2Nyb2xsIGlzIGVuYWJsZWQuWy9lbl1cbiAgICogICBbamFd44Kq44O844OI44K544Kv44Ot44O844Or44GM5pyJ5Yq544Gn44GC44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgYXV0b1Njcm9sbCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2F1dG8tc2Nyb2xsJyk7XG4gIH1cblxuICBzZXQgYXV0b1Njcm9sbCh2YWx1ZSkge1xuICAgIHJldHVybiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZSh0aGlzLCAnYXV0by1zY3JvbGwnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgdmVydGljYWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCdkaXJlY3Rpb24nKSA9PT0gJ3ZlcnRpY2FsJztcbiAgfVxuXG4gIGdldCBpdGVtU2l6ZSgpIHtcbiAgICBjb25zdCBpdGVtU2l6ZUF0dHIgPSAodGhpcy5nZXRBdHRyaWJ1dGUoYGl0ZW0tJHt0aGlzLnZlcnRpY2FsID8gJ2hlaWdodCcgOiAnd2lkdGgnfWApIHx8ICcnKS50cmltKCk7XG4gICAgcmV0dXJuIGl0ZW1TaXplQXR0ci5tYXRjaCgvXlxcZCsocHh8JSkkLykgPyBpdGVtU2l6ZUF0dHIgOiAnMTAwJSc7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGF1dG9TY3JvbGxSYXRpb1xuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGN1cnJlbnQgYXV0byBzY3JvbGwgcmF0aW8uIFsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBruOCquODvOODiOOCueOCr+ODreODvOODq+OBrnJhdGlv5YCk44CCWy9qYV1cbiAgICovXG4gIGdldCBhdXRvU2Nyb2xsUmF0aW8oKSB7XG4gICAgcmV0dXJuIHBhcnNlRmxvYXQodGhpcy5nZXRBdHRyaWJ1dGUoJ2F1dG8tc2Nyb2xsLXJhdGlvJykpO1xuICB9XG5cbiAgc2V0IGF1dG9TY3JvbGxSYXRpbyhyYXRpbykge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdhdXRvLXNjcm9sbC1yYXRpbycsIHJhdGlvKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBjYXJvdXNlbCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvdmVyc2Nyb2xsYWJsZVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGNhcm91c2VsIGlzIG92ZXJzY3JvbGxhYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV1vdmVyc2Nyb2xs44Gn44GN44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgb3ZlcnNjcm9sbGFibGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKCdvdmVyc2Nyb2xsYWJsZScpO1xuICB9XG5cbiAgc2V0IG92ZXJzY3JvbGxhYmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdvdmVyc2Nyb2xsYWJsZScsIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2VudGVyZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBjYXJvdXNlbCBpcyBjZW50ZXJlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFdY2VudGVyZWTnirbmhYvjgavjgarjgaPjgabjgYTjgozjgbB0cnVl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGdldCBjZW50ZXJlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2NlbnRlcmVkJyk7XG4gIH1cblxuICBzZXQgY2VudGVyZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2NlbnRlcmVkJywgdmFsdWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBldmVudHMoKSB7XG4gICAgcmV0dXJuIFsncG9zdGNoYW5nZScsICdyZWZyZXNoJywgJ292ZXJzY3JvbGwnXTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5DYXJvdXNlbCA9IENhcm91c2VsRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNhcm91c2VsJywgQ2Fyb3VzZWxFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHN0eWxlciBmcm9tICcuLi9vbnMvc3R5bGVyJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtY29sXG4gKiBAY2F0ZWdvcnkgZ3JpZFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1SZXByZXNlbnRzIGEgY29sdW1uIGluIHRoZSBncmlkIHN5c3RlbS4gVXNlIHdpdGggYDxvbnMtcm93PmAgdG8gbGF5b3V0IGNvbXBvbmVudHMuWy9lbl1cbiAqICAgW2phXeOCsOODquODg+ODieOCt+OCueODhuODoOOBq+OBpuWIl+OCkuWumue+qeOBl+OBvuOBmeOAgm9ucy1yb3fjgajjgajjgoLjgavkvb/nlKjjgZfjgIHjgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jg6zjgqTjgqLjgqbjg4jjgavliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQG5vdGVcbiAqICAgW2VuXUZvciBBbmRyb2lkIDQuMyBhbmQgZWFybGllciwgYW5kIGlPUzYgYW5kIGVhcmxpZXIsIHdoZW4gdXNpbmcgbWl4ZWQgYWxpZ25tZW50IHdpdGggb25zLXJvdyBhbmQgb25zLWNvbHVtbiwgdGhleSBtYXkgbm90IGJlIGRpc3BsYXllZCBjb3JyZWN0bHkuIFlvdSBjYW4gdXNlIG9ubHkgb25lIGFsaWdubWVudC5bL2VuXVxuICogICBbamFdQW5kcm9pZCA0LjPku6XliY3jgIHjgoLjgZfjgY/jga9pT1MgNuS7peWJjeOBrk9T44Gu5aC05ZCI44CBb25zLXJvd+OBqG9ucy1jb2x1bW7jgpLntYTjgb/lkIjjgo/jgZvjgZ/loLTlkIjjgavmj4/nlLvjgYzltKnjgozjgovloLTlkIjjgYzjgYLjgorjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gR2d1akMge3dpZGV9XG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sIFtlbl1MYXlvdXRpbmcgZ3VpZGVbL2VuXVtqYV3jg6zjgqTjgqLjgqbjg4jmqZ/og71bL2phXVxuICogQHNlZWFsc28gb25zLXJvd1xuICogICBbZW5dVGhlIGA8b25zLXJvdz5gIGNvbXBvbmVudCBpcyB0aGUgcGFyZW50IG9mIGA8b25zLWNvbD5gLlsvZW5dXG4gKiAgIFtqYV1vbnMtcm9344Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXJvdz5cbiAqICAgPG9ucy1jb2wgd2lkdGg9XCI1MHB4XCI+PG9ucy1pY29uIGljb249XCJmYS10d2l0dGVyXCI+PC9vbnMtaWNvbj48L29ucy1jb2w+XG4gKiAgIDxvbnMtY29sPlRleHQ8L29ucy1jb2w+XG4gKiA8L29ucy1yb3c+XG4gKi9cblxuLyoqXG4gKiBAYXR0cmlidXRlIHZlcnRpY2FsLWFsaWduXG4gKiBAdHlwZSB7U3RyaW5nfVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1WZXJ0aWNhbCBhbGlnbm1lbnQgb2YgdGhlIGNvbHVtbi4gVmFsaWQgdmFsdWVzIGFyZSBcInRvcFwiLCBcImNlbnRlclwiLCBhbmQgXCJib3R0b21cIi5bL2VuXVxuICogICBbamFd57im44Gu6YWN572u44KS5oyH5a6a44GZ44KL44CCXCJ0b3BcIiwgXCJjZW50ZXJcIiwgXCJib3R0b21cIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gKi9cblxuLyoqXG4gKiBAYXR0cmlidXRlIHdpZHRoXG4gKiBAdHlwZSB7U3RyaW5nfVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1UaGUgd2lkdGggb2YgdGhlIGNvbHVtbi4gVmFsaWQgdmFsdWVzIGFyZSBjc3Mgd2lkdGggdmFsdWVzIChcIjEwJVwiLCBcIjUwcHhcIikuWy9lbl1cbiAqICAgW2phXeOCq+ODqeODoOOBruaoquW5heOCkuaMh+WumuOBmeOCi+OAguODkeODvOOCu+ODs+ODiOOCguOBl+OBj+OBr+ODlOOCr+OCu+ODq+OBp+aMh+WumuOBl+OBvuOBme+8iDEwJeOChDUwcHjvvInjgIJbL2phXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoJ3dpZHRoJykpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVdpZHRoKCk7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnd2lkdGgnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICd3aWR0aCcpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVdpZHRoKCk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZVdpZHRoKCkge1xuICAgIGxldCB3aWR0aCA9IHRoaXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpO1xuICAgIGlmICghd2lkdGgpIHtcbiAgICAgIHN0eWxlci5jbGVhcih0aGlzLCAnZmxleCBtYXhXaWR0aCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aWR0aCA9IHdpZHRoLnRyaW0oKS5tYXRjaCgvXlxcZCskLykgPyB3aWR0aCArICclJyA6IHdpZHRoO1xuXG4gICAgICBzdHlsZXIodGhpcywge1xuICAgICAgICBmbGV4OiAnMCAwICcgKyB3aWR0aCxcbiAgICAgICAgbWF4V2lkdGg6IHdpZHRoXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxub25zRWxlbWVudHMuQ29sID0gQ29sRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWNvbCcsIENvbEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InXG5cbmV4cG9ydCBjbGFzcyBEaWFsb2dBbmltYXRvciBleHRlbmRzIEJhc2VBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBzaG93KGRpYWxvZywgZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZG9uZVxuICAgKi9cbiAgaGlkZShkaWFsb2csIGRvbmUpIHtcbiAgICBkb25lKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbmRyb2lkIHN0eWxlIGFuaW1hdG9yIGZvciBkaWFsb2cuXG4gKi9cbmV4cG9ydCBjbGFzcyBBbmRyb2lkRGlhbG9nQW5pbWF0b3IgZXh0ZW5kcyBEaWFsb2dBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdlYXNlLWluLW91dCcsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjN9ID0ge30pIHtcbiAgICBzdXBlcih7dGltaW5nLCBkZWxheSwgZHVyYXRpb259KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KGRpYWxvZywgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSksXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX2RpYWxvZywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTYwJSwgMCknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScsIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC01MCUsIC02MCUsIDApJywgb3BhY2l0eTogMCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBpT1Mgc3R5bGUgYW5pbWF0b3IgZm9yIGRpYWxvZy5cbiAqL1xuZXhwb3J0IGNsYXNzIElPU0RpYWxvZ0FuaW1hdG9yIGV4dGVuZHMgRGlhbG9nQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnZWFzZS1pbi1vdXQnLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoe3RpbWluZywgZGVsYXksIGR1cmF0aW9ufSk7XG5cbiAgICB0aGlzLmJvZHlIZWlnaHQgPSBkb2N1bWVudC5ib2R5LmNsaWVudEhlaWdodDsgLy8gYXZvaWQgRm9yY2VkIFN5bmNocm9ub3VzIExheW91dFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHNob3coZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAwIH0sIHsgb3BhY2l0eTogMSB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgtNTAlLCAke3RoaXMuYm9keUhlaWdodCAvIDIuMCAtIDF9cHgsIDApYCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCknIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGlhbG9nXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKGRpYWxvZywgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fbWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMSB9LCB7IG9wYWNpdHk6IDAgfSksXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX2RpYWxvZywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoLTUwJSwgLTUwJSwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgtNTAlLCAke3RoaXMuYm9keUhlaWdodCAvIDIuMCAtIDF9cHgsIDApYCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBTbGlkZSBhbmltYXRvciBmb3IgZGlhbG9nLlxuICovXG5leHBvcnQgY2xhc3MgU2xpZGVEaWFsb2dBbmltYXRvciBleHRlbmRzIERpYWxvZ0FuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2N1YmljLWJlemllciguMSwgLjcsIC40LCAxKScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7dGltaW5nLCBkZWxheSwgZHVyYXRpb259KTtcblxuICAgIHRoaXMuYm9keUhlaWdodCA9IGRvY3VtZW50LmJvZHkuY2xpZW50SGVpZ2h0OyAvLyBhdm9pZCBGb3JjZWQgU3luY2hyb25vdXMgTGF5b3V0XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGRpYWxvZ1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhkaWFsb2csIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdChkaWFsb2cuX21hc2ssIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH0pLFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9kaWFsb2csIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAvLyBGSVhNRTogVGhpcyBzaG91bGQgYXZvaWQgRm9yY2VkIFN5bmNocm9ub3VzIExheW91dC4gT3RoZXJ3aXNlLCBmYWRlIGFuaW1hdGlvbiBvZiBtYXNrIHdpbGwgYmUgYnJva2VuLlxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoLTUwJSwgJHstICh0aGlzLmJvZHlIZWlnaHQgLyAyLjApICsgMSAtIGRpYWxvZy5fZGlhbG9nLmNsaWVudEhlaWdodH1weCwgMClgIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBkaWFsb2dcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUoZGlhbG9nLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgPyBjYWxsYmFjayA6IGZ1bmN0aW9uKCkge307XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZGlhbG9nLl9tYXNrLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KSxcblxuICAgICAgYW5pbWl0KGRpYWxvZy5fZGlhbG9nLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNTAlLCAtNTAlLCAwKScgfSxcbiAgICAgICAgICAvLyBGSVhNRTogVGhpcyBzaG91bGQgYXZvaWQgRm9yY2VkIFN5bmNocm9ub3VzIExheW91dC4gT3RoZXJ3aXNlLCBmYWRlIGFuaW1hdGlvbiBvZiBtYXNrIHdpbGwgYmUgYnJva2VuLlxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoLTUwJSwgJHstICh0aGlzLmJvZHlIZWlnaHQgLyAyLjApICsgMSAtIGRpYWxvZy5fZGlhbG9nLmNsaWVudEhlaWdodH1weCwgMClgIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQW5pbWF0b3JGYWN0b3J5IGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9hbmltYXRvci1mYWN0b3J5JztcbmltcG9ydCB7IERpYWxvZ0FuaW1hdG9yLCBJT1NEaWFsb2dBbmltYXRvciwgQW5kcm9pZERpYWxvZ0FuaW1hdG9yLCBTbGlkZURpYWxvZ0FuaW1hdG9yIH0gZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcuZGlhbG9nJzogJ2RpYWxvZy0tKicsXG4gICcuZGlhbG9nLWNvbnRhaW5lcic6ICdkaWFsb2ctY29udGFpbmVyLS0qJyxcbiAgJy5kaWFsb2ctbWFzayc6ICdkaWFsb2ctbWFzay0tKidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdkZWZhdWx0JzogKCkgPT4gcGxhdGZvcm0uaXNBbmRyb2lkKCkgPyBBbmRyb2lkRGlhbG9nQW5pbWF0b3IgOiBJT1NEaWFsb2dBbmltYXRvcixcbiAgJ3NsaWRlJzogU2xpZGVEaWFsb2dBbmltYXRvcixcbiAgJ25vbmUnOiBEaWFsb2dBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtZGlhbG9nXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpYWxvZyB0aGF0IGlzIGRpc3BsYXllZCBvbiB0b3Agb2YgY3VycmVudCBzY3JlZW4uIEFzIG9wcG9zZWQgdG8gdGhlIGA8b25zLWFsZXJ0LWRpYWxvZz5gIGVsZW1lbnQsIHRoaXMgY29tcG9uZW50IGNhbiBjb250YWluIGFueSBraW5kIG9mIGNvbnRlbnQuXG4gKlxuICogICAgIFRvIHVzZSB0aGUgZWxlbWVudCBpdCBjYW4gZWl0aGVyIGJlIGF0dGFjaGVkIGRpcmVjdGx5IHRvIHRoZSBgPGJvZHk+YCBlbGVtZW50IG9yIGR5bmFtaWNhbGx5IGNyZWF0ZWQgZnJvbSBhIHRlbXBsYXRlIHVzaW5nIHRoZSBgb25zLmNyZWF0ZURpYWxvZyh0ZW1wbGF0ZSlgIHV0aWxpdHkgZnVuY3Rpb24gYW5kIHRoZSBgPHRlbXBsYXRlPmAgdGFnLlxuICpcbiAqICAgICBUaGUgZGlhbG9nIGlzIHVzZWZ1bCBmb3IgZGlzcGxheWluZyBtZW51cywgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvciB0byBhc2sgdGhlIHVzZXIgdG8gbWFrZSBhIGRlY2lzaW9uLlxuICpcbiAqICAgICBJdCB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZGlzcGxheWVkIGFzIE1hdGVyaWFsIERlc2lnbiB3aGVuIHJ1bm5pbmcgb24gYW4gQW5kcm9pZCBkZXZpY2UuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIGRpYWxvZy5bL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44OA44Kk44Ki44Ot44Kw44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBjb2RlcGVuIHp4eGFHYVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2RpYWxvZ1xuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNtb2RpZmllcnMgW2VuXU1vcmUgZGV0YWlscyBhYm91dCB0aGUgYG1vZGlmaWVyYCBhdHRyaWJ1dGVbL2VuXVtqYV1tb2RpZmllcuWxnuaAp+OBruS9v+OBhOaWuVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtYWxlcnQtZGlhbG9nXG4gKiAgIFtlbl1gPG9ucy1hbGVydC1kaWFsb2c+YCBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWFsZXJ0LWRpYWxvZ+OCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcG9wb3ZlclxuICogICBbZW5dYDxvbnMtcG9wb3Zlcj5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtcG9wb3ZlcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbW9kYWxcbiAqICAgW2VuXWA8b25zLW1vZGFsPmAgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1tb2RhbOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1kaWFsb2cgaWQ9XCJkaWFsb2dcIj5cbiAqICAgPHA+VGhpcyBpcyBhIGRpYWxvZyE8L3A+XG4gKiA8L29ucy1kaWFsb2c+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RpYWxvZycpLnNob3coKTtcbiAqIDwvc2NyaXB0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEaWFsb2dFbGVtZW50IGV4dGVuZHMgQmFzZURpYWxvZ0VsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBkaWFsb2cgaXMgZGlzcGxheWVkLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzooajnpLrjgZXjgozjgovnm7TliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuZGlhbG9nXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBkaWFsb2cgZnJvbSBiZWluZyBzaG93bi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjgpLlrp/ooYzjgZnjgovjgajjgIHjg4DjgqTjgqLjg63jgrDjga7ooajnpLrjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgZGlhbG9nIGlzIGRpc3BsYXllZC5bL2VuXVxuICAgKiBbamFd44OA44Kk44Ki44Ot44Kw44GM6KGo56S644GV44KM44Gf55u05b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmRpYWxvZ1xuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBkaWFsb2cgaXMgaGlkZGVuLlsvZW5dXG4gICAqIFtqYV3jg4DjgqTjgqLjg63jgrDjgYzpmqDjgozjgovnm7TliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuZGlhbG9nXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBkaWFsb2cgZnJvbSBiZWluZyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5a6f6KGM44GZ44KL44Go44CB44OA44Kk44Ki44Ot44Kw44Gu6Z2e6KGo56S644GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0aGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIGRpYWxvZyBpcyBoaWRkZW4uWy9lbl1cbiAgICogW2phXeODgOOCpOOCouODreOCsOOBjOmaoOOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5kaWFsb2dcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgZGlhbG9nLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgY2FuY2VsYWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIGRpYWxvZyBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0aGUgZGlhbG9nIGlzIGRpc2FibGVkLlsvZW5dXG4gICAqICBbamFd44GT44Gu5bGe5oCn44GM44GC44KL5pmC44CB44OA44Kk44Ki44Ot44Kw44GvZGlzYWJsZWTnirbmhYvjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlZmF1bHQgZGVmYXVsdFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYW5pbWF0aW9uIHVzZWQgd2hlbiBzaG93aW5nIGFuZCBoaWRpbmcgdGhlIGRpYWxvZy4gQ2FuIGJlIGVpdGhlciBgXCJub25lXCJgIG9yIGBcImRlZmF1bHRcImAuWy9lbl1cbiAgICogIFtqYV3jg4DjgqTjgqLjg63jgrDjgpLooajnpLrjgZnjgovpmpvjga7jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIuOCguOBl+OBj+OBr1wiZGVmYXVsdFwi44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAxLCB0aW1pbmc6ICdlYXNlLWluJ31gWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbWFzay1jb2xvclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCByZ2JhKDAsIDAsIDAsIDAuMilcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBgXCJyZ2JhKDAsIDAsIDAsIDAuMilcImAuWy9lbl1cbiAgICogIFtqYV3og4zmma/jga7jg57jgrnjgq/jga7oibLjgpLmjIflrprjgZfjgb7jgZnjgIJcInJnYmEoMCwgMCwgMCwgMC4yKVwi44GM44OH44OV44Kp44Or44OI5YCk44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuICB9XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfbWFzaygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5kaWFsb2ctbWFzaycpO1xuICB9XG5cbiAgZ2V0IF9kaWFsb2coKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcuZGlhbG9nJyk7XG4gIH1cblxuICBfdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCkge1xuICAgIHJldHVybiBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogRGlhbG9nQW5pbWF0b3IsXG4gICAgICBiYXNlQ2xhc3NOYW1lOiAnRGlhbG9nQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAxO1xuXG4gICAgLyogRXhwZWN0ZWQgcmVzdWx0OlxuICAgICAqICAgPG9ucy1kaWFsb2c+XG4gICAgICogICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctbWFza1wiPjwvZGl2PlxuICAgICAqICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nXCI+XG4gICAgICogICAgICAgPGRpdiBjbGFzcz1cImRpYWxvZy1jb250YWluZXJcIj4uLi48L2Rpdj5cbiAgICAgKiAgICAgPC9kaXY+XG4gICAgICogICA8L29ucy1kaWFsb2c+XG4gICAgICovXG5cbiAgICBpZiAoIXRoaXMuX2RpYWxvZykge1xuICAgICAgY29uc3QgZGlhbG9nID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBkaWFsb2cuY2xhc3NMaXN0LmFkZCgnZGlhbG9nJyk7XG5cbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgY29udGFpbmVyLmNsYXNzTGlzdC5hZGQoJ2RpYWxvZy1jb250YWluZXInKTtcbiAgICAgIHdoaWxlICh0aGlzLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgICB9XG4gICAgICBkaWFsb2cuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZChkaWFsb2cpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fbWFzaykge1xuICAgICAgY29uc3QgbWFzayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgbWFzay5jbGFzc0xpc3QuYWRkKCdkaWFsb2ctbWFzaycpO1xuICAgICAgdGhpcy5pbnNlcnRCZWZvcmUobWFzaywgdGhpcy5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaWFsb2cuc3R5bGUuekluZGV4ID0gMjAwMDE7XG4gICAgdGhpcy5fbWFzay5zdHlsZS56SW5kZXggPSAyMDAwMDtcblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzdGF0dXMtYmFyLWZpbGwnLCAnJyk7XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHRoaXMuX3NjaGVtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdyhbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcIm5vbmVcImAgYW5kIGBcInNsaWRlXCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcInNsaWRlXCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAgWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIHRoZSBkaWFsb2cgaGFzIGJlZW4gcmV2ZWFsZWQuWy9lbl1cbiAgICogICBbamFd44OA44Kk44Ki44Ot44Kw44GM6KGo56S644GV44KM57WC44KP44Gj44Gf5b6M44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU2hvdyB0aGUgZGlhbG9nLlsvZW5dXG4gICAqICBbamFd44OA44Kk44Ki44Ot44Kw44KS6ZaL44GN44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX0gUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50LlxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBoaWRlXG4gICAqIEBzaWduYXR1cmUgaGlkZShbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcIm5vbmVcImAgYW5kIGBcInNsaWRlXCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcInNsaWRlXCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbnMgaXMgY2FsbGVkIGFmdGVyIHRoZSBkaWFsb2cgaGFzIGJlZW4gaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeODgOOCpOOCouODreOCsOOBjOmaoOOCjOOBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRoZSBkaWFsb2cuWy9lbl1cbiAgICogICBbamFd44OA44Kk44Ki44Ot44Kw44KS6ZaJ44GY44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGhpZGRlbiBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGRpYWxvZyBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZGlhbG9nIGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGNhbmNlbGFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBkaWFsb2cgaXMgY2FuY2VsYWJsZSBvciBub3QuIEEgY2FuY2VsYWJsZSBkaWFsb2cgY2FuIGJlIGNsb3NlZCBieSB0YXBwaW5nIHRoZSBiYWNrZ3JvdW5kIG9yIGJ5IHByZXNzaW5nIHRoZSBiYWNrIGJ1dHRvbiBvbiBBbmRyb2lkIGRldmljZXMuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7RGlhbG9nQW5pbWF0b3J9IEFuaW1hdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yLnByb3RvdHlwZSBpbnN0YW5jZW9mIERpYWxvZ0FuaW1hdG9yKSkge1xuICAgICAgdXRpbC50aHJvd0FuaW1hdG9yKCdEaWFsb2cnKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IERpYWxvZ0FuaW1hdG9yKCkge1xuICAgIHJldHVybiBEaWFsb2dBbmltYXRvcjtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5EaWFsb2cgPSBEaWFsb2dFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtZGlhbG9nJywgRGlhbG9nRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgc3R5bGVyIGZyb20gJy4uL29ucy9zdHlsZXInO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnZmFiJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ2ZhYi0tKicsXG4gICcuZmFiX19pY29uJzogJ2ZhYi0tKl9faWNvbidcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWZhYlxuICogQGNhdGVnb3J5IGZvcm1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhlIEZsb2F0aW5nIGFjdGlvbiBidXR0b24gaXMgYSBjaXJjdWxhciBidXR0b24gZGVmaW5lZCBpbiB0aGUgW01hdGVyaWFsIERlc2lnbiBzcGVjaWZpY2F0aW9uXShodHRwczovL3d3dy5nb29nbGUuY29tL2Rlc2lnbi9zcGVjL2NvbXBvbmVudHMvYnV0dG9ucy1mbG9hdGluZy1hY3Rpb24tYnV0dG9uLmh0bWwpLiBUaGV5IGFyZSBvZnRlbiB1c2VkIHRvIHByb21vdGUgdGhlIHByaW1hcnkgYWN0aW9uIG9mIHRoZSBhcHAuXG4gKlxuICogICAgIEl0IGNhbiBiZSBkaXNwbGF5ZWQgZWl0aGVyIGFzIGFuIGlubGluZSBlbGVtZW50IG9yIGluIG9uZSBvZiB0aGUgY29ybmVycy4gTm9ybWFsbHkgaXQgd2lsbCBiZSBwb3NpdGlvbmVkIGluIHRoZSBsb3dlciByaWdodCBjb3JuZXIgb2YgdGhlIHNjcmVlbi5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvZmFiXG4gKiBAbW9kaWZpZXIgbWluaVxuICogICBbZW5dTWFrZXMgdGhlIGBvbnMtZmFiYCBzbWFsbGVyLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAc2VlYWxzbyBvbnMtc3BlZWQtZGlhbFxuICogICBbZW5dVGhlIGA8b25zLXNwZWVkLWRpYWw+YCBjb21wb25lbnQgaXMgYSBGbG9hdGluZyBhY3Rpb24gYnV0dG9uIHRoYXQgZGlzcGxheXMgYSBtZW51IHdoZW4gdGFwcGVkLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGYWJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBidXR0b24uWy9lbl1cbiAgICogIFtqYV3jg5zjgr/jg7Pjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSByaXBwbGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgZGVmaW5lZCwgdGhlIGJ1dHRvbiB3aWxsIGhhdmUgYSByaXBwbGUgZWZmZWN0IHdoZW4gdGFwcGVkLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgcG9zaXRpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIHBvc2l0aW9uIG9mIHRoZSBidXR0b24uIFNob3VsZCBiZSBhIHN0cmluZyBsaWtlIGBcImJvdHRvbSByaWdodFwiYCBvciBgXCJ0b3AgbGVmdFwiYC4gSWYgdGhpcyBhdHRyaWJ1dGUgaXMgbm90IGRlZmluZWQgaXQgd2lsbCBiZSBkaXNwbGF5ZWQgYXMgYW4gaW5saW5lIGVsZW1lbnQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeODnOOCv+ODs+OCkueEoeWKueWMluOBmeOCi+WgtOWQiOOBr+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvLyBUaGUgZm9sbG93aW5nIHN0YXRlbWVudHMgY2FuIGJlIGV4ZWN1dGVkIGJlZm9yZSBjb250ZW50UmVhZHlcbiAgICAvLyBzaW5jZSB0aGVzZSBkbyBub3QgYWNjZXNzIHRoZSBjaGlsZHJlblxuICAgIHRoaXMuX2hpZGUoKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHRoaXMsICcuZmFiX19pY29uJykpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBjb250ZW50LmNsYXNzTGlzdC5hZGQoJ2ZhYl9faWNvbicpO1xuXG4gICAgICB1dGlsLmFycmF5RnJvbSh0aGlzLmNoaWxkTm9kZXMpLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICAgIGlmICghZWxlbWVudC50YWdOYW1lIHx8IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnb25zLXJpcHBsZScpIHtcbiAgICAgICAgICBjb250ZW50LmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlUmlwcGxlKCk7XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG5cbiAgICB0aGlzLl91cGRhdGVQb3NpdGlvbigpO1xuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc2V0SW1tZWRpYXRlKCgpID0+IHRoaXMuX3Nob3coKSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdyaXBwbGUnLCAncG9zaXRpb24nLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICB0aGlzLl91cGRhdGVSaXBwbGUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwb3NpdGlvbic6XG4gICAgICAgIHRoaXMuX3VwZGF0ZVBvc2l0aW9uKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIGlmICghdGhpcy5fbWFudWFsbHlIaWRkZW4pIHsgLy8gaWYgdXNlciBoYXMgbm90IGNhbGxlZCBvbnMtZmFiLmhpZGUoKVxuICAgICAgdGhpcy5fdG9nZ2xlKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl90b2dnbGUoZmFsc2UpKTtcbiAgfVxuXG4gIF91cGRhdGVSaXBwbGUoKSB7XG4gICAgdXRpbC51cGRhdGVSaXBwbGUodGhpcyk7XG4gIH1cblxuICBfdXBkYXRlUG9zaXRpb24oKSB7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5yZW1vdmUoXG4gICAgICAnZmFiLS10b3BfX2xlZnQnLFxuICAgICAgJ2ZhYi0tYm90dG9tX19yaWdodCcsXG4gICAgICAnZmFiLS1ib3R0b21fX2xlZnQnLFxuICAgICAgJ2ZhYi0tdG9wX19yaWdodCcsXG4gICAgICAnZmFiLS10b3BfX2NlbnRlcicsXG4gICAgICAnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICAgIGNhc2UgJ3RvcCByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCB0b3AnOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tdG9wX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvcCBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgdG9wJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLXRvcF9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCBib3R0b20nOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tYm90dG9tX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgYm90dG9tJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLWJvdHRvbV9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciB0b3AnOlxuICAgICAgY2FzZSAndG9wIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS10b3BfX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciBib3R0b20nOlxuICAgICAgY2FzZSAnYm90dG9tIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dcbiAgICogQHNpZ25hdHVyZSBzaG93KClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU2hvdyB0aGUgZmxvYXRpbmcgYWN0aW9uIGJ1dHRvbi5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuICBzaG93KCkge1xuICAgIHRoaXMudG9nZ2xlKHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1IaWRlIHRoZSBmbG9hdGluZyBhY3Rpb24gYnV0dG9uLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG4gIGhpZGUoKSB7XG4gICAgdGhpcy50b2dnbGUoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICB0b2dnbGUoYWN0aW9uID0gIXRoaXMudmlzaWJsZSkge1xuICAgIHRoaXMuX21hbnVhbGx5SGlkZGVuID0gIWFjdGlvbjtcbiAgICB0aGlzLl90b2dnbGUoYWN0aW9uKTtcbiAgfVxuXG4gIF90b2dnbGUoYWN0aW9uID0gIXRoaXMudmlzaWJsZSkge1xuICAgIGNvbnN0IGlzQm90dG9tID0gKHRoaXMuZ2V0QXR0cmlidXRlKCdwb3NpdGlvbicpIHx8ICcnKS5pbmRleE9mKCdib3R0b20nKSA+PSAwO1xuICAgIGNvbnN0IHRyYW5zbGF0ZSA9IGlzQm90dG9tID8gYHRyYW5zbGF0ZTNkKDBweCwgLSR7dXRpbC5nbG9iYWxzLmZhYk9mZnNldCB8fCAwfXB4LCAwcHgpYCA6ICcnO1xuXG4gICAgc3R5bGVyKHRoaXMsIHsgdHJhbnNmb3JtOiBgJHt0cmFuc2xhdGV9IHNjYWxlKCR7TnVtYmVyKGFjdGlvbil9KWAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuICAgIHJldHVybiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZSh0aGlzLCAnZGlzYWJsZWQnLCB2YWx1ZSk7XG4gIH1cblxuICBnZXQgZGlzYWJsZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGFzQXR0cmlidXRlKCdkaXNhYmxlZCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIGdldCB2aXNpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLnN0eWxlLnRyYW5zZm9ybS5pbmRleE9mKCdzY2FsZSgwKScpID09PSAtMSAmJiB0aGlzLnN0eWxlLmRpc3BsYXkgIT09ICdub25lJztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5GYWIgPSBGYWJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtZmFiJywgRmFiRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vb25zL2dlc3R1cmUtZGV0ZWN0b3InO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1nZXN0dXJlLWRldGVjdG9yXG4gKiBAY2F0ZWdvcnkgZ2VzdHVyZVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBDb21wb25lbnQgdG8gZGV0ZWN0IGZpbmdlciBnZXN0dXJlcyB3aXRoaW4gdGhlIHdyYXBwZWQgZWxlbWVudC4gRm9sbG93aW5nIGdlc3R1cmVzIGFyZSBzdXBwb3J0ZWQ6XG4gKiAgICAgLSBEcmFnIGdlc3R1cmVzOiBgZHJhZ2AsIGBkcmFnbGVmdGAsIGBkcmFncmlnaHRgLCBgZHJhZ3VwYCwgYGRyYWdkb3duYFxuICogICAgIC0gSG9sZCBnZXN0dXJlczogYGhvbGRgLCBgcmVsZWFzZWBcbiAqICAgICAtIFN3aXBlIGdlc3R1cmVzOiBgc3dpcGVgLCBgc3dpcGVsZWZ0YCwgYHN3aXBlcmlnaHRgLCBgc3dpcGV1cGAsIGBzd2lwZWRvd25gXG4gKiAgICAgLSBUYXAgZ2VzdHVyZXM6IGB0YXBgLCBgZG91YmxldGFwYFxuICogICAgIC0gUGluY2ggZ2VzdHVyZXM6IGBwaW5jaGAsIGBwaW5jaGluYCwgYHBpbmNob3V0YFxuICogICAgIC0gT3RoZXIgZ2VzdHVyZXM6IGB0b3VjaGAsIGB0cmFuc2Zvcm1gLCBgcm90YXRlYFxuICogICBbL2VuXVxuICogICBbamFd6KaB57Sg5YaF44Gu44K444Kn44K544OB44Oj44O85pON5L2c44KS5qSc55+l44GX44G+44GZ44CC6Kmz44GX44GP44Gv44Ks44Kk44OJ44KS5Y+C54Wn44GX44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAqIEBndWlkZSBmZWF0dXJlcy5odG1sI2dlc3R1cmUtZGV0ZWN0aW9uXG4gKiAgIFtlbl1EZXRlY3RpbmcgZmluZ2VyIGdlc3R1cmVzWy9lbl1cbiAqICAgW2phXeOCuOOCp+OCueODgeODo+ODvOaTjeS9nOOBruaknOefpVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1nZXN0dXJlLWRldGVjdG9yPlxuICogICA8ZGl2IGlkPVwiZGV0ZWN0LWFyZWFcIiBzdHlsZT1cIndpZHRoOiAxMDBweDsgaGVpZ2h0OiAxMDBweDtcIj5cbiAqICAgICBTd2lwZSBIZXJlXG4gKiAgIDwvZGl2PlxuICogPC9vbnMtZ2VzdHVyZS1kZXRlY3Rvcj5cbiAqXG4gKiA8c2NyaXB0PlxuICogICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzd2lwZWxlZnQnLCBmdW5jdGlvbihldmVudCkge1xuICogICAgIGlmIChldmVudC50YXJnZXQubWF0Y2hlcygnI2RldGVjdC1hcmVhJykpIHtcbiAqICAgICAgIGNvbnNvbGUubG9nKCdTd2lwZSBsZWZ0IGlzIGRldGVjdGVkLicpO1xuICogICAgIH1cbiAqICAgfSk7XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgR2VzdHVyZURldGVjdG9yRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciA9IG5ldyBHZXN0dXJlRGV0ZWN0b3IodGhpcywgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkdlc3R1cmVEZXRlY3RvciA9IEdlc3R1cmVEZXRlY3RvckVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1nZXN0dXJlLWRldGVjdG9yJywgR2VzdHVyZURldGVjdG9yRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcblxubGV0IGF1dG9QcmVmaXggPSAnZmEnOyAvLyBGSVhNRTogVG8gYmUgcmVtb3ZlZCBpbiB2M1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1pY29uXG4gKiBAY2F0ZWdvcnkgdmlzdWFsXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIERpc3BsYXlzIGFuIGljb24uIFRoZSBmb2xsb3dpbmcgaWNvbiBzdWl0ZXMgYXJlIGF2YWlsYWJsZTpcbiAqXG4gKiAgICAgKiBbRm9udCBBd2Vzb21lXShodHRwczovL2ZvcnRhd2Vzb21lLmdpdGh1Yi5pby9Gb250LUF3ZXNvbWUvKVxuICogICAgICogW0lvbmljb25zXShodHRwOi8vaW9uaWNvbnMuY29tLylcbiAqICAgICAqIFtNYXRlcmlhbCBEZXNpZ24gSWNvbmljIEZvbnRdKGh0dHA6Ly96YXZvbG9rbG9tLmdpdGh1Yi5pby9tYXRlcmlhbC1kZXNpZ24taWNvbmljLWZvbnQvKVxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIHhBaHZnXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvaWNvblxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdWy9qYV1cbiAqIEBndWlkZSBhcHBzaXplLmh0bWwjcmVtb3ZpbmctaWNvbi1wYWNrcyBbZW5dUmVtb3ZpbmcgaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQGd1aWRlIGZhcS5odG1sI2hvdy1jYW4taS11c2UtY3VzdG9tLWljb24tcGFja3MgW2VuXUFkZGluZyBjdXN0b20gaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtaWNvblxuICogICBpY29uPVwibWQtY2FyXCJcbiAqICAgc2l6ZT1cIjIwcHhcIlxuICogICBzdHlsZT1cImNvbG9yOiByZWRcIj5cbiAqIDwvb25zLWljb24+XG4gKlxuICogPG9ucy1idXR0b24+XG4gKiAgIDxvbnMtaWNvbiBpY29uPVwibWQtY2FyXCI+PC9vbnMtaWNvbj5cbiAqICAgQ2FyXG4gKiA8L29ucy1idXR0b24+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEljb25FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGljb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgVGhlIGljb24gbmFtZS4gYFwibWQtXCJgIHByZWZpeCBmb3IgTWF0ZXJpYWwgSWNvbnMsIGBcImZhLVwiYCBmb3IgRm9udCBBd2Vzb21lIGFuZCBgXCJpb24tXCJgIHByZWZpeCBmb3IgSW9uaWNvbnMuXG4gICAqXG4gICAqICAgICBTZWUgYWxsIGF2YWlsYWJsZSBpY29ucyBvbiB0aGUgZWxlbWVudCBkZXNjcmlwdGlvbiAoYXQgdGhlIHRvcCkuXG4gICAqXG4gICAqICAgICBJY29ucyBjYW4gYWxzbyBiZSBzdHlsZWQgYmFzZWQgb24gbW9kaWZpZXIgcHJlc2VuY2UuIEFkZCBjb21tYS1zZXBhcmF0ZWQgaWNvbnMgd2l0aCBgXCJtb2RpZmllck5hbWU6XCJgIHByZWZpeC5cbiAgICpcbiAgICogICAgIFRoZSBjb2RlIGA8b25zLWljb24gaWNvbj1cImlvbi1lZGl0LCBtYXRlcmlhbDptZC1lZGl0XCI+PC9vbnMtaWNvbj5gIHdpbGwgZGlzcGxheSBgXCJtZC1lZGl0XCJgIGZvciBNYXRlcmlhbCBEZXNpZ24gYW5kIGBcImlvbi1lZGl0XCJgIGFzIHRoZSBkZWZhdWx0IGljb24uXG4gICAqXG4gICAqICAgICBgZmEtYCBwcmVmaXggaXMgYWRkZWQgYXV0b21hdGljYWxseSBpZiBub25lIGlzIHByb3ZpZGVkLiBDaGVjayBbU2VlIGFsc29dKCNzZWVhbHNvKSBzZWN0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNpemVcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgVGhlIHNpemVzIG9mIHRoZSBpY29uLiBWYWxpZCB2YWx1ZXMgYXJlIGxnLCAyeCwgM3gsIDR4LCA1eCwgb3IgaW4gdGhlIHNpemUgaW4gcGl4ZWxzLlxuICAgKiAgICAgSWNvbnMgY2FuIGFsc28gYmUgc3R5bGVkIGJhc2VkIG9uIG1vZGlmaWVyIHByZXNlbmNlLiBBZGQgY29tbWEtc2VwYXJhdGVkIGljb25zIHdpdGggYFwibW9kaWZpZXJOYW1lOlwiYCBwcmVmaXguXG4gICAqXG4gICAqICAgICBUaGUgY29kZTpcbiAgICpcbiAgICogICAgIGBgYFxuICAgKiAgICAgPG9ucy1pY29uXG4gICAqICAgICAgIGljb249XCJpb24tZWRpdFwiXG4gICAqICAgICAgIHNpemU9XCIzMnB4LCBtYXRlcmlhbDoyNHB4XCI+XG4gICAqICAgICA8L29ucy1pY29uPlxuICAgKiAgICAgYGBgXG4gICAqXG4gICAqICAgICB3aWxsIHJlbmRlciBhcyBhIGAyNHB4YCBpY29uIGlmIHRoZSBgXCJtYXRlcmlhbFwiYCBtb2RpZmllciBpcyBwcmVzZW50IGFuZCBgMzJweGAgb3RoZXJ3aXNlLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJvdGF0ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dTnVtYmVyIG9mIGRlZ3JlZXMgdG8gcm90YXRlIHRoZSBpY29uLiBWYWxpZCB2YWx1ZXMgYXJlIDkwLCAxODAgYW5kIDI3MC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgqTjgrPjg7PjgpLlm57ou6LjgZfjgabooajnpLrjgZfjgb7jgZnjgII5MCwgMTgwLCAyNzDjgYvjgonmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBmaXhlZC13aWR0aFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dV2hlbiB1c2VkIGluIGEgbGlzdCwgeW91IHdhbnQgdGhlIGljb25zIHRvIGhhdmUgdGhlIHNhbWUgd2lkdGggc28gdGhhdCB0aGV5IGFsaWduIHZlcnRpY2FsbHkgYnkgZGVmaW5pbmcgdGhpcyBhdHRyaWJ1dGUuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzcGluXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHdoZXRoZXIgdGhlIGljb24gc2hvdWxkIGJlIHNwaW5uaW5nLlsvZW5dXG4gICAqICAgW2phXeOCouOCpOOCs+ODs+OCkuWbnui7ouOBmeOCi+OBi+OBqeOBhuOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnaWNvbicsICdzaXplJywgJ21vZGlmaWVyJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHRoaXMuX2NsZWFuQ2xhc3NBdHRyaWJ1dGUobmFtZSA9PT0gJ2ljb24nID8gbGFzdCA6IHRoaXMuZ2V0QXR0cmlidXRlKCdpY29uJyksIG5hbWUgPT09ICdtb2RpZmllcicgPyBsYXN0IDogdW5kZWZpbmVkKTtcbiAgICB0aGlzLl91cGRhdGUoKTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuICAgIHRoaXMuX3VwZGF0ZSgpO1xuICB9XG5cbiAgX3VwZGF0ZSgpIHtcbiAgICBjb25zdCB7Y2xhc3NMaXN0LCBzdHlsZX0gPSB0aGlzLl9idWlsZENsYXNzQW5kU3R5bGUodGhpcy5fcGFyc2VBdHRyKCdpY29uJyksIHRoaXMuX3BhcnNlQXR0cignc2l6ZScpKTtcbiAgICB1dGlsLmV4dGVuZCh0aGlzLnN0eWxlLCBzdHlsZSk7XG5cbiAgICBjbGFzc0xpc3QuZm9yRWFjaChjbGFzc05hbWUgPT4gdGhpcy5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSkpO1xuICB9XG5cbiAgX3BhcnNlQXR0cihhdHRyTmFtZSwgbW9kaWZpZXIgPSB0aGlzLmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSB8fCAnJykge1xuICAgIGNvbnN0IGF0dHIgPSB0aGlzLmdldEF0dHJpYnV0ZShhdHRyTmFtZSkgfHwgYXR0ck5hbWUgfHwgJydcbiAgICBjb25zdCBwYXJ0cyA9IGF0dHIuc3BsaXQoL1xccyosXFxzKi8pO1xuICAgIGNvbnN0IGRlZiA9IHBhcnRzWzBdO1xuICAgIGxldCBtZCA9IHBhcnRzWzFdO1xuICAgIG1kID0gKG1kIHx8ICcnKS5zcGxpdCgvXFxzKjpcXHMqLyk7XG5cbiAgICByZXR1cm4gKG1vZGlmaWVyICYmIChSZWdFeHAoYChefFxcXFxzKykke21kWzBdfSgkfFxcXFxzKylgLCAnaScpLnRlc3QobW9kaWZpZXIpKSA/IG1kWzFdIDogZGVmKSB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdW5uZWVkZWQgY2xhc3MgdmFsdWUuXG4gICAqL1xuICBfY2xlYW5DbGFzc0F0dHJpYnV0ZShsYXN0SWNvbiwgbGFzdE1vZGlmaWVyKSB7XG4gICAgY29uc3QgeyBjbGFzc05hbWUsIHByZWZpeCB9ID0gdGhpcy5fcHJlZml4SWNvbih0aGlzLl9wYXJzZUF0dHIobGFzdEljb24sIGxhc3RNb2RpZmllcikpO1xuICAgIGNvbnN0IGN1c3RvbVByZWZpeFJFID0gY2xhc3NOYW1lICE9PSBwcmVmaXggPyBgfCR7cHJlZml4fSR8JHtwcmVmaXh9LWAgOiBgfCR7Y2xhc3NOYW1lfSRgIHx8ICcnO1xuICAgIGNvbnN0IHJlID0gbmV3IFJlZ0V4cChgXihmYSR8ZmEtfGlvbi18em1kaSR8em1kaS18b25zLWljb24tLSR7Y3VzdG9tUHJlZml4UkV9KWApO1xuXG4gICAgdXRpbC5hcnJheUZyb20odGhpcy5jbGFzc0xpc3QpXG4gICAgICAuZmlsdGVyKGNsYXNzTmFtZSA9PiByZS50ZXN0KGNsYXNzTmFtZSkpXG4gICAgICAuZm9yRWFjaChjbGFzc05hbWUgPT4gdGhpcy5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSkpO1xuICB9XG5cbiAgX3ByZWZpeEljb24oaWNvbk5hbWUpIHtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBhdXRvUHJlZml4ICsgKGF1dG9QcmVmaXggPyAnLScgOiAnJykgKyBpY29uTmFtZTtcbiAgICByZXR1cm4geyBjbGFzc05hbWUsIHByZWZpeDogY2xhc3NOYW1lLnNwbGl0KCctJylbMF0gfTtcbiAgfVxuXG4gIF9idWlsZENsYXNzQW5kU3R5bGUoaWNvbk5hbWUsIHNpemUpIHtcbiAgICBjb25zdCBjbGFzc0xpc3QgPSBbJ29ucy1pY29uJ107XG4gICAgY29uc3Qgc3R5bGUgPSB7fTtcblxuICAgIC8vIEljb25cbiAgICBpZiAoaWNvbk5hbWUuaW5kZXhPZignaW9uLScpID09PSAwKSB7XG4gICAgICBjbGFzc0xpc3QucHVzaChpY29uTmFtZSk7XG4gICAgICBjbGFzc0xpc3QucHVzaCgnb25zLWljb24tLWlvbicpO1xuICAgIH0gZWxzZSBpZiAoaWNvbk5hbWUuaW5kZXhPZignZmEtJykgPT09IDApIHtcbiAgICAgIGNsYXNzTGlzdC5wdXNoKGljb25OYW1lKTtcbiAgICAgIC8vIGRlZmF1bHQgaWNvbiBzdHlsZSB0byBGb250IEF3ZXNvbWUgU29saWQgaWYgaWNvbiBzdHlsZSBpcyBub3Qgc3BlY2lmaWVkIGFscmVhZHlcbiAgICAgIGlmICghKHRoaXMuY2xhc3NMaXN0LmNvbnRhaW5zKCdmYXInKSB8fCB0aGlzLmNsYXNzTGlzdC5jb250YWlucygnZmFiJykgfHwgdGhpcy5jbGFzc0xpc3QuY29udGFpbnMoJ2ZhbCcpKSkge1xuICAgICAgICBjbGFzc0xpc3QucHVzaCgnZmEnKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGljb25OYW1lLmluZGV4T2YoJ21kLScpID09PSAwKSAge1xuICAgICAgY2xhc3NMaXN0LnB1c2goJ3ptZGknKTtcbiAgICAgIGNsYXNzTGlzdC5wdXNoKCd6bWRpLScgKyBpY29uTmFtZS5zcGxpdCgvLSguKyk/LylbMV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgcHJlZml4IH0gPSB0aGlzLl9wcmVmaXhJY29uKGljb25OYW1lKTtcbiAgICAgIHByZWZpeCAmJiBjbGFzc0xpc3QucHVzaChwcmVmaXgpO1xuICAgICAgY2xhc3NOYW1lICYmIGNsYXNzTGlzdC5wdXNoKGNsYXNzTmFtZSk7XG4gICAgfVxuXG4gICAgLy8gU2l6ZVxuICAgIGlmIChzaXplLm1hdGNoKC9eWzEtNV14fGxnJC8pKSB7XG4gICAgICBjbGFzc0xpc3QucHVzaCgnb25zLWljb24tLScgKyBzaXplKTtcbiAgICAgIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2ZvbnQtc2l6ZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZS5mb250U2l6ZSA9IHNpemU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYXNzTGlzdDogY2xhc3NMaXN0LFxuICAgICAgc3R5bGU6IHN0eWxlXG4gICAgfTtcbiAgfVxuXG4gIHN0YXRpYyBzZXRBdXRvUHJlZml4KHByZWZpeCkge1xuICAgIGF1dG9QcmVmaXggPSBwcmVmaXggPyAodHlwZW9mIHByZWZpeCA9PT0gJ3N0cmluZycgJiYgcHJlZml4IHx8ICdmYScpIDogJyc7XG4gIH1cbn1cblxub25zRWxlbWVudHMuSWNvbiA9IEljb25FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtaWNvbicsIEljb25FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uL3BsYXRmb3JtJztcblxuZXhwb3J0IGNsYXNzIExhenlSZXBlYXREZWxlZ2F0ZSB7XG5cbiAgY29uc3RydWN0b3IodXNlckRlbGVnYXRlLCB0ZW1wbGF0ZUVsZW1lbnQgPSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiB1c2VyRGVsZWdhdGUgIT09ICdvYmplY3QnIHx8IHVzZXJEZWxlZ2F0ZSA9PT0gbnVsbCkge1xuICAgICAgdXRpbC50aHJvdygnXCJkZWxlZ2F0ZVwiIHBhcmFtZXRlciBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cbiAgICB0aGlzLl91c2VyRGVsZWdhdGUgPSB1c2VyRGVsZWdhdGU7XG5cbiAgICBpZiAoISh0ZW1wbGF0ZUVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSAmJiB0ZW1wbGF0ZUVsZW1lbnQgIT09IG51bGwpIHtcbiAgICAgIHV0aWwudGhyb3coJ1widGVtcGxhdGVFbGVtZW50XCIgcGFyYW1ldGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgRWxlbWVudCBvciBudWxsJyk7XG4gICAgfVxuICAgIHRoaXMuX3RlbXBsYXRlRWxlbWVudCA9IHRlbXBsYXRlRWxlbWVudDtcbiAgfVxuXG4gIGdldCBpdGVtSGVpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLl91c2VyRGVsZWdhdGUuaXRlbUhlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaGFzUmVuZGVyRnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3VzZXJEZWxlZ2F0ZS5fcmVuZGVyIGluc3RhbmNlb2YgRnVuY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICovXG4gIF9yZW5kZXIoKSB7XG4gICAgdGhpcy5fdXNlckRlbGVnYXRlLl9yZW5kZXIuYXBwbHkodGhpcy5fdXNlckRlbGVnYXRlLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lIEEgZnVuY3Rpb24gdGhhdCB0YWtlIGl0ZW0gb2JqZWN0IGFzIHBhcmFtZXRlci5cbiAgICovXG4gIGxvYWRJdGVtRWxlbWVudChpbmRleCwgZG9uZSkge1xuICAgIGlmICh0aGlzLl91c2VyRGVsZWdhdGUubG9hZEl0ZW1FbGVtZW50IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIHRoaXMuX3VzZXJEZWxlZ2F0ZS5sb2FkSXRlbUVsZW1lbnQoaW5kZXgsIGRvbmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fdXNlckRlbGVnYXRlLmNyZWF0ZUl0ZW1Db250ZW50KGluZGV4LCB0aGlzLl90ZW1wbGF0ZUVsZW1lbnQpO1xuICAgICAgaWYgKCEoZWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7XG4gICAgICAgIHV0aWwudGhyb3coJ1wiY3JlYXRlSXRlbUNvbnRlbnRcIiBtdXN0IHJldHVybiBhbiBpbnN0YW5jZSBvZiBFbGVtZW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGRvbmUoe2VsZW1lbnR9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7TnVtYmVyfVxuICAgKi9cbiAgY291bnRJdGVtcygpIHtcbiAgICBjb25zdCBjb3VudCA9IHRoaXMuX3VzZXJEZWxlZ2F0ZS5jb3VudEl0ZW1zKCk7XG4gICAgaWYgKHR5cGVvZiBjb3VudCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wiY291bnRJdGVtc1wiIG11c3QgcmV0dXJuIGEgbnVtYmVyJyk7XG4gICAgfVxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW1cbiAgICogQHBhcmFtIHtFbGVtZW50fSBpdGVtLmVsZW1lbnRcbiAgICovXG4gIHVwZGF0ZUl0ZW0oaW5kZXgsIGl0ZW0pIHtcbiAgICBpZiAodGhpcy5fdXNlckRlbGVnYXRlLnVwZGF0ZUl0ZW1Db250ZW50IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIHRoaXMuX3VzZXJEZWxlZ2F0ZS51cGRhdGVJdGVtQ29udGVudChpbmRleCwgaXRlbSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICovXG4gIGNhbGN1bGF0ZUl0ZW1IZWlnaHQoaW5kZXgpIHtcbiAgICBpZiAodGhpcy5fdXNlckRlbGVnYXRlLmNhbGN1bGF0ZUl0ZW1IZWlnaHQgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5fdXNlckRlbGVnYXRlLmNhbGN1bGF0ZUl0ZW1IZWlnaHQoaW5kZXgpO1xuXG4gICAgICBpZiAodHlwZW9mIGhlaWdodCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdXRpbC50aHJvdygnXCJjYWxjdWxhdGVJdGVtSGVpZ2h0XCIgbXVzdCByZXR1cm4gYSBudW1iZXInKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGhlaWdodDtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtPYmplY3R9IGl0ZW1cbiAgICovXG4gIGRlc3Ryb3lJdGVtKGluZGV4LCBpdGVtKSB7XG4gICAgaWYgKHRoaXMuX3VzZXJEZWxlZ2F0ZS5kZXN0cm95SXRlbSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLl91c2VyRGVsZWdhdGUuZGVzdHJveUl0ZW0oaW5kZXgsIGl0ZW0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fdXNlckRlbGVnYXRlLmRlc3Ryb3kgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgdGhpcy5fdXNlckRlbGVnYXRlLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICB0aGlzLl91c2VyRGVsZWdhdGUgPSB0aGlzLl90ZW1wbGF0ZUVsZW1lbnQgPSBudWxsO1xuICB9XG59XG5cbi8qKlxuICogVGhpcyBjbGFzcyBwcm92aWRlIGNvcmUgZnVuY3Rpb25zIGZvciBvbnMtbGF6eS1yZXBlYXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYXp5UmVwZWF0UHJvdmlkZXIge1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IHdyYXBwZXJFbGVtZW50XG4gICAqIEBwYXJhbSB7TGF6eVJlcGVhdERlbGVnYXRlfSBkZWxlZ2F0ZVxuICAgKi9cbiAgY29uc3RydWN0b3Iod3JhcHBlckVsZW1lbnQsIGRlbGVnYXRlKSB7XG4gICAgaWYgKCEoZGVsZWdhdGUgaW5zdGFuY2VvZiBMYXp5UmVwZWF0RGVsZWdhdGUpKSB7XG4gICAgICB1dGlsLnRocm93KCdcImRlbGVnYXRlXCIgcGFyYW1ldGVyIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgTGF6eVJlcGVhdERlbGVnYXRlJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fd3JhcHBlckVsZW1lbnQgPSB3cmFwcGVyRWxlbWVudDtcbiAgICB0aGlzLl9kZWxlZ2F0ZSA9IGRlbGVnYXRlO1xuICAgIHRoaXMuX2luc2VydEluZGV4ID0gKHRoaXMuX3dyYXBwZXJFbGVtZW50LmNoaWxkcmVuWzBdICYmIHRoaXMuX3dyYXBwZXJFbGVtZW50LmNoaWxkcmVuWzBdLnRhZ05hbWUgPT09ICdPTlMtTEFaWS1SRVBFQVQnKSA/IDEgOiAwO1xuXG4gICAgaWYgKHdyYXBwZXJFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ29ucy1saXN0Jykge1xuICAgICAgd3JhcHBlckVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnbGF6eS1saXN0Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5fcGFnZUNvbnRlbnQgPSB0aGlzLl9maW5kUGFnZUNvbnRlbnRFbGVtZW50KHdyYXBwZXJFbGVtZW50KTtcblxuICAgIGlmICghdGhpcy5fcGFnZUNvbnRlbnQpIHtcbiAgICAgIHV0aWwudGhyb3coJ0xhenlSZXBlYXQgbXVzdCBiZSBkZXNjZW5kYW50IG9mIGEgUGFnZSBlbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5sYXN0U2Nyb2xsVG9wID0gdGhpcy5fcGFnZUNvbnRlbnQuc2Nyb2xsVG9wO1xuICAgIHRoaXMucGFkZGluZyA9IDA7XG4gICAgdGhpcy5fdG9wUG9zaXRpb25zID0gWzBdO1xuICAgIHRoaXMuX3JlbmRlcmVkSXRlbXMgPSB7fTtcblxuICAgIGlmICghdGhpcy5fZGVsZWdhdGUuaXRlbUhlaWdodCAmJiAhdGhpcy5fZGVsZWdhdGUuY2FsY3VsYXRlSXRlbUhlaWdodCgwKSkge1xuICAgICAgdGhpcy5fdW5rbm93bkl0ZW1IZWlnaHQgPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuX2FkZEV2ZW50TGlzdGVuZXJzKCk7XG4gICAgdGhpcy5fb25DaGFuZ2UoKTtcbiAgfVxuXG4gIGdldCBwYWRkaW5nKCkge1xuICAgIHJldHVybiBwYXJzZUludCh0aGlzLl93cmFwcGVyRWxlbWVudC5zdHlsZS5wYWRkaW5nVG9wLCAxMCk7XG4gIH1cblxuICBzZXQgcGFkZGluZyhuZXdWYWx1ZSkge1xuICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnN0eWxlLnBhZGRpbmdUb3AgPSBuZXdWYWx1ZSArICdweCc7XG4gIH1cblxuICBfZmluZFBhZ2VDb250ZW50RWxlbWVudCh3cmFwcGVyRWxlbWVudCkge1xuICAgIGNvbnN0IHBhZ2VDb250ZW50ID0gdXRpbC5maW5kUGFyZW50KHdyYXBwZXJFbGVtZW50LCAnLnBhZ2VfX2NvbnRlbnQnKTtcblxuICAgIGlmIChwYWdlQ29udGVudCkge1xuICAgICAgcmV0dXJuIHBhZ2VDb250ZW50O1xuICAgIH1cblxuICAgIGNvbnN0IHBhZ2UgPSB1dGlsLmZpbmRQYXJlbnQod3JhcHBlckVsZW1lbnQsICdvbnMtcGFnZScpO1xuICAgIGlmIChwYWdlKSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gdXRpbC5maW5kQ2hpbGQocGFnZSwgJy5jb250ZW50Jyk7XG4gICAgICBpZiAoY29udGVudCkge1xuICAgICAgICByZXR1cm4gY29udGVudDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIF9jaGVja0l0ZW1IZWlnaHQoY2FsbGJhY2spIHtcbiAgICB0aGlzLl9kZWxlZ2F0ZS5sb2FkSXRlbUVsZW1lbnQoMCwgaXRlbSA9PiB7XG4gICAgICBpZiAoIXRoaXMuX3Vua25vd25JdGVtSGVpZ2h0KSB7XG4gICAgICAgIHV0aWwudGhyb3coJ0ludmFsaWQgc3RhdGUnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuYXBwZW5kQ2hpbGQoaXRlbS5lbGVtZW50KTtcblxuICAgICAgY29uc3QgZG9uZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5fZGVsZWdhdGUuZGVzdHJveUl0ZW0oMCwgaXRlbSk7XG4gICAgICAgIGl0ZW0uZWxlbWVudCAmJiBpdGVtLmVsZW1lbnQucmVtb3ZlKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl91bmtub3duSXRlbUhlaWdodDtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuX2l0ZW1IZWlnaHQgPSBpdGVtLmVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICBpZiAodGhpcy5faXRlbUhlaWdodCA+IDApIHtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIHJldHJ5IHRvIG1lYXN1cmUgb2Zmc2V0IGhlaWdodFxuICAgICAgLy8gZGlydHkgZml4IGZvciBhbmd1bGFyMiBkaXJlY3RpdmVcbiAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICAgIGl0ZW0uZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG5cbiAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2l0ZW1IZWlnaHQgPSBpdGVtLmVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBpZiAodGhpcy5faXRlbUhlaWdodCA9PSAwKSB7XG4gICAgICAgICAgdXRpbC50aHJvdygnSW52YWxpZCBzdGF0ZTogXCJpdGVtSGVpZ2h0XCIgbXVzdCBiZSBncmVhdGVyIHRoYW4gemVybycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAnJztcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgc3RhdGljSXRlbUhlaWdodCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVsZWdhdGUuaXRlbUhlaWdodCB8fCB0aGlzLl9pdGVtSGVpZ2h0O1xuICB9XG4gIF9jb3VudEl0ZW1zKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWxlZ2F0ZS5jb3VudEl0ZW1zKCk7XG4gIH1cblxuICBfZ2V0SXRlbUhlaWdodChpKSB7XG4gICAgLy8gSXRlbSBpcyByZW5kZXJlZFxuICAgIGlmICh0aGlzLl9yZW5kZXJlZEl0ZW1zLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICBpZiAoIXRoaXMuX3JlbmRlcmVkSXRlbXNbaV0uaGFzT3duUHJvcGVydHkoJ2hlaWdodCcpKSB7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVkSXRlbXNbaV0uaGVpZ2h0ID0gdGhpcy5fcmVuZGVyZWRJdGVtc1tpXS5lbGVtZW50Lm9mZnNldEhlaWdodDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9yZW5kZXJlZEl0ZW1zW2ldLmhlaWdodDtcbiAgICB9XG5cbiAgICAvLyBJdGVtIGlzIG5vdCByZW5kZXJlZCwgc2Nyb2xsIHVwXG4gICAgaWYgKHRoaXMuX3RvcFBvc2l0aW9uc1tpICsgMV0gJiYgdGhpcy5fdG9wUG9zaXRpb25zW2ldKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdG9wUG9zaXRpb25zW2kgKyAxXSAtIHRoaXMuX3RvcFBvc2l0aW9uc1tpXTtcbiAgICB9XG4gICAgLy8gSXRlbSBpcyBub3QgcmVuZGVyZWQsIHNjcm9sbCBkb3duXG4gICAgcmV0dXJuIHRoaXMuc3RhdGljSXRlbUhlaWdodCB8fCB0aGlzLl9kZWxlZ2F0ZS5jYWxjdWxhdGVJdGVtSGVpZ2h0KGkpO1xuICB9XG5cbiAgX2NhbGN1bGF0ZVJlbmRlcmVkSGVpZ2h0KCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLl9yZW5kZXJlZEl0ZW1zKS5yZWR1Y2UoKGEsIGIpID0+IGEgKyB0aGlzLl9nZXRJdGVtSGVpZ2h0KCsoYikpLCAwKVxuICB9XG5cbiAgX29uQ2hhbmdlKCkge1xuICAgIHRoaXMuX3JlbmRlcigpO1xuICB9XG5cbiAgX2xhc3RJdGVtUmVuZGVyZWQoKSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KC4uLk9iamVjdC5rZXlzKHRoaXMuX3JlbmRlcmVkSXRlbXMpKTtcbiAgfVxuXG4gIF9maXJzdEl0ZW1SZW5kZXJlZCgpIHtcbiAgICByZXR1cm4gTWF0aC5taW4oLi4uT2JqZWN0LmtleXModGhpcy5fcmVuZGVyZWRJdGVtcykpO1xuICB9XG5cbiAgcmVmcmVzaCgpIHtcbiAgICBjb25zdCBmb3JjZVJlbmRlciA9IHsgZm9yY2VTY3JvbGxEb3duOiB0cnVlIH07XG4gICAgY29uc3QgZmlyc3RJdGVtSW5kZXggPSB0aGlzLl9maXJzdEl0ZW1SZW5kZXJlZCgpO1xuXG4gICAgaWYgKHV0aWwuaXNJbnRlZ2VyKGZpcnN0SXRlbUluZGV4KSkge1xuICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gdGhpcy5fdG9wUG9zaXRpb25zW2ZpcnN0SXRlbUluZGV4XSArIHRoaXMuX2NhbGN1bGF0ZVJlbmRlcmVkSGVpZ2h0KCkgKyAncHgnO1xuICAgICAgdGhpcy5wYWRkaW5nID0gdGhpcy5fdG9wUG9zaXRpb25zW2ZpcnN0SXRlbUluZGV4XTtcbiAgICAgIGZvcmNlUmVuZGVyLmZvcmNlRmlyc3RJbmRleCA9IGZpcnN0SXRlbUluZGV4O1xuICAgIH1cblxuICAgIHRoaXMuX3JlbW92ZUFsbEVsZW1lbnRzKCk7XG4gICAgdGhpcy5fcmVuZGVyKGZvcmNlUmVuZGVyKTtcbiAgICB0aGlzLl93cmFwcGVyRWxlbWVudC5zdHlsZS5oZWlnaHQgPSAnaW5oZXJpdCc7XG4gIH1cblxuICBfcmVuZGVyKHtmb3JjZVNjcm9sbERvd24gPSBmYWxzZSwgZm9yY2VGaXJzdEluZGV4LCBmb3JjZUxhc3RJbmRleH0gPSB7fSkge1xuICAgIGlmICh0aGlzLl91bmtub3duSXRlbUhlaWdodCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2NoZWNrSXRlbUhlaWdodCh0aGlzLl9yZW5kZXIuYmluZCh0aGlzLCBhcmd1bWVudHNbMF0pKTtcbiAgICB9XG5cbiAgICBjb25zdCBpc1Njcm9sbFVwID0gIWZvcmNlU2Nyb2xsRG93biAmJiB0aGlzLmxhc3RTY3JvbGxUb3AgPiB0aGlzLl9wYWdlQ29udGVudC5zY3JvbGxUb3A7XG4gICAgdGhpcy5sYXN0U2Nyb2xsVG9wID0gdGhpcy5fcGFnZUNvbnRlbnQuc2Nyb2xsVG9wO1xuICAgIGNvbnN0IGtlZXAgPSB7fTtcblxuICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuX3dyYXBwZXJFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcDtcbiAgICBjb25zdCBsaW1pdCA9IDQgKiB3aW5kb3cuaW5uZXJIZWlnaHQgLSBvZmZzZXQ7XG4gICAgY29uc3QgY291bnQgPSB0aGlzLl9jb3VudEl0ZW1zKCk7XG5cbiAgICBjb25zdCBpdGVtcyA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0ID0gZm9yY2VGaXJzdEluZGV4IHx8IE1hdGgubWF4KDAsIHRoaXMuX2NhbGN1bGF0ZVN0YXJ0SW5kZXgob2Zmc2V0KSAtIDMwKTsgLy8gUmVjYWxjdWxhdGUgZm9yIDAgb3IgdW5kZWZpbmVkXG4gICAgbGV0IGkgPSBzdGFydDtcblxuICAgIGZvciAobGV0IHRvcCA9IHRoaXMuX3RvcFBvc2l0aW9uc1tpXTsgaSA8IGNvdW50ICYmIHRvcCA8IGxpbWl0OyBpKyspIHtcbiAgICAgIGlmIChpID49IHRoaXMuX3RvcFBvc2l0aW9ucy5sZW5ndGgpIHsgLy8gcGVyZiBvcHRpbWl6YXRpb25cbiAgICAgICAgdGhpcy5fdG9wUG9zaXRpb25zLmxlbmd0aCArPSAxMDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3RvcFBvc2l0aW9uc1tpXSA9IHRvcDtcbiAgICAgIHRvcCArPSB0aGlzLl9nZXRJdGVtSGVpZ2h0KGkpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9kZWxlZ2F0ZS5oYXNSZW5kZXJGdW5jdGlvbiAmJiB0aGlzLl9kZWxlZ2F0ZS5oYXNSZW5kZXJGdW5jdGlvbigpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZGVsZWdhdGUuX3JlbmRlcihzdGFydCwgaSwgKCkgPT4ge1xuICAgICAgICB0aGlzLnBhZGRpbmcgPSB0aGlzLl90b3BQb3NpdGlvbnNbc3RhcnRdO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGlzU2Nyb2xsVXApIHtcbiAgICAgIGZvciAobGV0IGogPSBpIC0gMTsgaiA+PSBzdGFydDsgai0tKSB7XG4gICAgICAgIGtlZXBbal0gPSB0cnVlO1xuICAgICAgICB0aGlzLl9yZW5kZXJFbGVtZW50KGosIGlzU2Nyb2xsVXApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBsYXN0SW5kZXggPSBmb3JjZUxhc3RJbmRleCB8fCBNYXRoLm1heChpIC0gMSwgLi4uT2JqZWN0LmtleXModGhpcy5fcmVuZGVyZWRJdGVtcykpOyAvLyBSZWNhbGN1bGF0ZSBmb3IgMCBvciB1bmRlZmluZWRcbiAgICAgIGZvciAobGV0IGogPSBzdGFydDsgaiA8PSBsYXN0SW5kZXg7IGorKykge1xuICAgICAgICBrZWVwW2pdID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fcmVuZGVyRWxlbWVudChqLCBpc1Njcm9sbFVwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBPYmplY3Qua2V5cyh0aGlzLl9yZW5kZXJlZEl0ZW1zKS5mb3JFYWNoKGtleSA9PiBrZWVwW2tleV0gfHwgdGhpcy5fcmVtb3ZlRWxlbWVudChrZXksIGlzU2Nyb2xsVXApKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtCb29sZWFufSBpc1Njcm9sbFVwXG4gICAqL1xuICBfcmVuZGVyRWxlbWVudChpbmRleCwgaXNTY3JvbGxVcCkge1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9yZW5kZXJlZEl0ZW1zW2luZGV4XTtcbiAgICBpZiAoaXRlbSkge1xuICAgICAgdGhpcy5fZGVsZWdhdGUudXBkYXRlSXRlbShpbmRleCwgaXRlbSk7IC8vIHVwZGF0ZSBpZiBpdCBleGlzdHNcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9kZWxlZ2F0ZS5sb2FkSXRlbUVsZW1lbnQoaW5kZXgsIGl0ZW0gPT4ge1xuICAgICAgaWYgKGlzU2Nyb2xsVXApIHtcbiAgICAgICAgdGhpcy5fd3JhcHBlckVsZW1lbnQuaW5zZXJ0QmVmb3JlKGl0ZW0uZWxlbWVudCwgdGhpcy5fd3JhcHBlckVsZW1lbnQuY2hpbGRyZW5bdGhpcy5faW5zZXJ0SW5kZXhdKVxuICAgICAgICB0aGlzLnBhZGRpbmcgPSB0aGlzLl90b3BQb3NpdGlvbnNbaW5kZXhdO1xuICAgICAgICBpdGVtLmhlaWdodCA9IHRoaXMuX3RvcFBvc2l0aW9uc1tpbmRleCArIDFdIC0gdGhpcy5fdG9wUG9zaXRpb25zW2luZGV4XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3dyYXBwZXJFbGVtZW50LmFwcGVuZENoaWxkKGl0ZW0uZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlbmRlcmVkSXRlbXNbaW5kZXhdID0gaXRlbTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtCb29sZWFufSBpc1Njcm9sbFVwXG4gICAqL1xuICBfcmVtb3ZlRWxlbWVudChpbmRleCwgaXNTY3JvbGxVcCA9IHRydWUpIHtcbiAgICBpbmRleCA9ICsoaW5kZXgpO1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9yZW5kZXJlZEl0ZW1zW2luZGV4XTtcbiAgICB0aGlzLl9kZWxlZ2F0ZS5kZXN0cm95SXRlbShpbmRleCwgaXRlbSk7XG5cbiAgICBpZiAoaXNTY3JvbGxVcCkge1xuICAgICAgdGhpcy5fdG9wUG9zaXRpb25zW2luZGV4ICsgMV0gPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGFkZGluZyA9IHRoaXMucGFkZGluZyArIHRoaXMuX2dldEl0ZW1IZWlnaHQoaW5kZXgpO1xuICAgIH1cblxuICAgIGlmIChpdGVtLmVsZW1lbnQucGFyZW50RWxlbWVudCkge1xuICAgICAgaXRlbS5lbGVtZW50LnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoaXRlbS5lbGVtZW50KTtcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5fcmVuZGVyZWRJdGVtc1tpbmRleF07XG4gIH1cblxuICBfcmVtb3ZlQWxsRWxlbWVudHMoKSB7XG4gICAgT2JqZWN0LmtleXModGhpcy5fcmVuZGVyZWRJdGVtcykuZm9yRWFjaChrZXkgPT4gdGhpcy5fcmVtb3ZlRWxlbWVudChrZXkpKTtcbiAgfVxuXG4gIF9yZWNhbGN1bGF0ZVRvcFBvc2l0aW9ucyhzdGFydCwgZW5kKSB7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzLl90b3BQb3NpdGlvbnNbaSArIDFdID0gdGhpcy5fdG9wUG9zaXRpb25zW2ldICsgdGhpcy5fZ2V0SXRlbUhlaWdodChpKTtcbiAgICB9XG4gIH1cblxuICBfY2FsY3VsYXRlU3RhcnRJbmRleChjdXJyZW50KSB7XG4gICAgY29uc3QgZmlyc3RJdGVtSW5kZXggPSB0aGlzLl9maXJzdEl0ZW1SZW5kZXJlZCgpO1xuICAgIGNvbnN0IGxhc3RJdGVtSW5kZXggPSB0aGlzLl9sYXN0SXRlbVJlbmRlcmVkKCk7XG5cbiAgICAvLyBGaXggZm9yIFNhZmFyaSBzY3JvbGwgYW5kIEFuZ3VsYXIgMlxuICAgIHRoaXMuX3JlY2FsY3VsYXRlVG9wUG9zaXRpb25zKGZpcnN0SXRlbUluZGV4LCBsYXN0SXRlbUluZGV4KTtcblxuICAgIGxldCBzdGFydCA9IDA7XG4gICAgbGV0IGVuZCA9IHRoaXMuX2NvdW50SXRlbXMoKSAtIDE7XG5cbiAgICAvLyBCaW5hcnkgc2VhcmNoIGZvciBpbmRleCBhdCB0b3Agb2Ygc2NyZWVuIHNvIHdlIGNhbiBzcGVlZCB1cCByZW5kZXJpbmcuXG4gICAgZm9yICg7Oykge1xuICAgICAgY29uc3QgbWlkZGxlID0gTWF0aC5mbG9vcigoc3RhcnQgKyBlbmQpIC8gMik7XG4gICAgICBjb25zdCB2YWx1ZSA9IGN1cnJlbnQgKyB0aGlzLl90b3BQb3NpdGlvbnNbbWlkZGxlXTtcblxuICAgICAgaWYgKGVuZCA8IHN0YXJ0KSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSA8PSAwICYmIHZhbHVlICsgdGhpcy5fZ2V0SXRlbUhlaWdodChtaWRkbGUpID4gMCkge1xuICAgICAgICByZXR1cm4gbWlkZGxlO1xuICAgICAgfSBlbHNlIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPj0gMCkge1xuICAgICAgICBlbmQgPSBtaWRkbGUgLSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnQgPSBtaWRkbGUgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9kZWJvdW5jZShmdW5jLCB3YWl0LCBpbW1lZGlhdGUpIHtcbiAgICBsZXQgdGltZW91dDtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBjb25zdCBjYWxsTm93ID0gaW1tZWRpYXRlICYmICF0aW1lb3V0O1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgaWYgKGNhbGxOb3cpIHtcbiAgICAgICAgZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfSwgd2FpdCk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIF9kb3VibGVGaXJlT25Ub3VjaGVuZCgpIHtcbiAgICB0aGlzLl9yZW5kZXIoKTtcbiAgICB0aGlzLl9kZWJvdW5jZSh0aGlzLl9yZW5kZXIuYmluZCh0aGlzKSwgMTAwKTtcbiAgfVxuXG4gIF9hZGRFdmVudExpc3RlbmVycygpIHtcbiAgICB1dGlsLmJpbmRMaXN0ZW5lcnModGhpcywgWydfb25DaGFuZ2UnLCAnX2RvdWJsZUZpcmVPblRvdWNoZW5kJ10pO1xuXG4gICAgaWYgKHBsYXRmb3JtLmlzSU9TKCkpIHtcbiAgICAgIHRoaXMuX2JvdW5kT25DaGFuZ2UgPSB0aGlzLl9kZWJvdW5jZSh0aGlzLl9ib3VuZE9uQ2hhbmdlLCAzMCk7XG4gICAgfVxuXG4gICAgdGhpcy5fcGFnZUNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG5cbiAgICBpZiAocGxhdGZvcm0uaXNJT1MoKSkge1xuICAgICAgdXRpbC5hZGRFdmVudExpc3RlbmVyKHRoaXMuX3BhZ2VDb250ZW50LCAndG91Y2htb3ZlJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgdGhpcy5fcGFnZUNvbnRlbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLl9ib3VuZERvdWJsZUZpcmVPblRvdWNoZW5kLCB0cnVlKTtcbiAgICB9XG5cbiAgICB3aW5kb3cuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG4gIH1cblxuICBfcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgdGhpcy5fcGFnZUNvbnRlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG5cbiAgICBpZiAocGxhdGZvcm0uaXNJT1MoKSkge1xuICAgICAgdXRpbC5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMuX3BhZ2VDb250ZW50LCAndG91Y2htb3ZlJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgdGhpcy5fcGFnZUNvbnRlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLl9ib3VuZERvdWJsZUZpcmVPblRvdWNoZW5kLCB0cnVlKTtcbiAgICB9XG5cbiAgICB3aW5kb3cuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgdHJ1ZSk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuX3JlbW92ZUFsbEVsZW1lbnRzKCk7XG4gICAgdGhpcy5fZGVsZWdhdGUuZGVzdHJveSgpO1xuICAgIHRoaXMuX3BhcmVudEVsZW1lbnQgPSB0aGlzLl9kZWxlZ2F0ZSA9IHRoaXMuX3JlbmRlcmVkSXRlbXMgPSBudWxsO1xuICAgIHRoaXMuX3JlbW92ZUV2ZW50TGlzdGVuZXJzKCk7XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgeyBMYXp5UmVwZWF0RGVsZWdhdGUsIExhenlSZXBlYXRQcm92aWRlciB9IGZyb20gJy4uL29ucy9pbnRlcm5hbC9sYXp5LXJlcGVhdCc7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWxhenktcmVwZWF0XG4gKiBAY2F0ZWdvcnkgbGlzdFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBVc2luZyB0aGlzIGNvbXBvbmVudCBhIGxpc3Qgd2l0aCBtaWxsaW9ucyBvZiBpdGVtcyBjYW4gYmUgcmVuZGVyZWQgd2l0aG91dCBhIGRyb3AgaW4gcGVyZm9ybWFuY2UuXG4gKiAgICAgSXQgZG9lcyB0aGF0IGJ5IFwibGF6aWx5XCIgbG9hZGluZyBlbGVtZW50cyBpbnRvIHRoZSBET00gd2hlbiB0aGV5IGNvbWUgaW50byB2aWV3IGFuZFxuICogICAgIHJlbW92aW5nIGl0ZW1zIGZyb20gdGhlIERPTSB3aGVuIHRoZXkgYXJlIG5vdCB2aXNpYmxlLlxuICogICBbL2VuXVxuICogICBbamFdXG4gKiAgICAg44GT44Gu44Kz44Oz44Od44O844ON44Oz44OI5YaF44Gn5o+P55S744GV44KM44KL44Ki44Kk44OG44Og44GuRE9N6KaB57Sg44Gu6Kqt44G/6L6844G/44Gv44CB55S76Z2i44Gr6KaL44GI44Gd44GG44Gr44Gq44Gj44Gf5pmC44G+44Gn6Ieq5YuV55qE44Gr6YGF5bu244GV44KM44CBXG4gKiAgICAg55S76Z2i44GL44KJ6KaL44GI44Gq44GP44Gq44Gj44Gf5aC05ZCI44Gr44Gv44Gd44Gu6KaB57Sg44Gv5YuV55qE44Gr44Ki44Oz44Ot44O844OJ44GV44KM44G+44GZ44CCXG4gKiAgICAg44GT44Gu44Kz44Oz44Od44O844ON44Oz44OI44KS5L2/44GG44GT44Go44Gn44CB44OR44OV44Kp44O844Oe44Oz44K544KS5Yqj5YyW44GV44Gb44KL44GT44Go54Sh44GX44Gr5beo5aSn44Gq5pWw44Gu6KaB57Sg44KS5o+P55S744Gn44GN44G+44GZ44CCXG4gKiAgIFsvamFdXG4gKiBAY29kZXBlbiBRd3JHQm1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9sYXp5LXJlcGVhdFxuICogQHNlZWFsc28gb25zLWxpc3RcbiAqICAgW2VuXVRoZSBgPG9ucy1saXN0PmAgZWxlbWVudCBpcyB1c2VkIHRvIHJlbmRlciBhIGxpc3QuWy9lbl1cbiAqICAgW2phXWA8b25zLWxpc3Q+YOimgee0oOOBr+ODquOCueODiOOCkuaPj+eUu+OBmeOCi+OBruOBq+S9v+OCj+OCjOOBvuOBmeOAglsvamFdXG4gKiBAZXhhbXBsZVxuICogPHNjcmlwdD5cbiAqICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCBmdW5jdGlvbigpIHtcbiAqICAgICB2YXIgbGF6eVJlcGVhdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNsaXN0Jyk7XG4gKiAgICAgbGF6eVJlcGVhdC5kZWxlZ2F0ZSA9IHtcbiAqICAgICAgY3JlYXRlSXRlbUNvbnRlbnQ6IGZ1bmN0aW9uKGksIHRlbXBsYXRlKSB7XG4gKiAgICAgICAgdmFyIGRvbSA9IHRlbXBsYXRlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgICAgICBkb20uaW5uZXJUZXh0ID0gaTtcbiAqXG4gKiAgICAgICAgcmV0dXJuIGRvbTtcbiAqICAgICAgfSxcbiAqICAgICAgY291bnRJdGVtczogZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgcmV0dXJuIDEwMDAwMDAwO1xuICogICAgICB9LFxuICogICAgICBkZXN0cm95SXRlbTogZnVuY3Rpb24oaW5kZXgsIGl0ZW0pIHtcbiAqICAgICAgICBjb25zb2xlLmxvZygnRGVzdHJveWVkIGl0ZW0gd2l0aCBpbmRleDogJyArIGluZGV4KTtcbiAqICAgICAgfVxuICogICAgIH07XG4gKiAgIH0pO1xuICogPC9zY3JpcHQ+XG4gKlxuICogPG9ucy1saXN0IGlkPVwibGlzdFwiPlxuICogICA8b25zLWxhenktcmVwZWF0PlxuICogICAgIDxvbnMtbGlzdC1pdGVtPjwvb25zLWxpc3QtaXRlbT5cbiAqICAgPC9vbnMtbGF6eS1yZXBlYXQ+XG4gKiA8L29ucy1saXN0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMYXp5UmVwZWF0RWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAvLyBub3QgdmVyeSBnb29kIGlkZWEgYW5kIGFsc28gbm90IGRvY3VtZW50ZWRcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2RlbGVnYXRlJykpIHtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSB3aW5kb3dbdGhpcy5nZXRBdHRyaWJ1dGUoJ2RlbGVnYXRlJyldO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGVsZWdhdGVcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSBhIGRlbGVnYXRlIG9iamVjdCB0byBsb2FkIGFuZCB1bmxvYWQgaXRlbSBlbGVtZW50cy5bL2VuXVxuICAgKiAgW2phXeimgee0oOOBruODreODvOODieOAgeOCouODs+ODreODvOODieOBquOBqeOBruWHpueQhuOCkuWnlOitsuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGVsZWdhdGUuY3JlYXRlSXRlbUNvbnRlbnRcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBUaGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gYSBgSFRNTEVsZW1lbnRgLlxuICAgKlxuICAgKiAgICAgVG8gaGVscCByZW5kZXJpbmcgdGhlIGVsZW1lbnQsIHRoZSBjdXJyZW50IGluZGV4IGFuZCBhIHRlbXBsYXRlIGlzIHN1cHBsaWVkIGFzIGFyZ3VtZW50cy4gVGhlIHRlbXBsYXRlIGlzIHRoZSBpbml0aWFsIGNvbnRlbnQgb2YgdGhlIGA8b25zLWxhenktcmVwZWF0PmAgZWxlbWVudC5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1cbiAgICogICAgIOOBk+OBrumWouaVsOOBr2BIVE1MRWxlbWVudGDjgpLov5TjgZfjgabjgY/jgaDjgZXjgYTjgIJcbiAgICogICAgIOimgee0oOOCkueUn+aIkOOBl+OChOOBmeOBj+OBmeOCi+OBn+OCgeOBq+OAgeePvuWcqOOBruOCouOCpOODhuODoOOBruOCpOODs+ODh+ODg+OCr+OCueOBqOODhuODs+ODl+ODrOODvOODiOOBjOW8leaVsOOBq+a4oeOBleOCjOOBvuOBmeOAglxuICAgKiAgICAg44GT44Gu44OG44Oz44OX44Os44O844OI44Gv44CBYDxvbnMtbGF6eS1yZXBlYXQ+YOimgee0oOOBruOCs+ODs+ODhuODs+ODhOOBjOa4oeOBleOCjOOBvuOBmeOAglxuICAgKiAgIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGVsZWdhdGUuY291bnRJdGVtc1xuICAgKiBAdHlwZSB7RnVuY3Rpb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG91bGQgcmV0dXJuIHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIGxpc3QuWy9lbl1cbiAgICogICBbamFd44Oq44K544OI5YaF44Gu44Ki44Kk44OG44Og5pWw44KS6L+U44GX44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkZWxlZ2F0ZS5jYWxjdWxhdGVJdGVtSGVpZ2h0XG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgU2hvdWxkIHJldHVybiB0aGUgaGVpZ2h0IG9mIGFuIGl0ZW0uIFRoZSBpbmRleCBpcyBwcm92aWRlZCBhcyBhbiBhcmd1bWVudC5cbiAgICpcbiAgICogICAgIFRoaXMgaXMgaW1wb3J0YW50IHdoZW4gcmVuZGVyaW5nIGxpc3RzIHdoZXJlIHRoZSBpdGVtcyBoYXZlIGRpZmZlcmVudCBoZWlnaHQuXG4gICAqXG4gICAqICAgICBUaGUgZnVuY3Rpb24gaXMgb3B0aW9uYWwgYW5kIGlmIGl0IGlzbid0IHByZXNlbnQgdGhlIGhlaWdodCBvZiB0aGUgZmlyc3QgaXRlbSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY2FsY3VsYXRlZCBhbmQgdXNlZCBmb3IgYWxsIG90aGVyIGl0ZW1zLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVxuICAgKiAgICAg44Ki44Kk44OG44Og44Gu6auY44GVKOODlOOCr+OCu+ODqynjgpLov5TjgZfjgabjgY/jgaDjgZXjgYTjgILjgqLjgqTjg4bjg6Djga7jgqTjg7Pjg4fjg4Pjgq/jgrnlgKTjga/lvJXmlbDjgafmuKHjgZXjgozjgb7jgZnjgIJcbiAgICogICAgIOOBk+OBrumWouaVsOOBr+OAgeOBneOCjOOBnuOCjOOBruOCouOCpOODoOOBjOmBleOBo+OBn+mrmOOBleOCkuaMgeOBpOODquOCueODiOOCkuODrOODs+ODgOODquODs+OCsOOBmeOCi+mam+OBq+mHjeimgeOBp+OBmeOAglxuICAgKiAgICAg44GT44Gu6Zai5pWw44Gv44Kq44OX44K344On44OK44Or44Gn44GZ44CC44KC44GX44GT44Gu6Zai5pWw44GM54Sh44GE5aC05ZCI44Gr44Gv44CBXG4gICAqICAgICDmnIDliJ3jga7jgqLjgqTjg4bjg6Djga7pq5jjgZXjgYzku5bjga7jgZnjgbnjgabjga7jgqLjgqTjg4bjg6Djga7pq5jjgZXjgajjgZfjgabliKnnlKjjgZXjgozjgb7jgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRlbGVnYXRlLmRlc3Ryb3lJdGVtXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGNhbGxlZCB3aGVuIGFuIGl0ZW0gaXMgcmVtb3ZlZCBmcm9tIHRoZSBET00uIFRoZSBpbmRleCBhbmQgRE9NIGVsZW1lbnQgaXMgcHJvdmlkZWQgYXMgYXJndW1lbnRzLlxuICAgKlxuICAgKiAgICAgVGhlIGZ1bmN0aW9uIGlzIG9wdGlvbmFsIGJ1dCBtYXkgYmUgaW1wb3J0YW50IGluIG9yZGVyIHRvIGF2b2lkIG1lbW9yeSBsZWFrcy5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1cbiAgICogICAgIOOBk+OBrumWouaVsOOBr+OAgeOBguOCi+OCouOCpOODhuODoOOBjERPTeODhOODquODvOOBi+OCiemZpOOBi+OCjOOBn+aZguOBq+WRvOOBs+WHuuOBleOCjOOBvuOBmeOAglxuICAgKiAgICAg44Ki44Kk44OG44Og44Gu44Kk44Oz44OH44OD44Kv44K55YCk44GoRE9N6KaB57Sg44GM5byV5pWw44Go44GX44Gm5rih44GV44KM44G+44GZ44CCXG4gICAqICAgICDjgZPjga7plqLmlbDjga/jgqrjg5fjgrfjg6fjg4rjg6vjgafjgZnjgYzjgIHlkITjgqLjgqTjg4bjg6Djga7lvozlh6bnkIbjgYzlv4XopoHjgarloLTlkIjjgavjga/jg6Hjg6Ljg6rjg7zjg6rjg7zjgq/jgpLpgb/jgZHjgovjgZ/jgoHjgavph43opoHjgafjgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICBzZXQgZGVsZWdhdGUodXNlckRlbGVnYXRlKSB7XG4gICAgdGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyICYmIHRoaXMuX2xhenlSZXBlYXRQcm92aWRlci5kZXN0cm95KCk7XG5cbiAgICBpZiAoIXRoaXMuX3RlbXBsYXRlRWxlbWVudCAmJiB0aGlzLmNoaWxkcmVuWzBdKSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZUVsZW1lbnQgPSB0aGlzLnJlbW92ZUNoaWxkKHRoaXMuY2hpbGRyZW5bMF0pO1xuICAgIH1cblxuICAgIGNvbnN0IGRlbGVnYXRlID0gbmV3IExhenlSZXBlYXREZWxlZ2F0ZSh1c2VyRGVsZWdhdGUsIHRoaXMuX3RlbXBsYXRlRWxlbWVudCB8fCBudWxsKTtcbiAgICB0aGlzLl9sYXp5UmVwZWF0UHJvdmlkZXIgPSBuZXcgTGF6eVJlcGVhdFByb3ZpZGVyKHRoaXMucGFyZW50RWxlbWVudCwgZGVsZWdhdGUpO1xuICB9XG5cbiAgZ2V0IGRlbGVnYXRlKCkge1xuICAgIHV0aWwudGhyb3coJ05vIGRlbGVnYXRlIGdldHRlcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgcmVmcmVzaFxuICAgKiBAc2lnbmF0dXJlIHJlZnJlc2goKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmVmcmVzaCB0aGUgbGlzdC4gVXNlIHRoaXMgbWV0aG9kIHdoZW4gdGhlIGRhdGEgaGFzIGNoYW5nZWQuWy9lbl1cbiAgICogICBbamFd44Oq44K544OI44KS5pu05paw44GX44G+44GZ44CC44KC44GX44OH44O844K/44GM5aSJ44KP44Gj44Gf5aC05ZCI44Gr44Gv44GT44Gu44Oh44K944OD44OJ44KS5L2/44Gj44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAgICovXG4gIHJlZnJlc2goKSB7XG4gICAgdGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyICYmIHRoaXMuX2xhenlSZXBlYXRQcm92aWRlci5yZWZyZXNoKCk7XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge31cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAodGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyKSB7XG4gICAgICB0aGlzLl9sYXp5UmVwZWF0UHJvdmlkZXIuZGVzdHJveSgpO1xuICAgICAgdGhpcy5fbGF6eVJlcGVhdFByb3ZpZGVyID0gbnVsbDtcbiAgICB9XG4gIH1cblxufVxuXG5pbnRlcm5hbC5MYXp5UmVwZWF0RGVsZWdhdGUgPSBMYXp5UmVwZWF0RGVsZWdhdGU7XG5pbnRlcm5hbC5MYXp5UmVwZWF0UHJvdmlkZXIgPSBMYXp5UmVwZWF0UHJvdmlkZXI7XG5cbm9uc0VsZW1lbnRzLkxhenlSZXBlYXQgPSBMYXp5UmVwZWF0RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWxhenktcmVwZWF0JywgTGF6eVJlcGVhdEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnbGlzdC1oZWFkZXInO1xuY29uc3Qgc2NoZW1lID0geycnOiAnbGlzdC1oZWFkZXItLSonfTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtbGlzdC1oZWFkZXJcbiAqIEBjYXRlZ29yeSBsaXN0XG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUhlYWRlciBlbGVtZW50IGZvciBsaXN0IGl0ZW1zLiBNdXN0IGJlIHB1dCBpbnNpZGUgdGhlIGA8b25zLWxpc3Q+YCBjb21wb25lbnQuWy9lbl1cbiAqICAgW2phXeODquOCueODiOimgee0oOOBq+S9v+eUqOOBmeOCi+ODmOODg+ODgOODvOeUqOOCs+ODs+ODneODvOODjeODs+ODiOOAgm9ucy1saXN044Go5YWx44Gr5L2/55So44GX44G+44GZ44CCWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1saXN0XG4gKiAgIFtlbl1UaGUgYDxvbnMtbGlzdD5gIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbGlzdC1pdGVtXG4gKiAgIFtlbl1UaGUgYDxvbnMtbGlzdC1pdGVtPmAgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1saXN0LWl0ZW3jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGNvZGVwZW4geXhjQ3RcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9saXN0XG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXURpc3BsYXkgYSBNYXRlcmlhbCBEZXNpZ24gbGlzdCBoZWFkZXIuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1saXN0PlxuICogICA8b25zLWxpc3QtaGVhZGVyPkhlYWRlciBUZXh0PC9vbnMtbGlzdC1oZWFkZXI+XG4gKiAgIDxvbnMtbGlzdC1pdGVtPkl0ZW08L29ucy1saXN0LWl0ZW0+XG4gKiAgIDxvbnMtbGlzdC1pdGVtPkl0ZW08L29ucy1saXN0LWl0ZW0+XG4gKiA8L29ucy1saXN0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0SGVhZGVyRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIGxpc3QgaGVhZGVyLlsvZW5dXG4gICAqICAgW2phXeODmOODg+ODgOODvOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9jb21waWxlKCk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLkxpc3RIZWFkZXIgPSBMaXN0SGVhZGVyRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLWxpc3QtaGVhZGVyJywgTGlzdEhlYWRlckVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnbGlzdC10aXRsZSc7XG5jb25zdCBzY2hlbWUgPSB7Jyc6ICdsaXN0LXRpdGxlLS0qJ307XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWxpc3QtdGl0bGVcbiAqIEBjYXRlZ29yeSBsaXN0XG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVJlcHJlc2VudHMgYSBsaXN0IHRpdGxlLlsvZW5dXG4gKiAgIFtqYV3jg6rjgrnjg4jjga7jgr/jgqTjg4jjg6vjgpLooajnj77jgZfjgb7jgZnjgIJbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtbGlzdC10aXRsZT5MaXN0IFRpdGxlPC9vbnMtbGlzdC10aXRsZT5cbiAqIDxvbnMtbGlzdD5cbiAqICAgPG9ucy1saXN0LWl0ZW0+SXRlbTwvb25zLWxpc3QtaXRlbT5cbiAqIDwvb25zLWxpc3Q+XG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXURpc3BsYXkgYSBNYXRlcmlhbCBEZXNpZ24gbGlzdCB0aXRsZS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0VGl0bGVFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9jb21waWxlKCk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLkxpc3RUaXRsZSA9IExpc3RUaXRsZUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1saXN0LXRpdGxlJywgTGlzdFRpdGxlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxOCBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InXG5cbmV4cG9ydCBjbGFzcyBMaXN0SXRlbUFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIHNob3dFeHBhbnNpb24obGlzdEl0ZW0sIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGhpZGVFeHBhbnNpb24obGlzdEl0ZW0sIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU2xpZGVMaXN0SXRlbUFuaW1hdG9yIGV4dGVuZHMgTGlzdEl0ZW1BbmltYXRvciB7XG5cbiAgc2hvd0V4cGFuc2lvbihsaXN0SXRlbSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hbmltYXRlRXhwYW5zaW9uKGxpc3RJdGVtLCB0cnVlLCBjYWxsYmFjayk7XG4gIH1cblxuICBoaWRlRXhwYW5zaW9uKGxpc3RJdGVtLCBjYWxsYmFjaykge1xuICAgIHRoaXMuX2FuaW1hdGVFeHBhbnNpb24obGlzdEl0ZW0sIGZhbHNlLCBjYWxsYmFjayk7XG4gIH1cblxuICBfYW5pbWF0ZUV4cGFuc2lvbihsaXN0SXRlbSwgc2hvdWxkT3BlbiwgY2FsbGJhY2spIHtcbiAgICAvLyBUbyBhbmltYXRlIHRoZSBvcGVuaW5nIG9mIHRoZSBleHBhbnNpb24gcGFuZWwgY29ycmVjdGx5LCB3ZSBuZWVkIHRvIGtub3cgaXRzXG4gICAgLy8gaGVpZ2h0LiBUbyBjYWxjdWxhdGUgdGhpcywgd2Ugc2V0IGl0cyBoZWlnaHQgdG8gYXV0bywgYW5kIHRoZW4gZ2V0IHRoZSBjb21wdXRlZFxuICAgIC8vIGhlaWdodCBhbmQgcGFkZGluZy4gT25jZSB0aGlzIGlzIGRvbmUsIHdlIHNldCB0aGUgaGVpZ2h0IGJhY2sgdG8gaXRzIG9yaWdpbmFsIHZhbHVlLlxuICAgIGNvbnN0IG9sZEhlaWdodCA9IGxpc3RJdGVtLmV4cGFuZGFibGVDb250ZW50LnN0eWxlLmhlaWdodDtcbiAgICBjb25zdCBvbGREaXNwbGF5ID0gbGlzdEl0ZW0uZXhwYW5kYWJsZUNvbnRlbnQuc3R5bGUuZGlzcGxheTtcbiAgICBsaXN0SXRlbS5leHBhbmRhYmxlQ29udGVudC5zdHlsZS5oZWlnaHQgPSAnYXV0byc7XG4gICAgbGlzdEl0ZW0uZXhwYW5kYWJsZUNvbnRlbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGxpc3RJdGVtLmV4cGFuZGFibGVDb250ZW50KTtcblxuICAgIGNvbnN0IGV4cGFuc2lvbk9wZW5UcmFuc2l0aW9uID0gW1xuICAgICAgeyBoZWlnaHQ6IDAsIHBhZGRpbmdUb3A6IDAsIHBhZGRpbmdCb3R0b206IDAgfSxcbiAgICAgIHtcbiAgICAgICAgaGVpZ2h0OiBjb21wdXRlZFN0eWxlLmhlaWdodCxcbiAgICAgICAgcGFkZGluZ1RvcDogY29tcHV0ZWRTdHlsZS5wYWRkaW5nVG9wLFxuICAgICAgICBwYWRkaW5nQm90dG9tOiBjb21wdXRlZFN0eWxlLnBhZGRpbmdCb3R0b20sXG4gICAgICB9XG4gICAgXTtcbiAgICBjb25zdCBpY29uT3BlblRyYW5zaXRpb24gPSBbe3RyYW5zZm9ybTogJ3JvdGF0ZSg0NWRlZyknfSwge3RyYW5zZm9ybTogJ3JvdGF0ZSgyMjVkZWcpJ31dO1xuXG4gICAgLy8gTm93IHRoYXQgd2UgaGF2ZSB0aGUgdmFsdWVzIHdlIG5lZWQsIHJlc2V0IHRoZSBoZWlnaHQgYmFjayB0byBpdHMgb3JpZ2luYWwgc3RhdGVcbiAgICBsaXN0SXRlbS5leHBhbmRhYmxlQ29udGVudC5zdHlsZS5oZWlnaHQgPSBvbGRIZWlnaHQ7XG5cbiAgICBhbmltaXQobGlzdEl0ZW0uZXhwYW5kYWJsZUNvbnRlbnQsIHsgZHVyYXRpb246IHRoaXMuZHVyYXRpb24sIHByb3BlcnR5OiAnaGVpZ2h0IHBhZGRpbmctdG9wIHBhZGRpbmctYm90dG9tJyB9KVxuICAgICAgLmRlZmF1bHQoLi4uKHNob3VsZE9wZW4gPyBleHBhbnNpb25PcGVuVHJhbnNpdGlvbiA6IGV4cGFuc2lvbk9wZW5UcmFuc2l0aW9uLnJldmVyc2UoKSkpXG4gICAgICAucGxheSgoKSA9PiB7XG4gICAgICAgIGxpc3RJdGVtLmV4cGFuZGFibGVDb250ZW50LnN0eWxlLmRpc3BsYXkgPSBvbGREaXNwbGF5O1xuICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgfSk7XG5cbiAgICBpZiAobGlzdEl0ZW0uZXhwYW5kQ2hldnJvbikge1xuICAgICAgYW5pbWl0KGxpc3RJdGVtLmV4cGFuZENoZXZyb24sIHsgZHVyYXRpb246IHRoaXMuZHVyYXRpb24sIHByb3BlcnR5OiAndHJhbnNmb3JtJyB9KVxuICAgICAgICAuZGVmYXVsdCguLi4oc2hvdWxkT3BlbiA/IGljb25PcGVuVHJhbnNpdGlvbiA6IGljb25PcGVuVHJhbnNpdGlvbi5yZXZlcnNlKCkpKVxuICAgICAgICAucGxheSgpO1xuICAgIH1cbiAgfVxuXG59IiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uLy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IHN0eWxlciBmcm9tICcuLi8uLi9vbnMvc3R5bGVyJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBBbmltYXRvckZhY3RvcnkgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnknO1xuaW1wb3J0IHsgTGlzdEl0ZW1BbmltYXRvciwgU2xpZGVMaXN0SXRlbUFuaW1hdG9yIH0gZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnbGlzdC1pdGVtJztcbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5saXN0LWl0ZW0nOiAnbGlzdC1pdGVtLS0qJyxcbiAgJy5saXN0LWl0ZW1fX2xlZnQnOiAnbGlzdC1pdGVtLS0qX19sZWZ0JyxcbiAgJy5saXN0LWl0ZW1fX2NlbnRlcic6ICdsaXN0LWl0ZW0tLSpfX2NlbnRlcicsXG4gICcubGlzdC1pdGVtX19yaWdodCc6ICdsaXN0LWl0ZW0tLSpfX3JpZ2h0JyxcbiAgJy5saXN0LWl0ZW1fX2xhYmVsJzogJ2xpc3QtaXRlbS0tKl9fbGFiZWwnLFxuICAnLmxpc3QtaXRlbV9fdGl0bGUnOiAnbGlzdC1pdGVtLS0qX190aXRsZScsXG4gICcubGlzdC1pdGVtX19zdWJ0aXRsZSc6ICdsaXN0LWl0ZW0tLSpfX3N1YnRpdGxlJyxcbiAgJy5saXN0LWl0ZW1fX3RodW1ibmFpbCc6ICdsaXN0LWl0ZW0tLSpfX3RodW1ibmFpbCcsXG4gICcubGlzdC1pdGVtX19pY29uJzogJ2xpc3QtaXRlbS0tKl9faWNvbidcbn07XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gICdkZWZhdWx0JzogU2xpZGVMaXN0SXRlbUFuaW1hdG9yLFxuICAnbm9uZSc6IExpc3RJdGVtQW5pbWF0b3Jcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLWxpc3QtaXRlbVxuICogQGNhdGVnb3J5IGxpc3RcbiAqIEBtb2RpZmllciB0YXBwYWJsZVxuICogICBbZW5dTWFrZSB0aGUgbGlzdCBpdGVtIGNoYW5nZSBhcHBlYXJhbmNlIHdoZW4gaXQncyB0YXBwZWQuIE9uIGlPUyBpdCBpcyBiZXR0ZXIgdG8gdXNlIHRoZSBcInRhcHBhYmxlXCIgYW5kIFwidGFwLWJhY2tncm91bmQtY29sb3JcIiBhdHRyaWJ1dGUgZm9yIGJldHRlciBiZWhhdmlvciB3aGVuIHNjcm9sbGluZy5bL2VuXVxuICogICBbamFd44K/44OD44OX44KE44Kv44Oq44OD44Kv44GX44Gf5pmC44Gr5Yq55p6c44GM6KGo56S644GV44KM44KL44KI44GG44Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBjaGV2cm9uXG4gKiAgIFtlbl1EaXNwbGF5IGEgY2hldnJvbiBhdCB0aGUgcmlnaHQgZW5kIG9mIHRoZSBsaXN0IGl0ZW0gYW5kIG1ha2UgaXQgY2hhbmdlIGFwcGVhcmFuY2Ugd2hlbiB0YXBwZWQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgbG9uZ2RpdmlkZXJcbiAqICAgW2VuXURpc3BsYXlzIGEgbG9uZyBob3Jpem9udGFsIGRpdmlkZXIgYmV0d2VlbiBpdGVtcy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBtb2RpZmllciBub2RpdmlkZXJcbiAqICAgW2VuXVJlbW92ZXMgdGhlIGRpdmlkZXIgYmV0d2VlbiBsaXN0IGl0ZW1zLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIGxpc3QgaXRlbS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQ29tcG9uZW50IHRoYXQgcmVwcmVzZW50cyBlYWNoIGl0ZW0gaW4gYSBsaXN0LiBUaGUgbGlzdCBpdGVtIGlzIGNvbXBvc2VkIG9mIGZvdXIgcGFydHMgdGhhdCBhcmUgcmVwcmVzZW50ZWQgd2l0aCB0aGUgYGxlZnRgLCBgY2VudGVyYCwgYHJpZ2h0YCBhbmQgYGV4cGFuZGFibGUtY29udGVudGAgY2xhc3Nlcy4gVGhlc2UgY2xhc3NlcyBjYW4gYmUgdXNlZCB0byBlbnN1cmUgdGhhdCB0aGUgY29udGVudCBvZiB0aGUgbGlzdCBpdGVtcyBpcyBwcm9wZXJseSBhbGlnbmVkLlxuICpcbiAqICAgICBgYGBcbiAqICAgICA8b25zLWxpc3QtaXRlbT5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJsZWZ0XCI+TGVmdDwvZGl2PlxuICogICAgICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPkNlbnRlcjwvZGl2PlxuICogICAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+UmlnaHQ8L2Rpdj5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJleHBhbmRhYmxlLWNvbnRlbnRcIj5FeHBhbmRhYmxlIGNvbnRlbnQ8L2Rpdj5cbiAqICAgICA8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgYGBgXG4gKlxuICogICAgIFRoZXJlIGFyZSBhbHNvIGEgbnVtYmVyIG9mIGNsYXNzZXMgKHByZWZpeGVkIHdpdGggYGxpc3QtaXRlbV9fKmApIHRoYXQgaGVscCB3aGVuIHB1dHRpbmcgdGhpbmdzIGxpa2UgaWNvbnMgYW5kIHRodW1ibmFpbHMgaW50byB0aGUgbGlzdCBpdGVtcy5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbGlzdFxuICogICBbZW5db25zLWxpc3QgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1saXN044Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1saXN0LWhlYWRlclxuICogICBbZW5db25zLWxpc3QtaGVhZGVyIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1oZWFkZXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGNvZGVwZW4geXhjQ3RcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9saXN0XG4gKiBAZXhhbXBsZVxuICogPG9ucy1saXN0LWl0ZW0+XG4gKiAgIDxkaXYgY2xhc3M9XCJsZWZ0XCI+XG4gKiAgICAgPG9ucy1pY29uIGljb249XCJtZC1mYWNlXCIgY2xhc3M9XCJsaXN0LWl0ZW1fX2ljb25cIj48L29ucy1pY29uPlxuICogICA8L2Rpdj5cbiAqICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlxuICogICAgIDxkaXYgY2xhc3M9XCJsaXN0LWl0ZW1fX3RpdGxlXCI+VGl0bGU8L2Rpdj5cbiAqICAgICA8ZGl2IGNsYXNzPVwibGlzdC1pdGVtX19zdWJ0aXRsZVwiPlN1YnRpdGxlPC9kaXY+XG4gKiAgIDwvZGl2PlxuICogICA8ZGl2IGNsYXNzPVwicmlnaHRcIj5cbiAqICAgICA8b25zLXN3aXRjaD48L29ucy1zd2l0Y2g+XG4gKiAgIDwvZGl2PlxuICogPC9vbnMtbGlzdC1pdGVtPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0SXRlbUVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSBsaXN0IGl0ZW0uWy9lbl1cbiAgICogICBbamFd5ZCE6KaB57Sg44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbG9jay1vbi1kcmFnXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1QcmV2ZW50IHZlcnRpY2FsIHNjcm9sbGluZyB3aGVuIHRoZSB1c2VyIGRyYWdzIGhvcml6b250YWxseS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovjgajjgIHjg6bjg7zjgrbjg7zjgYzjgZPjga7opoHntKDjgpLmqKrmlrnlkJHjgavjg4njg6njg4PjgrDjgZfjgabjgYTjgovmmYLjgavjgIHnuKbmlrnlkJHjga7jgrnjgq/jg63jg7zjg6vjgYzotbfjgY3jgarjgYTjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0YXBwYWJsZVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU1ha2VzIHRoZSBlbGVtZW50IHJlYWN0IHRvIHRhcHMuIGBwcmV2ZW50LXRhcGAgYXR0cmlidXRlIGNhbiBiZSBhZGRlZCB0byBjaGlsZCBlbGVtZW50cyBsaWtlIGJ1dHRvbnMgb3IgaW5wdXRzIHRvIHByZXZlbnQgdGhpcyBlZmZlY3QuIGBvbnMtKmAgZWxlbWVudHMgYXJlIGlnbm9yZWQgYnkgZGVmYXVsdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0YXAtYmFja2dyb3VuZC1jb2xvclxuICAgKiBAdHlwZSB7Q29sb3J9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl0gQ2hhbmdlcyB0aGUgYmFja2dyb3VuZCBjb2xvciB3aGVuIHRhcHBlZC4gRm9yIHRoaXMgdG8gd29yaywgdGhlIGF0dHJpYnV0ZSBcInRhcHBhYmxlXCIgbmVlZHMgdG8gYmUgc2V0LiBUaGUgZGVmYXVsdCBjb2xvciBpcyBcIiNkOWQ5ZDlcIi4gSXQgd2lsbCBkaXNwbGF5IGFzIGEgcmlwcGxlIGVmZmVjdCBvbiBBbmRyb2lkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGV4cGFuZGFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1NYWtlcyB0aGUgZWxlbWVudCBhYmxlIHRvIGJlIGV4cGFuZGVkIHRvIHJldmVhbCBleHRyYSBjb250ZW50LiBGb3IgdGhpcyB0byB3b3JrLCB0aGUgZXhwYW5kYWJsZSBjb250ZW50IG11c3QgYmUgZGVmaW5lZCBpbiBgZGl2LmV4cGFuZGFibGUtY29udGVudGAuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBleHBhbmRhYmxlIGNvbnRlbnQuIENhbiBiZSBlaXRoZXIgYFwiZGVmYXVsdFwiYCBvciBgXCJub25lXCJgLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2FuaW1hdG9yRmFjdG9yeSA9IHRoaXMuX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpO1xuICAgIHRoaXMudG9nZ2xlRXhwYW5zaW9uID0gdGhpcy50b2dnbGVFeHBhbnNpb24uYmluZCh0aGlzKTtcblxuICAgIC8vIEVsZW1lbnRzIGlnbm9yZWQgd2hlbiB0YXBwaW5nXG4gICAgY29uc3QgcmUgPSAvXm9ucy0oPyFjb2wkfHJvdyR8aWYkKS9pO1xuICAgIHRoaXMuX3Nob3VsZElnbm9yZVRhcCA9IGUgPT4gZS5oYXNBdHRyaWJ1dGUoJ3ByZXZlbnQtdGFwJykgfHwgcmUudGVzdChlLnRhZ05hbWUpO1xuXG4gICAgLy8gc2hvdyBhbmQgaGlkZSBmdW5jdGlvbnMgZm9yIFZ1ZSBoaWRhYmxlIG1peGluXG4gICAgdGhpcy5zaG93ID0gdGhpcy5zaG93RXhwYW5zaW9uO1xuICAgIHRoaXMuaGlkZSA9IHRoaXMuaGlkZUV4cGFuc2lvbjtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ29tcGlsZXMgdGhlIGxpc3QgaXRlbS5cbiAgICpcbiAgICogVmFyaW91cyBlbGVtZW50cyBhcmUgYWxsb3dlZCBpbiB0aGUgYm9keSBvZiBhIGxpc3QgaXRlbTpcbiAgICpcbiAgICogIC0gZGl2LmxlZnQsIGRpdi5yaWdodCwgYW5kIGRpdi5jZW50ZXIgYXJlIGFsbG93ZWQgYXMgZGlyZWN0IGNoaWxkcmVuXG4gICAqICAtIGlmIGRpdi5jZW50ZXIgaXMgbm90IGRlZmluZWQsIGFueXRoaW5nIHRoYXQgaXNuJ3QgZGl2LmxlZnQsIGRpdi5yaWdodCBvciBkaXYuZXhwYW5kYWJsZS1jb250ZW50IHdpbGwgYmUgcHV0IGluIGEgZGl2LmNlbnRlclxuICAgKiAgLSBpZiBkaXYuY2VudGVyIGlzIGRlZmluZWQsIGFueXRoaW5nIHRoYXQgaXNuJ3QgZGl2LmxlZnQsIGRpdi5yaWdodCBvciBkaXYuZXhwYW5kYWJsZS1jb250ZW50IHdpbGwgYmUgaWdub3JlZFxuICAgKiAgLSBpZiBsaXN0IGl0ZW0gaGFzIGV4cGFuZGFibGUgYXR0cmlidXRlOlxuICAgKiAgICAgIC0gZGl2LmV4cGFuZGFibGUtY29udGVudCBpcyBhbGxvd2VkIGFzIGEgZGlyZWN0IGNoaWxkXG4gICAqICAgICAgLSBkaXYudG9wIGlzIGFsbG93ZWQgYXMgZGlyZWN0IGNoaWxkXG4gICAqICAgICAgLSBpZiBkaXYudG9wIGlzIGRlZmluZWQsIGFueXRoaW5nIHRoYXQgaXNuJ3QgZGl2LmV4cGFuZGFibGUtY29udGVudCBzaG91bGQgYmUgaW5zaWRlIGRpdi50b3AgLSBhbnl0aGluZyBlbHNlIHdpbGwgYmUgaWdub3JlZFxuICAgKiAgICAgIC0gaWYgZGl2LnJpZ2h0IGlzIG5vdCBkZWZpbmVkLCBhIGRpdi5yaWdodCB3aWxsIGJlIGNyZWF0ZWQgd2l0aCBhIGRyb3AtZG93biBjaGV2cm9uXG4gICAqXG4gICAqIFNlZSB0aGUgdGVzdHMgZm9yIGV4YW1wbGVzLlxuICAgKi9cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuXG4gICAgbGV0IHRvcCwgZXhwYW5kYWJsZUNvbnRlbnQ7XG4gICAgbGV0IHRvcENvbnRlbnQgPSBbXTtcbiAgICBBcnJheS5mcm9tKHRoaXMuY2hpbGROb2RlcykuZm9yRWFjaChub2RlID0+IHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlICE9PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICB0b3BDb250ZW50LnB1c2gobm9kZSk7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUuY2xhc3NMaXN0LmNvbnRhaW5zKCd0b3AnKSkge1xuICAgICAgICB0b3AgPSBub2RlO1xuICAgICAgfSBlbHNlIGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucygnZXhwYW5kYWJsZS1jb250ZW50JykpIHtcbiAgICAgICAgZXhwYW5kYWJsZUNvbnRlbnQgPSBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdG9wQ29udGVudC5wdXNoKG5vZGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZS5ub2RlTmFtZSAhPT0gJ09OUy1SSVBQTEUnKSB7XG4gICAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdG9wQ29udGVudCA9IHRvcCA/IEFycmF5LmZyb20odG9wLmNoaWxkTm9kZXMpIDogdG9wQ29udGVudDtcblxuICAgIGxldCBsZWZ0LCByaWdodCwgY2VudGVyO1xuICAgIGNvbnN0IGNlbnRlckNvbnRlbnQgPSBbXTtcbiAgICB0b3BDb250ZW50LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgY2VudGVyQ29udGVudC5wdXNoKG5vZGUpO1xuICAgICAgfSBlbHNlIGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucygnbGVmdCcpKSB7XG4gICAgICAgIGxlZnQgPSBub2RlO1xuICAgICAgfSBlbHNlIGlmIChub2RlLmNsYXNzTGlzdC5jb250YWlucygncmlnaHQnKSkge1xuICAgICAgICByaWdodCA9IG5vZGU7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUuY2xhc3NMaXN0LmNvbnRhaW5zKCdjZW50ZXInKSkge1xuICAgICAgICBjZW50ZXIgPSBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2VudGVyQ29udGVudC5wdXNoKG5vZGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdleHBhbmRhYmxlJykpIHtcbiAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtLS1leHBhbmRhYmxlJyk7XG5cbiAgICAgIGlmICghdG9wKSB7XG4gICAgICAgIHRvcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICB0b3AuY2xhc3NMaXN0LmFkZCgndG9wJyk7XG4gICAgICB9XG4gICAgICB0b3AuY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtX190b3AnKTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodG9wKTtcbiAgICAgIHRoaXMuX3RvcCA9IHRvcDtcblxuICAgICAgaWYgKGV4cGFuZGFibGVDb250ZW50KSB7XG4gICAgICAgIGV4cGFuZGFibGVDb250ZW50LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fZXhwYW5kYWJsZS1jb250ZW50Jyk7XG4gICAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoZXhwYW5kYWJsZUNvbnRlbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJpZ2h0KSB7XG4gICAgICAgIHJpZ2h0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIHJpZ2h0LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fcmlnaHQnLCAncmlnaHQnKTtcblxuICAgICAgICAvLyBXZSBjYW5ub3QgdXNlIGEgcHNldWRvLWVsZW1lbnQgZm9yIHRoaXMgY2hldnJvbiwgYXMgd2UgY2Fubm90IGFuaW1hdGUgaXQgdXNpbmdcbiAgICAgICAgLy8gSlMuIFNvLCB3ZSBtYWtlIGEgY2hldnJvbiBzcGFuIGluc3RlYWQuXG4gICAgICAgIGNvbnN0IGNoZXZyb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICAgIGNoZXZyb24uY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtX19leHBhbmQtY2hldnJvbicpO1xuICAgICAgICByaWdodC5hcHBlbmRDaGlsZChjaGV2cm9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdG9wID0gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoIWNlbnRlcikge1xuICAgICAgY2VudGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBjZW50ZXIuY2xhc3NMaXN0LmFkZCgnY2VudGVyJyk7XG4gICAgICBjZW50ZXJDb250ZW50LmZvckVhY2gobm9kZSA9PiBjZW50ZXIuYXBwZW5kQ2hpbGQobm9kZSkpO1xuICAgIH1cbiAgICBjZW50ZXIuY2xhc3NMaXN0LmFkZCgnbGlzdC1pdGVtX19jZW50ZXInKTtcbiAgICB0b3AuYXBwZW5kQ2hpbGQoY2VudGVyKTtcblxuICAgIGlmIChsZWZ0KSB7XG4gICAgICBsZWZ0LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fbGVmdCcpO1xuICAgICAgdG9wLmFwcGVuZENoaWxkKGxlZnQpO1xuICAgIH1cbiAgICBpZiAocmlnaHQpIHtcbiAgICAgIHJpZ2h0LmNsYXNzTGlzdC5hZGQoJ2xpc3QtaXRlbV9fcmlnaHQnKTtcbiAgICAgIHRvcC5hcHBlbmRDaGlsZChyaWdodCk7XG4gICAgfVxuXG4gICAgdXRpbC51cGRhdGVSaXBwbGUodGhpcyk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2hvd0V4cGFuc2lvblxuICAgKiBAc2lnbmF0dXJlIHNob3dFeHBhbnNpb24oKVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyB0aGUgZXhwYW5kYWJsZSBjb250ZW50IGlmIHRoZSBlbGVtZW50IGlzIGV4cGFuZGFibGUuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNob3dFeHBhbnNpb24oKSB7XG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdleHBhbmRhYmxlJykgJiYgIXRoaXMuX2V4cGFuZGluZykge1xuICAgICAgdGhpcy5leHBhbmRlZCA9IHRydWU7XG4gICAgICB0aGlzLl9leHBhbmRpbmcgPSB0cnVlO1xuXG4gICAgICBjb25zdCBhbmltYXRvciA9IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcigpO1xuICAgICAgYW5pbWF0b3Iuc2hvd0V4cGFuc2lvbih0aGlzLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZXhwYW5kZWQnKTtcbiAgICAgICAgdGhpcy5fZXhwYW5kaW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBoaWRlRXhwYW5zaW9uXG4gICAqIEBzaWduYXR1cmUgaGlkZUV4cGFuc2lvbigpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRoZSBleHBhbmRhYmxlIGNvbnRlbnQgaWYgdGhlIGVsZW1lbnQgZXhwYW5kYWJsZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgaGlkZUV4cGFuc2lvbigpIHtcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2V4cGFuZGFibGUnKSAmJiAhdGhpcy5fZXhwYW5kaW5nKSB7XG4gICAgICB0aGlzLmV4cGFuZGVkID0gZmFsc2U7XG4gICAgICB0aGlzLl9leHBhbmRpbmcgPSB0cnVlO1xuXG4gICAgICBjb25zdCBhbmltYXRvciA9IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcigpO1xuICAgICAgYW5pbWF0b3IuaGlkZUV4cGFuc2lvbih0aGlzLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LnJlbW92ZSgnZXhwYW5kZWQnKTtcbiAgICAgICAgdGhpcy5fZXhwYW5kaW5nID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICB0b2dnbGVFeHBhbnNpb24oKSB7XG4gICAgdGhpcy5jbGFzc0xpc3QuY29udGFpbnMoJ2V4cGFuZGVkJykgPyB0aGlzLmhpZGVFeHBhbnNpb24oKSA6IHRoaXMuc2hvd0V4cGFuc2lvbigpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2V4cGFuc2lvbicpKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBMaXN0SXRlbUFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ0xpc3RJdGVtQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpIHx8ICdkZWZhdWx0J1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnLCAncmlwcGxlJywgJ2FuaW1hdGlvbiddO1xuICB9XG5cbiAgZ2V0IGV4cGFuZGFibGVDb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJy5saXN0LWl0ZW1fX2V4cGFuZGFibGUtY29udGVudCcpO1xuICB9XG5cbiAgZ2V0IGV4cGFuZENoZXZyb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcignLmxpc3QtaXRlbV9fZXhwYW5kLWNoZXZyb24nKTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICB1dGlsLnVwZGF0ZVJpcHBsZSh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdhbmltYXRpb24nOlxuICAgICAgICB0aGlzLl9hbmltYXRvckZhY3RvcnkgPSB0aGlzLl91cGRhdGVBbmltYXRvckZhY3RvcnkoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX3NldHVwTGlzdGVuZXJzKHRydWUpO1xuICAgICAgdGhpcy5fb3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnN0eWxlLmJhY2tncm91bmRDb2xvcjtcbiAgICAgIHRoaXMudGFwcGVkID0gZmFsc2U7XG4gICAgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9zZXR1cExpc3RlbmVycyhmYWxzZSk7XG4gIH1cblxuICBfc2V0dXBMaXN0ZW5lcnMoYWRkKSB7XG4gICAgY29uc3QgYWN0aW9uID0gKGFkZCA/ICdhZGQnIDogJ3JlbW92ZScpICsgJ0V2ZW50TGlzdGVuZXInO1xuICAgIHV0aWxbYWN0aW9uXSh0aGlzLCAndG91Y2hzdGFydCcsIHRoaXMuX29uVG91Y2gsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICB1dGlsW2FjdGlvbl0odGhpcywgJ3RvdWNobW92ZScsIHRoaXMuX29uUmVsZWFzZSwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hjYW5jZWwnLCB0aGlzLl9vblJlbGVhc2UpO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hlbmQnLCB0aGlzLl9vblJlbGVhc2UpO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hsZWF2ZScsIHRoaXMuX29uUmVsZWFzZSk7XG4gICAgdGhpc1thY3Rpb25dKCdkcmFnJywgdGhpcy5fb25EcmFnKTtcbiAgICB0aGlzW2FjdGlvbl0oJ21vdXNlZG93bicsIHRoaXMuX29uVG91Y2gpO1xuICAgIHRoaXNbYWN0aW9uXSgnbW91c2V1cCcsIHRoaXMuX29uUmVsZWFzZSk7XG4gICAgdGhpc1thY3Rpb25dKCdtb3VzZW91dCcsIHRoaXMuX29uUmVsZWFzZSk7XG5cbiAgICBpZiAodGhpcy5fdG9wKSB7XG4gICAgICB0aGlzLl90b3BbYWN0aW9uXSgnY2xpY2snLCB0aGlzLnRvZ2dsZUV4cGFuc2lvbik7XG4gICAgfVxuICB9XG5cbiAgX29uRHJhZyhldmVudCkge1xuICAgIGNvbnN0IGdlc3R1cmUgPSBldmVudC5nZXN0dXJlO1xuICAgIC8vIFByZXZlbnQgdmVydGljYWwgc2Nyb2xsaW5nIGlmIHRoZSB1c2VycyBwYW5zIGxlZnQgb3IgcmlnaHQuXG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCdsb2NrLW9uLWRyYWcnKSAmJiBbJ2xlZnQnLCAncmlnaHQnXS5pbmRleE9mKGdlc3R1cmUuZGlyZWN0aW9uKSA+IC0xKSB7XG4gICAgICBnZXN0dXJlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgX29uVG91Y2goZSkge1xuICAgIGlmICh0aGlzLnRhcHBlZCB8fFxuICAgICAgKHRoaXMgIT09IGUudGFyZ2V0ICYmICh0aGlzLl9zaG91bGRJZ25vcmVUYXAoZS50YXJnZXQpIHx8IHV0aWwuZmluZFBhcmVudChlLnRhcmdldCwgdGhpcy5fc2hvdWxkSWdub3JlVGFwLCBwID0+IHAgPT09IHRoaXMpKSlcbiAgICApIHtcbiAgICAgIHJldHVybjsgLy8gSWdub3JlIHRhcFxuICAgIH1cblxuICAgIHRoaXMudGFwcGVkID0gdHJ1ZTtcbiAgICBjb25zdCB0b3VjaFN0eWxlID0geyB0cmFuc2l0aW9uOiAnYmFja2dyb3VuZC1jb2xvciAwLjBzIGxpbmVhciAwLjAycywgYm94LXNoYWRvdyAwLjBzIGxpbmVhciAwLjAycycgfTtcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgndGFwcGFibGUnKSkge1xuICAgICAgaWYgKHRoaXMuc3R5bGUuYmFja2dyb3VuZENvbG9yKSB7XG4gICAgICAgIHRoaXMuX29yaWdpbmFsQmFja2dyb3VuZENvbG9yID0gdGhpcy5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICB9XG5cbiAgICAgIHRvdWNoU3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ3RhcC1iYWNrZ3JvdW5kLWNvbG9yJykgfHwgJyNkOWQ5ZDknO1xuICAgICAgdG91Y2hTdHlsZS5ib3hTaGFkb3cgPSBgMHB4IC0xcHggMHB4IDBweCAke3RvdWNoU3R5bGUuYmFja2dyb3VuZENvbG9yfWA7XG4gICAgfVxuXG4gICAgc3R5bGVyKHRoaXMsIHRvdWNoU3R5bGUpO1xuICB9XG5cbiAgX29uUmVsZWFzZSgpIHtcbiAgICB0aGlzLnRhcHBlZCA9IGZhbHNlO1xuICAgIHRoaXMuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5fb3JpZ2luYWxCYWNrZ3JvdW5kQ29sb3IgfHwgJyc7XG4gICAgc3R5bGVyLmNsZWFyKHRoaXMsICd0cmFuc2l0aW9uIGJveFNoYWRvdycpO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLkxpc3RJdGVtID0gTGlzdEl0ZW1FbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtbGlzdC1pdGVtJywgTGlzdEl0ZW1FbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2xpc3QnO1xuY29uc3Qgc2NoZW1lID0geycnOiAnbGlzdC0tKid9O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1saXN0XG4gKiBAY2F0ZWdvcnkgbGlzdFxuICogQG1vZGlmaWVyIGluc2V0XG4gKiAgIFtlbl1JbnNldCBsaXN0IHRoYXQgZG9lc24ndCBjb3ZlciB0aGUgd2hvbGUgd2lkdGggb2YgdGhlIHBhcmVudC5bL2VuXVxuICogICBbamFd6Kaq6KaB57Sg44Gu55S76Z2i44GE44Gj44Gx44GE44Gr5bqD44GM44KJ44Gq44GE44Oq44K544OI44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBub2JvcmRlclxuICogICBbZW5dQSBsaXN0IHdpdGggbm8gYm9yZGVycyBhdCB0aGUgdG9wIGFuZCBib3R0b20uWy9lbl1cbiAqICAgW2phXeODquOCueODiOOBruS4iuS4i+OBruODnOODvOODgOODvOOBjOeEoeOBhOODquOCueODiOOCkuihqOekuuOBl+OBvuOBmeOAglsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUNvbXBvbmVudCB0byBkZWZpbmUgYSBsaXN0LCBhbmQgdGhlIGNvbnRhaW5lciBmb3Igb25zLWxpc3QtaXRlbShzKS5bL2VuXVxuICogICBbamFd44Oq44K544OI44KS6KGo54++44GZ44KL44Gf44KB44Gu44Kz44Oz44Od44O844ON44Oz44OI44CCb25zLWxpc3QtaXRlbeOBruOCs+ODs+ODhuODiuOBqOOBl+OBpuS9v+eUqOOBl+OBvuOBmeOAglsvamFdXG4gKiBAc2VlYWxzbyBvbnMtbGlzdC1pdGVtXG4gKiAgIFtlbl1vbnMtbGlzdC1pdGVtIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1pdGVt44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1saXN0LWhlYWRlclxuICogICBbZW5db25zLWxpc3QtaGVhZGVyIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtbGlzdC1oZWFkZXLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLWxhenktcmVwZWF0XG4gKiAgIFtlbl1vbnMtbGF6eS1yZXBlYXQgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1sYXp5LXJlcGVhdOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAY29kZXBlbiB5eGNDdFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2xpc3RcbiAqIEBleGFtcGxlXG4gKiA8b25zLWxpc3Q+XG4gKiAgIDxvbnMtbGlzdC1oZWFkZXI+SGVhZGVyIFRleHQ8L29ucy1saXN0LWhlYWRlcj5cbiAqICAgPG9ucy1saXN0LWl0ZW0+SXRlbTwvb25zLWxpc3QtaXRlbT5cbiAqICAgPG9ucy1saXN0LWl0ZW0+SXRlbTwvb25zLWxpc3QtaXRlbT5cbiAqIDwvb25zLWxpc3Q+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpc3RFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgbGlzdC5bL2VuXVxuICAgKiAgIFtqYV3jg6rjgrnjg4jjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fY29tcGlsZSgpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCBkZWZhdWx0Q2xhc3NOYW1lLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vZGlmaWVyJzpcbiAgICAgICAgTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5vbnNFbGVtZW50cy5MaXN0ID0gTGlzdEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1saXN0JywgTGlzdEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuY29uc3QgSU5QVVRfQVRUUklCVVRFUyA9IFtcbiAgJ2F1dG9jYXBpdGFsaXplJyxcbiAgJ2F1dG9jb21wbGV0ZScsXG4gICdhdXRvY29ycmVjdCcsXG4gICdhdXRvZm9jdXMnLFxuICAnZGlzYWJsZWQnLFxuICAnaW5wdXRtb2RlJyxcbiAgJ21heCcsXG4gICdtYXhsZW5ndGgnLFxuICAnbWluJyxcbiAgJ21pbmxlbmd0aCcsXG4gICduYW1lJyxcbiAgJ3BhdHRlcm4nLFxuICAncGxhY2Vob2xkZXInLFxuICAncmVhZG9ubHknLFxuICAncmVxdWlyZWQnLFxuICAnc2l6ZScsXG4gICdzdGVwJyxcbiAgJ3ZhbGlkYXRvcicsXG4gICd2YWx1ZSdcbl07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhc2VJbnB1dEVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgX3VwZGF0ZSgpIHt9IC8vIE9wdGlvbmFsbHkgaW1wbGVtZW50ZWRcblxuICBnZXQgX3NjaGVtZSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBnZXQgX3RlbXBsYXRlKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciA9PT0gQmFzZUlucHV0RWxlbWVudCkge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX2NvbXBpbGUoKSk7XG4gICAgdGhpcy5fYm91bmREZWxlZ2F0ZUV2ZW50ID0gdGhpcy5fZGVsZWdhdGVFdmVudC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5fZGVmYXVsdENsYXNzTmFtZSAmJiB0aGlzLmNsYXNzTGlzdC5hZGQodGhpcy5fZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggIT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmFwcGVuZENoaWxkKHV0aWwuY3JlYXRlRnJhZ21lbnQodGhpcy5fdGVtcGxhdGUpKTtcblxuICAgIHRoaXMuX3NldElucHV0SWQoKTtcblxuICAgIHRoaXMuX3VwZGF0ZUJvdW5kQXR0cmlidXRlcygpO1xuXG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCB0aGlzLl9zY2hlbWUpO1xuICB9XG5cbiAgX3VwZGF0ZUJvdW5kQXR0cmlidXRlcygpIHtcbiAgICBJTlBVVF9BVFRSSUJVVEVTLmZvckVhY2goYXR0ciA9PiB7XG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoYXR0cikpIHtcbiAgICAgICAgdGhpcy5faW5wdXQuc2V0QXR0cmlidXRlKGF0dHIsIHRoaXMuZ2V0QXR0cmlidXRlKGF0dHIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2lucHV0LnJlbW92ZUF0dHJpYnV0ZShhdHRyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuX3VwZGF0ZSgpO1xuICB9XG5cbiAgX2RlbGVnYXRlRXZlbnQoZXZlbnQpIHtcbiAgICBjb25zdCBlID0gbmV3IEN1c3RvbUV2ZW50KGV2ZW50LnR5cGUsIHtcbiAgICAgIGJ1YmJsZXM6IGZhbHNlLFxuICAgICAgY2FuY2VsYWJsZTogdHJ1ZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2hFdmVudChlKTtcbiAgfVxuXG4gIF9zZXRJbnB1dElkKCkge1xuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnaW5wdXQtaWQnKSkge1xuICAgICAgdGhpcy5faW5wdXQuaWQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnaW5wdXQtaWQnKTtcbiAgICB9XG4gIH1cblxuICBnZXQgX2RlZmF1bHRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgZ2V0IF9pbnB1dCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpO1xuICB9XG5cbiAgZ2V0IHZhbHVlKCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dCA9PT0gbnVsbFxuICAgICAgPyB0aGlzLmdldEF0dHJpYnV0ZSgndmFsdWUnKVxuICAgICAgOiB0aGlzLl9pbnB1dC52YWx1ZTtcbiAgfVxuXG4gIHNldCB2YWx1ZSh2YWwpIHtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgdmFsID0gdmFsLnRvSVNPU3RyaW5nKCkuc3Vic3RyaW5nKDAsIDEwKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2lucHV0LnZhbHVlID0gdmFsO1xuICAgICAgdGhpcy5fdXBkYXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuX2JvdW5kRGVsZWdhdGVFdmVudCk7XG4gICAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgdGhpcy5fYm91bmREZWxlZ2F0ZUV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1cycsIHRoaXMuX2JvdW5kRGVsZWdhdGVFdmVudCk7XG4gICAgICB0aGlzLl9pbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKCdibHVyJywgdGhpcy5fYm91bmREZWxlZ2F0ZUV2ZW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ2lucHV0LWlkJywgJ2NsYXNzJywgLi4uSU5QVVRfQVRUUklCVVRFU107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHRoaXMuX3NjaGVtZSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2lucHV0LWlkJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX3NldElucHV0SWQoKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lLCB0aGlzLl9zY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoSU5QVVRfQVRUUklCVVRFUy5pbmRleE9mKG5hbWUpID49IDApIHtcbiAgICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl91cGRhdGVCb3VuZEF0dHJpYnV0ZXMoKSk7XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUlucHV0RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1pbnB1dCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnLnRleHQtaW5wdXQnOiAndGV4dC1pbnB1dC0tKicsXG4gICcudGV4dC1pbnB1dF9fbGFiZWwnOiAndGV4dC1pbnB1dC0tKl9fbGFiZWwnXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1pbnB1dFxuICogQGNhdGVnb3J5IGZvcm1cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogIFtlbl1EaXNwbGF5cyBhIE1hdGVyaWFsIERlc2lnbiBpbnB1dC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIHVuZGVyYmFyXG4gKiAgW2VuXURpc3BsYXlzIGEgaG9yaXpvbnRhbCBsaW5lIHVuZGVybmVhdGggYSB0ZXh0IGlucHV0LlsvZW5dXG4gKiAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgdHJhbnNwYXJlbnRcbiAqICBbZW5dRGlzcGxheXMgYSB0cmFuc3BhcmVudCBpbnB1dC4gV29ya3MgZm9yIE1hdGVyaWFsIERlc2lnbi5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQW4gaW5wdXQgZWxlbWVudC4gVGhlIGB0eXBlYCBhdHRyaWJ1dGUgY2FuIGJlIHVzZWQgdG8gY2hhbmdlIHRoZSBpbnB1dCB0eXBlLiBBbGwgdGV4dCBpbnB1dCB0eXBlcyBhcmUgc3VwcG9ydGVkLlxuICpcbiAqICAgIFRoZSBjb21wb25lbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHJlbmRlciBhcyBhIE1hdGVyaWFsIERlc2lnbiBpbnB1dCBvbiBBbmRyb2lkIGRldmljZXMuXG4gKlxuICogICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8aW5wdXQ+YCBlbGVtZW50IGNhbiBhbHNvIGJlIHVzZWQgb24gdGhlIGA8b25zLWlucHV0PmAgZWxlbWVudC5cbiAqICBbL2VuXVxuICogIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL2lucHV0XG4gKiBAc2VlYWxzbyBvbnMtY2hlY2tib3hcbiAqICAgW2VuXVRoZSBgPG9ucy1jaGVja2JveD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgY2hlY2tib3guWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcmFkaW9cbiAqICAgW2VuXVRoZSBgPG9ucy1yYWRpbz5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgcmFkaW8gYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXJhbmdlXG4gKiAgIFtlbl1UaGUgYDxvbnMtcmFuZ2U+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHJhbmdlIHNsaWRlci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zd2l0Y2hcbiAqICAgW2VuXVRoZSBgPG9ucy1zd2l0Y2g+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIGRyYWdnYWJsZSB0b2dnbGUgc3dpdGNoLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNlbGVjdFxuICogICBbZW5dVGhlIGA8b25zLXNlbGVjdD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgc2VsZWN0IGJveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtaW5wdXQgcGxhY2Vob2xkZXI9XCJVc2VybmFtZVwiIGZsb2F0Pjwvb25zLWlucHV0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJbnB1dEVsZW1lbnQgZXh0ZW5kcyBCYXNlSW5wdXRFbGVtZW50IHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fYm91bmRPbklucHV0ID0gdGhpcy5fdXBkYXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fYm91bmRPbkZvY3VzaW4gPSB0aGlzLl91cGRhdGUuYmluZCh0aGlzKTtcbiAgfVxuXG4gIC8qIEluaGVyaXRlZCBwcm9wcyAqL1xuXG4gIF91cGRhdGUoKSB7XG4gICAgdGhpcy5fdXBkYXRlTGFiZWwoKTtcbiAgICB0aGlzLl91cGRhdGVMYWJlbENsYXNzKCk7XG4gIH1cblxuICBnZXQgX3NjaGVtZSgpIHtcbiAgICByZXR1cm4gc2NoZW1lO1xuICB9XG5cbiAgZ2V0IF90ZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4gYFxuICAgICAgPGlucHV0IHR5cGU9XCIke3RoaXMudHlwZX1cIiBjbGFzcz1cInRleHQtaW5wdXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1pbnB1dF9fbGFiZWxcIj48L3NwYW4+XG4gICAgYDtcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuICAgIHJldHVybiAoWydjaGVja2JveCcsICdyYWRpbyddLmluZGV4T2YodHlwZSkgPCAwKSAmJiB0eXBlIHx8ICd0ZXh0JztcbiAgfVxuXG4gIC8qIE93biBwcm9wcyAqL1xuXG4gIF91cGRhdGVMYWJlbCgpIHtcbiAgICBjb25zdCBsYWJlbCA9IHRoaXMuZ2V0QXR0cmlidXRlKCdwbGFjZWhvbGRlcicpIHx8ICcnO1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzLl9oZWxwZXIudGV4dENvbnRlbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLl9oZWxwZXIudGV4dENvbnRlbnQgPSBsYWJlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faGVscGVyLmlubmVyVGV4dCA9IGxhYmVsO1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVMYWJlbENsYXNzKCkge1xuICAgIGlmICh0aGlzLnZhbHVlID09PSAnJykge1xuICAgICAgdGhpcy5faGVscGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3RleHQtaW5wdXQtLW1hdGVyaWFsX19sYWJlbC0tYWN0aXZlJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2hlbHBlci5jbGFzc0xpc3QuYWRkKCd0ZXh0LWlucHV0LS1tYXRlcmlhbF9fbGFiZWwtLWFjdGl2ZScpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBfaGVscGVyKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4nKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHN1cGVyLmNvbm5lY3RlZENhbGxiYWNrKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5faW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCB0aGlzLl9ib3VuZE9uSW5wdXQpO1xuICAgICAgdGhpcy5faW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXNpbicsIHRoaXMuX2JvdW5kT25Gb2N1c2luKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHR5cGUgPSB0aGlzLmdldEF0dHJpYnV0ZSgndHlwZScpO1xuICAgIGlmIChbJ2NoZWNrYm94JywgJ3JhZGlvJ10uaW5kZXhPZih0eXBlKSA+PSAwKSB7XG4gICAgICB1dGlsLndhcm4oYFdhcm46IDxvbnMtaW5wdXQgdHlwZT1cIiR7dHlwZX1cIj4gaXMgZGVwcmVjYXRlZCBzaW5jZSB2Mi40LjAuIFVzZSA8b25zLSR7dHlwZX0+IGluc3RlYWQuYClcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBzdXBlci5kaXNjb25uZWN0ZWRDYWxsYmFjaygpO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2lucHV0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2lucHV0JywgdGhpcy5fYm91bmRPbklucHV0KTtcbiAgICAgIHRoaXMuX2lucHV0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLCB0aGlzLl9ib3VuZE9uRm9jdXNpbik7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWy4uLnN1cGVyLm9ic2VydmVkQXR0cmlidXRlcywgJ3R5cGUnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICd0eXBlJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX2lucHV0LnNldEF0dHJpYnV0ZSgndHlwZScsIHRoaXMudHlwZSkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwbGFjZWhvbGRlclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUGxhY2Vob2xkZXIgdGV4dC4gSW4gTWF0ZXJpYWwgRGVzaWduLCB0aGlzIHBsYWNlaG9sZGVyIHdpbGwgYmUgYSBmbG9hdGluZyBsYWJlbC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBmbG9hdFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBwcmVzZW50LCB0aGUgcGxhY2Vob2xkZXIgd2lsbCBiZSBhbmltYXRlZCBpbiBNYXRlcmlhbCBEZXNpZ24uWy9lbl1cbiAgICogIFtqYV3jgZPjga7lsZ7mgKfjgYzoqK3lrprjgZXjgozjgZ/mmYLjgIHjg6njg5njg6vjga/jgqLjg4vjg6Hjg7zjgrfjg6fjg7PjgZnjgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0eXBlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVxuICAgKiAgICBTcGVjaWZ5IHRoZSBpbnB1dCB0eXBlLiBUaGlzIGlzIHRoZSBzYW1lIGFzIHRoZSBcInR5cGVcIiBhdHRyaWJ1dGUgZm9yIG5vcm1hbCBpbnB1dHMuIEl0IGV4cGVjdHMgc3RyaWN0IHRleHQgdHlwZXMgc3VjaCBhcyBgdGV4dGAsIGBwYXNzd29yZGAsIGV0Yy4gRm9yIGNoZWNrYm94LCByYWRpbyBidXR0b24sIHNlbGVjdCBvciByYW5nZSwgcGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSBjb3JyZXNwb25kaW5nIGVsZW1lbnRzLlxuICAgKlxuICAgKiAgICBQbGVhc2UgdGFrZSBhIGxvb2sgYXQgW01ETl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2lucHV0I2F0dHItdHlwZSkgZm9yIGFuIGV4aGF1c3RpdmUgbGlzdCBvZiBwb3NzaWJsZSB2YWx1ZXMuIERlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0gYW5kIGJyb3dzZXIgdmVyc2lvbiBzb21lIG9mIHRoZXNlIG1pZ2h0IG5vdCB3b3JrLlxuICAgKiAgWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbnB1dC1pZFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBcImlkXCIgYXR0cmlidXRlIG9mIHRoZSBpbm5lciBgPGlucHV0PmAgZWxlbWVudC4gVGhpcyBpcyB1c2VmdWwgd2hlbiB1c2luZyBgPGxhYmVsIGZvcj1cIi4uLlwiPmAgZWxlbWVudHMuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgaW5wdXQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGlucHV0IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuSW5wdXQgPSBJbnB1dEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1pbnB1dCcsIElucHV0RWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IEJhc2VJbnB1dEVsZW1lbnQgZnJvbSAnLi9iYXNlLWlucHV0JztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXNlQ2hlY2tib3hFbGVtZW50IGV4dGVuZHMgQmFzZUlucHV0RWxlbWVudCB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yID09PSBCYXNlQ2hlY2tib3hFbGVtZW50KSB7XG4gICAgICB1dGlsLnRocm93QWJzdHJhY3QoKTtcbiAgICB9XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soJ2NoZWNrZWQnLCBudWxsLCB0aGlzLmdldEF0dHJpYnV0ZSgnY2hlY2tlZCcpKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qIEluaGVyaXRlZCBwcm9wcyAqL1xuXG4gIGdldCBfdGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxpbnB1dCB0eXBlPVwiJHt0aGlzLnR5cGV9XCIgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X19pbnB1dFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X19jaGVja21hcmtcIj48L3NwYW4+XG4gICAgYDtcbiAgfVxuXG4gIC8qIE93biBwcm9wcyAqL1xuXG4gIGdldCBfaGVscGVyKCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3NwYW4nKTtcbiAgfVxuXG4gIGdldCBjaGVja2VkKCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dC5jaGVja2VkO1xuICB9XG5cbiAgc2V0IGNoZWNrZWQodmFsKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuX2lucHV0LmNoZWNrZWQgPSB2YWw7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWy4uLnN1cGVyLm9ic2VydmVkQXR0cmlidXRlcywgJ2NoZWNrZWQnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjaGVja2VkJzpcbiAgICAgICAgdGhpcy5jaGVja2VkID0gY3VycmVudCAhPT0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUNoZWNrYm94RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1jaGVja2JveCc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5jaGVja2JveCc6ICdjaGVja2JveC0tKicsXG4gICcuY2hlY2tib3hfX2lucHV0JzogJ2NoZWNrYm94LS0qX19pbnB1dCcsXG4gICcuY2hlY2tib3hfX2NoZWNrbWFyayc6ICdjaGVja2JveC0tKl9fY2hlY2ttYXJrJ1xufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtY2hlY2tib3hcbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICBbZW5dRGlzcGxheXMgYSBNYXRlcmlhbCBEZXNpZ24gY2hlY2tib3guWy9lbl1cbiAqICBbamFdWy9qYV1cbiAqIEBtb2RpZmllciBub2JvcmRlclxuICogIFtlbl1pT1MgYm9yZGVybGVzcyBjaGVja2JveC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQSBjaGVja2JveCBlbGVtZW50LiBUaGUgY29tcG9uZW50IHdpbGwgYXV0b21hdGljYWxseSByZW5kZXIgYXMgYSBNYXRlcmlhbCBEZXNpZ24gY2hlY2tib3ggb24gQW5kcm9pZCBkZXZpY2VzLlxuICpcbiAqICAgIE1vc3QgYXR0cmlidXRlcyB0aGF0IGNhbiBiZSB1c2VkIGZvciBhIG5vcm1hbCBgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiPmAgZWxlbWVudCBjYW4gYWxzbyBiZSB1c2VkIG9uIHRoZSBgPG9ucy1jaGVja2JveD5gIGVsZW1lbnQuXG4gKiAgWy9lbl1cbiAqICBbamFdWy9qYV1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9jaGVja2JveFxuICogQHNlZWFsc28gb25zLXN3aXRjaFxuICogICBbZW5dVGhlIGA8b25zLXN3aXRjaD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgZHJhZ2dhYmxlIHRvZ2dsZSBzd2l0Y2guWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcmFkaW9cbiAqICAgW2VuXVRoZSBgPG9ucy1yYWRpbz5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgcmFkaW8gYnV0dG9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWlucHV0XG4gKiAgIFtlbl1UaGUgYDxvbnMtaW5wdXQ+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHRleHQgaW5wdXQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtc2VhcmNoLWlucHV0XG4gKiAgIFtlbl1UaGUgYDxvbnMtc2VhcmNoLWlucHV0PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBzZWFyY2ggaW5wdXQuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcmFuZ2VcbiAqICAgW2VuXVRoZSBgPG9ucy1yYW5nZT5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgcmFuZ2Ugc2xpZGVyLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNlbGVjdFxuICogICBbZW5dVGhlIGA8b25zLXNlbGVjdD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgc2VsZWN0IGJveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtY2hlY2tib3ggY2hlY2tlZD48L29ucy1jaGVja2JveD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2hlY2tib3hFbGVtZW50IGV4dGVuZHMgQmFzZUNoZWNrYm94RWxlbWVudCB7XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ2NoZWNrYm94JztcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAnY2hlY2tib3gnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaW5wdXQtaWRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgXCJpZFwiIGF0dHJpYnV0ZSBvZiB0aGUgaW5uZXIgYDxpbnB1dD5gIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYDxsYWJlbCBmb3I9XCIuLi5cIj5gIGVsZW1lbnRzLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2YWx1ZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGNoZWNrYm94LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2hlY2tlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGNoZWNrYm94IGlzIGNoZWNrZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBjaGVja2JveCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG59XG5cbm9uc0VsZW1lbnRzLkNoZWNrYm94ID0gQ2hlY2tib3hFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtY2hlY2tib3gnLCBDaGVja2JveEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VDaGVja2JveEVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtY2hlY2tib3gnO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcucmFkaW8tYnV0dG9uJzogJ3JhZGlvLWJ1dHRvbi0tKicsXG4gICcucmFkaW8tYnV0dG9uX19pbnB1dCc6ICdyYWRpby1idXR0b24tLSpfX2lucHV0JyxcbiAgJy5yYWRpby1idXR0b25fX2NoZWNrbWFyayc6ICdyYWRpby1idXR0b24tLSpfX2NoZWNrbWFyaydcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXJhZGlvXG4gKiBAY2F0ZWdvcnkgZm9ybVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgW2VuXURpc3BsYXlzIGEgTWF0ZXJpYWwgRGVzaWduIHJhZGlvIGJ1dHRvbi5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQSByYWRpbyBidXR0b24gZWxlbWVudC4gVGhlIGNvbXBvbmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgcmVuZGVyIGFzIGEgTWF0ZXJpYWwgRGVzaWduIHJhZGlvIGJ1dHRvbiBvbiBBbmRyb2lkIGRldmljZXMuXG4gKlxuICogICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8aW5wdXQgdHlwZT1cInJhZGlvXCI+YCBlbGVtZW50IGNhbiBhbHNvIGJlIHVzZWQgb24gdGhlIGA8b25zLXJhZGlvPmAgZWxlbWVudC5cbiAqICBbL2VuXVxuICogIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3JhZGlvXG4gKiBAc2VlYWxzbyBvbnMtc2VsZWN0XG4gKiAgIFtlbl1UaGUgYDxvbnMtc2VsZWN0PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBzZWxlY3QgYm94LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWNoZWNrYm94XG4gKiAgIFtlbl1UaGUgYDxvbnMtY2hlY2tib3g+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIGNoZWNrYm94LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXN3aXRjaFxuICogICBbZW5dVGhlIGA8b25zLXN3aXRjaD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgZHJhZ2dhYmxlIHRvZ2dsZSBzd2l0Y2guWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAc2VlYWxzbyBvbnMtaW5wdXRcbiAqICAgW2VuXVRoZSBgPG9ucy1pbnB1dD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgdGV4dCBpbnB1dC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zZWFyY2gtaW5wdXRcbiAqICAgW2VuXVRoZSBgPG9ucy1zZWFyY2gtaW5wdXQ+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHNlYXJjaCBpbnB1dC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1yYW5nZVxuICogICBbZW5dVGhlIGA8b25zLXJhbmdlPmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSByYW5nZSBzbGlkZXIuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXJhZGlvIGNoZWNrZWQ+PC9vbnMtcmFkaW8+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJhZGlvRWxlbWVudCBleHRlbmRzIEJhc2VDaGVja2JveEVsZW1lbnQge1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBnZXQgX2RlZmF1bHRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdyYWRpby1idXR0b24nO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdyYWRpbyc7XG4gIH1cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbnB1dC1pZFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IHRoZSBcImlkXCIgYXR0cmlidXRlIG9mIHRoZSBpbm5lciBgPGlucHV0PmAgZWxlbWVudC4gVGhpcyBpcyB1c2VmdWwgd2hlbiB1c2luZyBgPGxhYmVsIGZvcj1cIi4uLlwiPmAgZWxlbWVudHMuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcmFkaW8gYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2hlY2tlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIHJhZGlvIGJ1dHRvbiBpcyBjaGVja2VkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgcmFkaW8gYnV0dG9uIGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuUmFkaW8gPSBSYWRpb0VsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1yYWRpbycsIFJhZGlvRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgQmFzZUlucHV0RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1pbnB1dCc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5zZWFyY2gtaW5wdXQnOiAnc2VhcmNoLWlucHV0LS0qJ1xufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc2VhcmNoLWlucHV0XG4gKiBAY2F0ZWdvcnkgZm9ybVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgW2VuXURpc3BsYXlzIGEgTWF0ZXJpYWwgRGVzaWduIHNlYXJjaCBpbnB1dC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgQSBzZWFyY2ggaW5wdXQgZWxlbWVudC4gVGhlIGNvbXBvbmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgcmVuZGVyIGFzIGEgTWF0ZXJpYWwgRGVzaWduIHNlYXJjaCBpbnB1dCBvbiBBbmRyb2lkIGRldmljZXMuXG4gKlxuICogICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8aW5wdXQ+YCBlbGVtZW50IGNhbiBhbHNvIGJlIHVzZWQgb24gdGhlIGA8b25zLXNlYXJjaC1pbnB1dD5gIGVsZW1lbnQuXG4gKiAgWy9lbl1cbiAqICBbamFdWy9qYV1cbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zZWFyY2gtaW5wdXRcbiAqIEBzZWVhbHNvIG9ucy1pbnB1dFxuICogICBbZW5dVGhlIGA8b25zLWlucHV0PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSB0ZXh0IGlucHV0LlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXJhbmdlXG4gKiAgIFtlbl1UaGUgYDxvbnMtcmFuZ2U+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIHJhbmdlIHNsaWRlci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zd2l0Y2hcbiAqICAgW2VuXVRoZSBgPG9ucy1zd2l0Y2g+YCBlbGVtZW50IGlzIHVzZWQgdG8gZGlzcGxheSBhIGRyYWdnYWJsZSB0b2dnbGUgc3dpdGNoLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXNlbGVjdFxuICogICBbZW5dVGhlIGA8b25zLXNlbGVjdD5gIGVsZW1lbnQgaXMgdXNlZCB0byBkaXNwbGF5IGEgc2VsZWN0IGJveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1jaGVja2JveFxuICogICBbZW5dVGhlIGA8b25zLWNoZWNrYm94PmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBjaGVja2JveC5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1yYWRpb1xuICogICBbZW5dVGhlIGA8b25zLXJhZGlvPmAgZWxlbWVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSByYWRpbyBidXR0b24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNlYXJjaC1pbnB1dCBwbGFjZWhvbGRlcj1cIlNlYXJjaFwiPjwvb25zLXNlYXJjaC1pbnB1dD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VhcmNoSW5wdXRFbGVtZW50IGV4dGVuZHMgQmFzZUlucHV0RWxlbWVudCB7XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfdGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxpbnB1dCB0eXBlPVwiJHt0aGlzLnR5cGV9XCIgY2xhc3M9XCJzZWFyY2gtaW5wdXRcIj5cbiAgICBgO1xuICB9XG5cbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICdzZWFyY2gnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaW5wdXQtaWRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgXCJpZFwiIGF0dHJpYnV0ZSBvZiB0aGUgaW5uZXIgYDxpbnB1dD5gIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYDxsYWJlbCBmb3I9XCIuLi5cIj5gIGVsZW1lbnRzLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2YWx1ZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGlucHV0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBpbnB1dCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG59XG5cbm9uc0VsZW1lbnRzLlNlYXJjaElucHV0ID0gU2VhcmNoSW5wdXRFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc2VhcmNoLWlucHV0JywgU2VhcmNoSW5wdXRFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNb2RhbEFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMudGltaW5nXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmR1cmF0aW9uXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmRlbGF5XG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IG1vZGFsXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KG1vZGFsLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxufVxuIiwiXG4vKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IE1vZGFsQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogaU9TIHN0eWxlIGFuaW1hdG9yIGZvciBkaWFsb2cuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZhZGVNb2RhbEFuaW1hdG9yIGV4dGVuZHMgTW9kYWxBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4zfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBtb2RhbFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyhtb2RhbCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0KG1vZGFsLCB0aGlzLmRlZilcbiAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSlcbiAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSlcbiAgICAgIC5wbGF5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdChtb2RhbCwgdGhpcy5kZWYpXG4gICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH0pXG4gICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IE1vZGFsQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogaU9TIHN0eWxlIGFuaW1hdG9yIGZvciBtb2RhbC5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaWZ0TW9kYWxBbmltYXRvciBleHRlbmRzIE1vZGFsQW5pbWF0b3JcbntcbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoIC4xLCAuNywgLjEsIDEpJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuNH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHNob3cobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdChtb2RhbCwgdGhpcy5kZWYpXG4gICAgICAuZGVmYXVsdChcbiAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAxMDAlLCAwKScgfSxcbiAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScgfVxuICAgICAgKVxuICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KVxuICAgICAgLnBsYXkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBtb2RhbFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgaGlkZShtb2RhbCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0KG1vZGFsLCB0aGlzLmRlZilcbiAgICAgIC5kZWZhdWx0KFxuICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9LFxuICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDEwMCUsIDApJyB9XG4gICAgICApXG4gICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgTW9kYWxBbmltYXRvciBmcm9tICcuL2FuaW1hdG9yJztcbmltcG9ydCBGYWRlTW9kYWxBbmltYXRvciBmcm9tICcuL2ZhZGUtYW5pbWF0b3InO1xuaW1wb3J0IExpZnRNb2RhbEFuaW1hdG9yIGZyb20gJy4vbGlmdC1hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnbW9kYWwtLSonLFxuICAnbW9kYWxfX2NvbnRlbnQnOiAnbW9kYWwtLSpfX2NvbnRlbnQnXG59O1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ21vZGFsJztcblxuY29uc3QgX2FuaW1hdG9yRGljdCA9IHtcbiAgJ2RlZmF1bHQnOiBNb2RhbEFuaW1hdG9yLFxuICAnZmFkZSc6IEZhZGVNb2RhbEFuaW1hdG9yLFxuICAnbGlmdCc6IExpZnRNb2RhbEFuaW1hdG9yLFxuICAnbm9uZSc6IE1vZGFsQW5pbWF0b3Jcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLW1vZGFsXG4gKiBAY2F0ZWdvcnkgZGlhbG9nXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIE1vZGFsIGNvbXBvbmVudCB0aGF0IG1hc2tzIGN1cnJlbnQgc2NyZWVuLiBVbmRlcmx5aW5nIGNvbXBvbmVudHMgYXJlIG5vdCBzdWJqZWN0IHRvIGFueSBldmVudHMgd2hpbGUgdGhlIG1vZGFsIGNvbXBvbmVudCBpcyBzaG93bi5cbiAqXG4gKiAgICAgVGhpcyBjb21wb25lbnQgY2FuIGJlIHVzZWQgdG8gYmxvY2sgdXNlciBpbnB1dCB3aGlsZSBzb21lIG9wZXJhdGlvbiBpcyBydW5uaW5nIG9yIHRvIHNob3cgc29tZSBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci5cbiAqICAgWy9lbl1cbiAqICAgW2phXVxuICogICAgIOeUu+mdouWFqOS9k+OCkuODnuOCueOCr+OBmeOCi+ODouODvOODgOODq+eUqOOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAguS4i+WBtOOBq+OBguOCi+OCs+ODs+ODneODvOODjeODs+ODiOOBr+OAgVxuICogICAgIOODouODvOODgOODq+OBjOihqOekuuOBleOCjOOBpuOBhOOCi+mWk+OBr+OCpOODmeODs+ODiOmAmuefpeOBjOihjOOCj+OCjOOBvuOBm+OCk+OAglxuICogICBbL2phXVxuICogQHNlZWFsc28gb25zLWRpYWxvZ1xuICogICBbZW5dVGhlIGA8b25zLWRpYWxvZz5gIGNvbXBvbmVudCBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYSBtb2RhbCBkaWFsb2cuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiBkZXZJZ1xuICogQHR1dG9yaWFsIHZhbmlsbGEvcmVmZXJlbmNlL21vZGFsXG4gKiBAZXhhbXBsZVxuICogPG9ucy1tb2RhbCBpZD1cIm1vZGFsXCI+XG4gKiAgIE1vZGFsIGNvbnRlbnRcbiAqIDwvb25zLW1vZGFsPlxuICogPHNjcmlwdD5cbiAqICAgdmFyIG1vZGFsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ21vZGFsJyk7XG4gKiAgIG1vZGFsLnNob3coKTtcbiAqIDwvc2NyaXB0PlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNb2RhbEVsZW1lbnQgZXh0ZW5kcyBCYXNlRGlhbG9nRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIG1vZGFsIGlzIGRpc3BsYXllZC5bL2VuXVxuICAgKiBbamFd44Oi44O844OA44Or44GM6KGo56S644GV44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm1vZGFsXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUV4ZWN1dGUgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBtb2RhbCBmcm9tIGJlaW5nIHNob3duLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWun+ihjOOBmeOCi+OBqOOAgeODgOOCpOOCouODreOCsOOBruihqOekuuOBjOOCreODo+ODs+OCu+ODq+OBleOCjOOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdHNob3dcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBtb2RhbCBpcyBkaXNwbGF5ZWQuWy9lbl1cbiAgICogW2phXeODouODvOODgOODq+OBjOihqOekuuOBleOCjOOBn+ebtOW+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5tb2RhbFxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBtb2RhbCBpcyBoaWRkZW4uWy9lbl1cbiAgICogW2phXeODouODvOODgOODq+OBjOmaoOOCjOOCi+ebtOWJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5tb2RhbFxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1FeGVjdXRlIHRoaXMgZnVuY3Rpb24gdG8gc3RvcCB0aGUgbW9kYWwgZnJvbSBiZWluZyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5a6f6KGM44GZ44KL44Go44CB44OA44Kk44Ki44Ot44Kw44Gu6Z2e6KGo56S644GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0aGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIG1vZGFsIGlzIGhpZGRlbi5bL2VuXVxuICAgKiBbamFd44Oi44O844OA44Or44GM6Zqg44KM44Gf5b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm1vZGFsXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSBtb2RhbC4gQ2FuIGJlIGVpdGhlciBgXCJub25lXCJgLCBgXCJmYWRlXCJgIG9yIGBcImxpZnRcImAuWy9lbl1cbiAgICogIFtqYV3jg6Ljg7zjg4Djg6vjgpLooajnpLrjgZnjgovpmpvjga7jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIuOCguOBl+OBj+OBr1wiZmFkZVwiLFwibGlmdFwi44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiA8Y29kZT57ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfTwvY29kZT5bL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fZGVmYXVsdERCQiA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBfdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCkge1xuICAgIHJldHVybiBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogTW9kYWxBbmltYXRvcixcbiAgICAgIGJhc2VDbGFzc05hbWU6ICdNb2RhbEFuaW1hdG9yJyxcbiAgICAgIGRlZmF1bHRBbmltYXRpb246IHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24nKVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvbkRldmljZUJhY2tCdXR0b25cbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJhY2stYnV0dG9uIGhhbmRsZXIuWy9lbl1cbiAgICogICBbamFd44OQ44OD44Kv44Oc44K/44Oz44OP44Oz44OJ44Op44CCWy9qYV1cbiAgICovXG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMuc3R5bGUuekluZGV4ID0gMTAwMDE7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuXG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLm1vZGFsX19jb250ZW50JykpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGNvbnRlbnQuY2xhc3NMaXN0LmFkZCgnbW9kYWxfX2NvbnRlbnQnKTtcblxuICAgICAgd2hpbGUgKHRoaXMuY2hpbGROb2Rlc1swXSkge1xuICAgICAgICBjb25zdCBub2RlID0gdGhpcy5jaGlsZE5vZGVzWzBdO1xuICAgICAgICB0aGlzLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICBjb250ZW50Lmluc2VydEJlZm9yZShub2RlLCBudWxsKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZChjb250ZW50KTtcbiAgICB9XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHRoaXMuX3NjaGVtZSk7XG4gIH1cblxuICBfdG9nZ2xlU3R5bGUoc2hvdWxkU2hvdykge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHNob3VsZFNob3cgPyAndGFibGUnIDogJ25vbmUnO1xuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc3VwZXIuY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHN1cGVyLmRpc2Nvbm5lY3RlZENhbGxiYWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZpc2libGVcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdyhbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcIm5vbmVcImAgYW5kIGBcImZhZGVcImAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJub25lXCIsIFwiZmFkZVwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1UaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgbW9kYWwgaGFzIGJlZW4gcmV2ZWFsZWQuWy9lbl1cbiAgICogICBbamFd44Oi44O844OA44Or44GM6KGo56S644GV44KM57WC44KP44Gj44Gf5b6M44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNob3cgbW9kYWwuWy9lbl1cbiAgICogICBbamFd44Oi44O844OA44Or44KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUFuaW1hdGlvbiBuYW1lLiBBdmFpbGFibGUgYW5pbWF0aW9ucyBhcmUgYFwibm9uZVwiYCBhbmQgYFwiZmFkZVwiYC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJcIm5vbmVcIiwgXCJmYWRlXCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFmdGVyIHRoZSBtb2RhbCBoYXMgYmVlbiByZXZlYWxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg6Ljg7zjg4Djg6vjgYzooajnpLrjgZXjgozntYLjgo/jgaPjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVG9nZ2xlIG1vZGFsIHZpc2liaWxpdHkuWy9lbl1cbiAgICogICBbamFd44Oi44O844OA44Or44Gu6KGo56S644KS5YiH44KK5pu/44GI44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJub25lXCJgIGFuZCBgXCJmYWRlXCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwibm9uZVwiLCBcImZhZGVcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgdGhlIG1vZGFsIGhhcyBiZWVuIHJldmVhbGVkLlsvZW5dXG4gICAqICAgW2phXeODouODvOODgOODq+OBjOihqOekuuOBleOCjOe1guOCj+OBo+OBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIG1vZGFsLlsvZW5dXG4gICAqICAgW2phXeODouODvOODgOODq+OCkumdnuihqOekuuOBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbLi4uc3VwZXIub2JzZXJ2ZWRBdHRyaWJ1dGVzLCAnY2xhc3MnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdjbGFzcycpIHtcbiAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gQW5pbWF0b3JcbiAgICovXG4gIHN0YXRpYyByZWdpc3RlckFuaW1hdG9yKG5hbWUsIEFuaW1hdG9yKSB7XG4gICAgaWYgKCEoQW5pbWF0b3IucHJvdG90eXBlIGluc3RhbmNlb2YgTW9kYWxBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignTW9kYWwnKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IE1vZGFsQW5pbWF0b3IoKSB7XG4gICAgcmV0dXJuIE1vZGFsQW5pbWF0b3I7XG4gIH1cbn1cblxub25zRWxlbWVudHMuTW9kYWwgPSBNb2RhbEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1tb2RhbCcsIE1vZGFsRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgR2VzdHVyZURldGVjdG9yIGZyb20gJy4uLy4uL29ucy9nZXN0dXJlLWRldGVjdG9yJztcblxuY29uc3Qgd2lkdGhUb1B4ID0gKHdpZHRoKSA9PiB7XG4gIGNvbnN0IFt2YWx1ZSwgcHhdID0gW3BhcnNlSW50KHdpZHRoLCAxMCksIC9weC8udGVzdCh3aWR0aCldO1xuICByZXR1cm4gcHggPyB2YWx1ZSA6IE1hdGgucm91bmQoZG9jdW1lbnQuYm9keS5vZmZzZXRXaWR0aCAqIHZhbHVlIC8gMTAwKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN3aXBlUmV2ZWFsIHtcblxuICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcbiAgICAnZWxlbWVudCBpZ25vcmVTd2lwZSBpc0luaXRpYWxTdGF0ZSBvbkRyYWdDYWxsYmFjayBzd2lwZU1heCBzd2lwZU1pbiBzd2lwZU1pZCdcbiAgICAgIC5zcGxpdCgvXFxzKy8pLmZvckVhY2goa2V5ID0+IHRoaXNba2V5XSA9IHBhcmFtc1trZXldKTtcblxuICAgIHRoaXMuZWxlbWVudEhhbmRsZXIgPSBwYXJhbXMuZWxlbWVudEhhbmRsZXIgfHwgcGFyYW1zLmVsZW1lbnQ7XG4gICAgdGhpcy5nZXRUaHJlc2hvbGQgPSBwYXJhbXMuZ2V0VGhyZXNob2xkIHx8ICgoKSA9PiAuNSk7XG4gICAgdGhpcy5nZXRTaWRlID0gcGFyYW1zLmdldFNpZGUgfHwgKCgpID0+ICdsZWZ0Jyk7XG5cbiAgICB0aGlzLmhhbmRsZUdlc3R1cmUgPSB0aGlzLmhhbmRsZUdlc3R1cmUuYmluZCh0aGlzKTtcblxuICAgIHRoaXMuX3Nob3VsZEZpeFNjcm9sbCA9IHV0aWwuZ2xvYmFscy5hY3R1YWxNb2JpbGVPUyA9PT0gJ2lvcyc7XG4gIH1cblxuICB1cGRhdGUoc3dpcGVhYmxlID0gdGhpcy5lbGVtZW50Lmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJykpIHtcbiAgICBpZiAoIXRoaXMuZ2VzdHVyZURldGVjdG9yKSB7XG4gICAgICB0aGlzLmdlc3R1cmVEZXRlY3RvciA9IG5ldyBHZXN0dXJlRGV0ZWN0b3IodGhpcy5lbGVtZW50SGFuZGxlciwgeyBkcmFnTWluRGlzdGFuY2U6IDEsIHBhc3NpdmU6ICF0aGlzLl9zaG91bGRGaXhTY3JvbGwgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aW9uID0gc3dpcGVhYmxlID8gJ29uJyA6ICdvZmYnO1xuICAgIHRoaXMuZ2VzdHVyZURldGVjdG9yW2FjdGlvbl0oJ2RyYWcgZHJhZ3N0YXJ0IGRyYWdlbmQnLCB0aGlzLmhhbmRsZUdlc3R1cmUpO1xuICB9XG5cbiAgaGFuZGxlR2VzdHVyZShlKSB7XG4gICAgaWYgKGUuZ2VzdHVyZSkge1xuICAgICAgaWYgKGUudHlwZSA9PT0gJ2RyYWdzdGFydCcpIHtcbiAgICAgICAgdGhpcy5vbkRyYWdTdGFydChlKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRoaXMuX2lnbm9yZURyYWcpIHtcbiAgICAgICAgZS50eXBlID09PSAnZHJhZ2VuZCcgPyB0aGlzLm9uRHJhZ0VuZChlKSA6IHRoaXMub25EcmFnKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGV2ZW50KSB7XG4gICAgY29uc3QgZ2V0RGlzdGFuY2UgPSAoKSA9PiB0aGlzLmdldFNpZGUoKSA9PT0gJ2xlZnQnID8gZXZlbnQuZ2VzdHVyZS5jZW50ZXIuY2xpZW50WCA6IHdpbmRvdy5pbm5lcldpZHRoIC0gZXZlbnQuZ2VzdHVyZS5jZW50ZXIuY2xpZW50WDtcbiAgICB0aGlzLl9pZ25vcmVEcmFnID0gZXZlbnQuY29uc3VtZWQgfHwgIXV0aWwuaXNWYWxpZEdlc3R1cmUoZXZlbnQpIHx8IHRoaXMuaWdub3JlU3dpcGUoZXZlbnQsIGdldERpc3RhbmNlKCkpO1xuXG4gICAgaWYgKCF0aGlzLl9pZ25vcmVEcmFnKSB7XG4gICAgICBldmVudC5jb25zdW1lICYmIGV2ZW50LmNvbnN1bWUoKTtcbiAgICAgIGV2ZW50LmNvbnN1bWVkID0gdHJ1ZTtcblxuICAgICAgdGhpcy5fd2lkdGggPSB3aWR0aFRvUHgodGhpcy5lbGVtZW50LnN0eWxlLndpZHRoIHx8ICcxMDAlJyk7XG4gICAgICB0aGlzLl9zdGFydERpc3RhbmNlID0gdGhpcy5fZGlzdGFuY2UgPSAoISh0aGlzLmlzSW5pdGlhbFN0YXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHx8IHRoaXMuaXNJbml0aWFsU3RhdGUoKSkgPyAwIDogdGhpcy5fd2lkdGg7XG5cbiAgICAgIHV0aWwuaW9zUHJldmVudFNjcm9sbCh0aGlzLmdlc3R1cmVEZXRlY3Rvcik7XG4gICAgfVxuICB9XG5cbiAgb25EcmFnKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBjb25zdCBkZWx0YSA9IHRoaXMuZ2V0U2lkZSgpID09PSAnbGVmdCcgPyBldmVudC5nZXN0dXJlLmRlbHRhWCA6IC1ldmVudC5nZXN0dXJlLmRlbHRhWDtcbiAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGgubWF4KDAsIE1hdGgubWluKHRoaXMuX3dpZHRoLCB0aGlzLl9zdGFydERpc3RhbmNlICsgZGVsdGEpKTtcbiAgICBpZiAoZGlzdGFuY2UgIT09IHRoaXMuX2Rpc3RhbmNlKSB7XG4gICAgICB0aGlzLl9kaXN0YW5jZSA9IGRpc3RhbmNlO1xuICAgICAgdGhpcy5zd2lwZU1pZCh0aGlzLl9kaXN0YW5jZSwgdGhpcy5fd2lkdGgpO1xuICAgIH1cbiAgfVxuXG4gIG9uRHJhZ0VuZChldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQuZ2VzdHVyZS5pbnRlcmltRGlyZWN0aW9uO1xuICAgIGNvbnN0IGlzU3dpcGVNYXggPSB0aGlzLmdldFNpZGUoKSAhPT0gZGlyZWN0aW9uICYmIHRoaXMuX2Rpc3RhbmNlID4gdGhpcy5fd2lkdGggKiB0aGlzLmdldFRocmVzaG9sZCgpO1xuICAgIGlzU3dpcGVNYXggPyB0aGlzLnN3aXBlTWF4KCkgOiB0aGlzLnN3aXBlTWluKCk7XG4gIH1cblxuICBkaXNwb3NlKCkge1xuICAgIHRoaXMuZ2VzdHVyZURldGVjdG9yICYmIHRoaXMuZ2VzdHVyZURldGVjdG9yLmRpc3Bvc2UoKTtcbiAgICB0aGlzLmdlc3R1cmVEZXRlY3RvciA9IHRoaXMuZWxlbWVudCA9IHRoaXMuZWxlbWVudEhhbmRsZXIgPSBudWxsO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUFuaW1hdG9yIGZyb20gJy4uLy4uL29ucy9iYXNlLWFuaW1hdG9yJ1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIEJhc2VBbmltYXRvciB7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLnRpbWluZ1xuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kdXJhdGlvblxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5kZWxheVxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB1dGlsLmV4dGVuZCh7XG4gICAgICB0aW1pbmc6ICdsaW5lYXInLFxuICAgICAgZHVyYXRpb246ICcwLjQnLFxuICAgICAgZGVsYXk6ICcwJ1xuICAgIH0sIG9wdGlvbnMgfHwge30pO1xuXG4gICAgc3VwZXIob3B0aW9ucyk7XG4gIH1cblxuICBwdXNoKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cblxuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGJsb2NrKHBhZ2UpIHtcbiAgICBjb25zdCBibG9ja2VyID0gdXRpbC5jcmVhdGVFbGVtZW50KGBcbiAgICAgIDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyB6LWluZGV4OiAxMDAwMDBcIj48L2Rpdj5cbiAgICBgKTtcbiAgICBwYWdlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoYmxvY2tlcik7XG4gICAgcmV0dXJuICgpID0+IGJsb2NrZXIucmVtb3ZlKCk7XG4gIH1cbn1cblxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcblxuLyoqXG4gKiBBYnN0cmFjdCBzd2lwZSBhbmltYXRvciBmb3IgaU9TIG5hdmlnYXRvciB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJT1NTd2lwZU5hdmlnYXRvckFuaW1hdG9yIGV4dGVuZHMgTmF2aWdhdG9yQW5pbWF0b3Ige1xuXG4gIHN0YXRpYyBnZXQgc3dpcGVhYmxlKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoeyBkdXJhdGlvblJlc3RvcmUgPSAwLjEsIGR1cmF0aW9uU3dpcGUgPSAwLjE1LCB0aW1pbmdTd2lwZSA9ICdsaW5lYXInLCAuLi5yZXN0IH0gPSB7fSkge1xuICAgIHN1cGVyKHsuLi5yZXN0fSk7XG5cbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciA9PT0gSU9TU3dpcGVOYXZpZ2F0b3JBbmltYXRvcikge1xuICAgICAgdXRpbC50aHJvd0Fic3RyYWN0KCk7XG4gICAgfVxuXG4gICAgdGhpcy5kdXJhdGlvblJlc3RvcmUgPSBkdXJhdGlvblJlc3RvcmU7XG4gICAgdGhpcy5kdXJhdGlvblN3aXBlID0gZHVyYXRpb25Td2lwZTtcbiAgICB0aGlzLnRpbWluZ1N3aXBlID0gdGltaW5nU3dpcGU7XG5cbiAgICB0aGlzLm9wdFN3aXBlID0geyB0aW1pbmc6IHRpbWluZ1N3aXBlLCBkdXJhdGlvbjogZHVyYXRpb25Td2lwZSB9O1xuICAgIHRoaXMub3B0UmVzdG9yZSA9IHsgdGltaW5nOiB0aW1pbmdTd2lwZSwgZHVyYXRpb246IGR1cmF0aW9uUmVzdG9yZSB9O1xuXG4gICAgdGhpcy5zd2lwZVNoYWRvdyA9IHV0aWwuY3JlYXRlRWxlbWVudChcbiAgICAgIGA8ZGl2IHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyBoZWlnaHQ6IDEwMCU7IHdpZHRoOiAxMnB4OyByaWdodDogMTAwJTsgdG9wOiAwOyBib3R0b206IDA7IHotaW5kZXg6IC0xO2AgK1xuICAgICAgICBgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCB0cmFuc3BhcmVudCAwLCByZ2JhKDAsMCwwLC4wNCkgNDAlLCByZ2JhKDAsMCwwLC4xMikgODAlLCByZ2JhKDAsMCwwLC4xNikgMTAwJSk7XCI+PC9kaXY+YFxuICAgICk7XG5cbiAgICB0aGlzLmlzRHJhZ1N0YXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIF9kZWNvbXBvc2UoKSB7XG4gICAgdXRpbC50aHJvd01lbWJlcigpO1xuICB9XG5cbiAgX3Nob3VsZEFuaW1hdGVUb29sYmFyKCkge1xuICAgIHV0aWwudGhyb3dNZW1iZXIoKTtcbiAgfVxuXG4gIF9jYWxjdWxhdGVEZWx0YSgpIHtcbiAgICB1dGlsLnRocm93TWVtYmVyKCk7XG4gIH1cblxuICBfZHJhZ1N0YXJ0U2V0dXAoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UpIHtcbiAgICB0aGlzLmlzRHJhZ1N0YXJ0ID0gZmFsc2U7XG5cbiAgICAvLyBBdm9pZCBjb250ZW50IGNsaWNrc1xuICAgIHRoaXMudW5ibG9jayA9IHN1cGVyLmJsb2NrKGxlYXZlUGFnZSk7XG5cbiAgICAvLyBNYXNrXG4gICAgZW50ZXJQYWdlLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKHRoaXMuYmFja2dyb3VuZE1hc2ssIGVudGVyUGFnZSk7XG5cbiAgICAvLyBEZWNvbXBvc2l0aW9uXG4gICAgdGhpcy50YXJnZXQgPSB7XG4gICAgICBlbnRlcjogdXRpbC5maW5kVG9vbGJhclBhZ2UoZW50ZXJQYWdlKSB8fCBlbnRlclBhZ2UsXG4gICAgICBsZWF2ZTogdXRpbC5maW5kVG9vbGJhclBhZ2UobGVhdmVQYWdlKSB8fCBsZWF2ZVBhZ2UsXG4gICAgfTtcbiAgICB0aGlzLmRlY29tcCA9IHtcbiAgICAgIGVudGVyOiB0aGlzLl9kZWNvbXBvc2UodGhpcy50YXJnZXQuZW50ZXIpLFxuICAgICAgbGVhdmU6IHRoaXMuX2RlY29tcG9zZSh0aGlzLnRhcmdldC5sZWF2ZSlcbiAgICB9O1xuXG4gICAgLy8gQW5pbWF0aW9uIHZhbHVlc1xuICAgIHRoaXMuZGVsdGEgPSB0aGlzLl9jYWxjdWxhdGVEZWx0YShsZWF2ZVBhZ2UsIHRoaXMuZGVjb21wLmxlYXZlKTtcbiAgICB0aGlzLnNob3VsZEFuaW1hdGVUb29sYmFyID0gdGhpcy5fc2hvdWxkQW5pbWF0ZVRvb2xiYXIodGhpcy50YXJnZXQuZW50ZXIsIHRoaXMudGFyZ2V0LmxlYXZlKTtcblxuICAgIC8vIFNoYWRvdyAmJiBzdHlsZXNcbiAgICBpZiAodGhpcy5zaG91bGRBbmltYXRlVG9vbGJhcikge1xuICAgICAgdGhpcy5zd2lwZVNoYWRvdy5zdHlsZS50b3AgPSB0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyLm9mZnNldEhlaWdodCArICdweCc7XG4gICAgICB0aGlzLnRhcmdldC5sZWF2ZS5hcHBlbmRDaGlsZCh0aGlzLnN3aXBlU2hhZG93KTtcbiAgICAgIHRoaXMuX3NhdmVTdHlsZSh0aGlzLnRhcmdldC5lbnRlciwgdGhpcy50YXJnZXQubGVhdmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZWF2ZVBhZ2UuYXBwZW5kQ2hpbGQodGhpcy5zd2lwZVNoYWRvdyk7XG4gICAgICB0aGlzLl9zYXZlU3R5bGUoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UpO1xuICAgIH1cbiAgICBsZWF2ZVBhZ2UuY2xhc3NMaXN0LmFkZCgnb3ZlcmZsb3ctdmlzaWJsZScpO1xuICAgIHRoaXMub3ZlcmZsb3dFbGVtZW50ID0gbGVhdmVQYWdlO1xuICAgIHRoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQuY2xhc3NMaXN0LmFkZCgnY29udGVudC1zd2lwaW5nJyk7XG5cbiAgfVxuXG4gIHRyYW5zbGF0ZShkaXN0YW5jZSwgbWF4V2lkdGgsIGVudGVyUGFnZSwgbGVhdmVQYWdlKSB7XG4gICAgdGhpcy5pc1N3aXBpbmcgPSB0cnVlO1xuXG4gICAgaWYgKGVudGVyUGFnZS5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIGVudGVyUGFnZS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNEcmFnU3RhcnQpIHtcbiAgICAgIHRoaXMubWF4V2lkdGggPSBtYXhXaWR0aDtcbiAgICAgIHRoaXMuX2RyYWdTdGFydFNldHVwKGVudGVyUGFnZSwgbGVhdmVQYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCBzd2lwZVJhdGlvID0gKGRpc3RhbmNlIC0gbWF4V2lkdGgpIC8gbWF4V2lkdGg7XG5cbiAgICBpZiAodGhpcy5zaG91bGRBbmltYXRlVG9vbGJhcikge1xuXG4gICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgIC8qIEVudGVyIHBhZ2UgKi9cblxuICAgICAgICBhbmltaXQoW3RoaXMuZGVjb21wLmVudGVyLmNvbnRlbnQsIHRoaXMuZGVjb21wLmVudGVyLmJvdHRvbVRvb2xiYXIsIHRoaXMuZGVjb21wLmVudGVyLmJhY2tncm91bmRdKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3N3aXBlUmF0aW8gKiAyNX0lLCAwLCAwKWAsXG4gICAgICAgICAgICBvcGFjaXR5OiAxICsgc3dpcGVSYXRpbyAqIDEwIC8gMTAwIC8vIDAuOSAtPiAxXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLnRvb2xiYXJDZW50ZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5kZWx0YS50aXRsZSAqIHN3aXBlUmF0aW99cHgsIDAsIDApYCxcbiAgICAgICAgICAgIG9wYWNpdHk6IDEgKyBzd2lwZVJhdGlvIC8vIDAgLT4gMVxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5lbnRlci5iYWNrQnV0dG9uTGFiZWwpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEgKyBzd2lwZVJhdGlvICogMTAgLyAxMDAsIC8vIDAuOSAtPiAxXG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMuZGVsdGEubGFiZWwgKiBzd2lwZVJhdGlvfXB4LCAwLCAwKWBcbiAgICAgICAgICB9KSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAuZW50ZXIub3RoZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDEgKyBzd2lwZVJhdGlvIC8vIDAgLT4gMVxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIC8qIExlYXZlIHBhZ2UgKi9cblxuICAgICAgICBhbmltaXQoW3RoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQsIHRoaXMuZGVjb21wLmxlYXZlLmJvdHRvbVRvb2xiYXIsIHRoaXMuZGVjb21wLmxlYXZlLmJhY2tncm91bmQsIHRoaXMuc3dpcGVTaGFkb3ddKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke2Rpc3RhbmNlfXB4LCAwLCAwKWBcbiAgICAgICAgICB9KSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAubGVhdmUudG9vbGJhcilcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogLTEgKiBzd2lwZVJhdGlvIC8vIDEgLT4gMFxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyQ2VudGVyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgkeygxICsgc3dpcGVSYXRpbykgKiAxMjV9JSwgMCwgMClgXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmxlYXZlLmJhY2tCdXR0b25MYWJlbClcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogLTEgKiBzd2lwZVJhdGlvLCAvLyAxIC0+IDBcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5kZWx0YS50aXRsZSAqICgxICsgc3dpcGVSYXRpbyl9cHgsIDAsIDApYFxuICAgICAgICAgIH0pLFxuXG5cbiAgICAgICAgLyogT3RoZXIgKi9cblxuICAgICAgICBhbmltaXQodGhpcy5zd2lwZVNoYWRvdylcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogLTEgKiBzd2lwZVJhdGlvIC8vIDEgLT4gMFxuICAgICAgICAgIH0pXG4gICAgICApO1xuXG5cbiAgICB9IGVsc2Uge1xuICAgICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgICAgYW5pbWl0KGxlYXZlUGFnZSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoJHtkaXN0YW5jZX1weCwgMCwgMClgXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KGVudGVyUGFnZSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoJHtzd2lwZVJhdGlvICogMjV9JSwgMCwgMClgLFxuICAgICAgICAgICAgb3BhY2l0eTogMSArIHN3aXBlUmF0aW8gKiAxMCAvIDEwMCAvLyAwLjkgLT4gMVxuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLnN3aXBlU2hhZG93KVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAtMSAqIHN3aXBlUmF0aW8gLy8gMSAtPiAwXG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmVzdG9yZShlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5pc0RyYWdTdGFydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNob3VsZEFuaW1hdGVUb29sYmFyKSB7XG5cbiAgICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgICAgLyogRW50ZXIgcGFnZSAqL1xuXG4gICAgICAgIGFuaW1pdChbdGhpcy5kZWNvbXAuZW50ZXIuY29udGVudCwgdGhpcy5kZWNvbXAuZW50ZXIuYm90dG9tVG9vbGJhciwgdGhpcy5kZWNvbXAuZW50ZXIuYmFja2dyb3VuZF0pXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC0yNSUsIDAsIDApJyxcbiAgICAgICAgICAgIG9wYWNpdHk6IDAuOVxuICAgICAgICAgIH0sIHRoaXMub3B0UmVzdG9yZSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLnRvb2xiYXJDZW50ZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKC0ke3RoaXMuZGVsdGEudGl0bGV9cHgsIDAsIDApYCxcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGBvcGFjaXR5ICR7dGhpcy5kdXJhdGlvblJlc3RvcmV9cyBsaW5lYXIsIHRyYW5zZm9ybSAke3RoaXMuZHVyYXRpb25SZXN0b3JlfXMgJHt0aGlzLnRpbWluZ1N3aXBlfWAsXG4gICAgICAgICAgICBvcGFjaXR5OiAwXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLmJhY2tCdXR0b25MYWJlbClcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoLSR7dGhpcy5kZWx0YS5sYWJlbH1weCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAuZW50ZXIub3RoZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDBcbiAgICAgICAgICB9LCB0aGlzLm9wdFJlc3RvcmUpLFxuXG4gICAgICAgIC8qIExlYXZlIHBhZ2UgKi9cblxuICAgICAgICBhbmltaXQoW3RoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQsIHRoaXMuZGVjb21wLmxlYXZlLmJvdHRvbVRvb2xiYXIsIHRoaXMuZGVjb21wLmxlYXZlLmJhY2tncm91bmQsIHRoaXMuc3dpcGVTaGFkb3ddKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAwLCAwKWBcbiAgICAgICAgICB9LCB0aGlzLm9wdFJlc3RvcmUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAubGVhdmUudG9vbGJhckNlbnRlcilcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQodGhpcy5kZWNvbXAubGVhdmUuYmFja0J1dHRvbkxhYmVsKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgMCwgMClgLFxuICAgICAgICAgICAgdHJhbnNpdGlvbjogYG9wYWNpdHkgJHt0aGlzLmR1cmF0aW9uUmVzdG9yZX1zIGxpbmVhciwgdHJhbnNmb3JtICR7dGhpcy5kdXJhdGlvblJlc3RvcmV9cyAke3RoaXMudGltaW5nU3dpcGV9YFxuICAgICAgICAgIH0pLFxuXG5cbiAgICAgICAgLyogT3RoZXIgKi9cblxuICAgICAgICBhbmltaXQodGhpcy5zd2lwZVNoYWRvdylcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogMFxuICAgICAgICAgIH0sIHRoaXMub3B0UmVzdG9yZSlcbiAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9yZXNldCh0aGlzLnRhcmdldC5lbnRlciwgdGhpcy50YXJnZXQubGVhdmUpO1xuICAgICAgICAgICAgZW50ZXJQYWdlLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuXG5cbiAgICB9IGVsc2Uge1xuICAgICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgICBhbmltaXQoZW50ZXJQYWdlKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKC0yNSUsIDAsIDApJyxcbiAgICAgICAgICBvcGFjaXR5OiAwLjlcbiAgICAgICAgfSwgdGhpcy5vcHRSZXN0b3JlKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJ1xuICAgICAgICB9LCB0aGlzLm9wdFJlc3RvcmUpXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLl9yZXNldChlbnRlclBhZ2UsIGxlYXZlUGFnZSk7XG4gICAgICAgICAgZW50ZXJQYWdlLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHBvcFN3aXBlKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmlzRHJhZ1N0YXJ0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2hvdWxkQW5pbWF0ZVRvb2xiYXIpIHtcblxuICAgICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgICAvKiBFbnRlciBwYWdlICovXG5cbiAgICAgICAgYW5pbWl0KFt0aGlzLmRlY29tcC5lbnRlci5jb250ZW50LCB0aGlzLmRlY29tcC5lbnRlci5ib3R0b21Ub29sYmFyLCB0aGlzLmRlY29tcC5lbnRlci5iYWNrZ3JvdW5kXSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLFxuICAgICAgICAgICAgb3BhY2l0eTogMVxuICAgICAgICAgIH0sIHRoaXMub3B0U3dpcGUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5lbnRlci50b29sYmFyQ2VudGVyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAwLCAwKWAsXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiBgb3BhY2l0eSAke3RoaXMuZHVyYXRpb25Td2lwZX1zIGxpbmVhciwgdHJhbnNmb3JtICR7dGhpcy5kdXJhdGlvblN3aXBlfXMgJHt0aGlzLnRpbWluZ1N3aXBlfWAsXG4gICAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLmJhY2tCdXR0b25MYWJlbClcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmVudGVyLm90aGVyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAxXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSksXG5cbiAgICAgICAgLyogTGVhdmUgcGFnZSAqL1xuXG4gICAgICAgIGFuaW1pdChbdGhpcy5kZWNvbXAubGVhdmUuY29udGVudCwgdGhpcy5kZWNvbXAubGVhdmUuYm90dG9tVG9vbGJhciwgdGhpcy5kZWNvbXAubGVhdmUuYmFja2dyb3VuZF0pXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDEwMCUsIDAsIDApYFxuICAgICAgICAgIH0sIHRoaXMub3B0U3dpcGUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS50b29sYmFyKVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICBvcGFjaXR5OiAwXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuZGVjb21wLmxlYXZlLnRvb2xiYXJDZW50ZXIpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDEyNSUsIDAsIDApYFxuICAgICAgICAgIH0sIHRoaXMub3B0U3dpcGUpLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLmRlY29tcC5sZWF2ZS5iYWNrQnV0dG9uTGFiZWwpXG4gICAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICAgIG9wYWNpdHk6IDAsXG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMuZGVsdGEudGl0bGV9cHgsIDAsIDApYCxcbiAgICAgICAgICAgIHRyYW5zaXRpb246IGBvcGFjaXR5ICR7dGhpcy5kdXJhdGlvblN3aXBlfXMgbGluZWFyLCB0cmFuc2Zvcm0gJHt0aGlzLmR1cmF0aW9uU3dpcGV9cyAke3RoaXMudGltaW5nU3dpcGV9YFxuICAgICAgICAgIH0pLFxuXG5cbiAgICAgICAgLyogT3RoZXIgKi9cblxuICAgICAgICBhbmltaXQodGhpcy5zd2lwZVNoYWRvdylcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5tYXhXaWR0aH1weCwgMCwgMClgXG4gICAgICAgICAgfSwgdGhpcy5vcHRTd2lwZSlcbiAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9yZXNldCh0aGlzLnRhcmdldC5lbnRlciwgdGhpcy50YXJnZXQubGVhdmUpO1xuICAgICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgIGFuaW1pdChlbnRlclBhZ2UpXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgMCwgMCknLFxuICAgICAgICAgIG9wYWNpdHk6IDEuMFxuICAgICAgICB9LCB0aGlzLm9wdFN3aXBlKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDEwMCUsIDAsIDApJ1xuICAgICAgICB9LCB0aGlzLm9wdFN3aXBlKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgdGhpcy5fcmVzZXQoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UpO1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfc2F2ZVN0eWxlKC4uLmFyZ3MpIHtcbiAgICB0aGlzLl9zYXZlZFN0eWxlID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBzYXZlID0gZWwgPT4gdGhpcy5fc2F2ZWRTdHlsZS5zZXQoZWwsIGVsLmdldEF0dHJpYnV0ZSgnc3R5bGUnKSk7XG4gICAgYXJncy5mb3JFYWNoKHNhdmUpO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5kZWNvbXApLmZvckVhY2gocCA9PiB7XG4gICAgICBPYmplY3Qua2V5cyh0aGlzLmRlY29tcFtwXSkuZm9yRWFjaChrID0+IHtcbiAgICAgICAgKHRoaXMuZGVjb21wW3BdW2tdIGluc3RhbmNlb2YgQXJyYXkgPyB0aGlzLmRlY29tcFtwXVtrXSA6IFt0aGlzLmRlY29tcFtwXVtrXV0pLmZvckVhY2goc2F2ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIF9yZXN0b3JlU3R5bGUoLi4uYXJncykge1xuICAgIGNvbnN0IHJlc3RvcmUgPSBlbCA9PiB7XG4gICAgICB0aGlzLl9zYXZlZFN0eWxlLmdldChlbCkgPT09IG51bGwgPyBlbC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJykgOiBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgdGhpcy5fc2F2ZWRTdHlsZS5nZXQoZWwpKVxuICAgICAgdGhpcy5fc2F2ZWRTdHlsZS5kZWxldGUoZWwpXG4gICAgfTtcbiAgICBhcmdzLmZvckVhY2gocmVzdG9yZSk7XG5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmRlY29tcCkuZm9yRWFjaChwID0+IHtcbiAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGVjb21wW3BdKS5mb3JFYWNoKGsgPT4ge1xuICAgICAgICAodGhpcy5kZWNvbXBbcF1ba10gaW5zdGFuY2VvZiBBcnJheSA/IHRoaXMuZGVjb21wW3BdW2tdIDogW3RoaXMuZGVjb21wW3BdW2tdXSkuZm9yRWFjaChyZXN0b3JlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3Jlc2V0KC4uLmFyZ3MpIHtcbiAgICB0aGlzLmlzU3dpcGluZyA9IGZhbHNlO1xuICAgIHRoaXMuX3NhdmVkU3R5bGUgJiYgdGhpcy5fcmVzdG9yZVN0eWxlKC4uLmFyZ3MpO1xuICAgIHRoaXMudW5ibG9jayAmJiB0aGlzLnVuYmxvY2soKTtcbiAgICB0aGlzLnN3aXBlU2hhZG93LnJlbW92ZSgpO1xuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgdGhpcy5vdmVyZmxvd0VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnb3ZlcmZsb3ctdmlzaWJsZScpO1xuICAgIHRoaXMuZGVjb21wLmxlYXZlLmNvbnRlbnQuY2xhc3NMaXN0LnJlbW92ZSgnY29udGVudC1zd2lwaW5nJyk7XG4gICAgdGhpcy5kZWNvbXAgPSB0aGlzLnRhcmdldCA9IHRoaXMub3ZlcmZsb3dFbGVtZW50ID0gdGhpcy5fc2F2ZWRTdHlsZSA9IG51bGw7XG4gICAgdGhpcy5pc0RyYWdTdGFydCA9IHRydWU7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBJT1NTd2lwZU5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vaW9zLXN3aXBlLWFuaW1hdG9yJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuY29uc3QgdHJhbnNsYXRlM2QgPSAoeCA9IDAsIHkgPSAwLCB6ID0gMCkgPT4gYHRyYW5zbGF0ZTNkKCR7eH0sICR7eX0sICR7en0pYDtcblxuLyoqXG4gKiBTbGlkZSBhbmltYXRvciBmb3IgbmF2aWdhdG9yIHRyYW5zaXRpb24gbGlrZSBpT1MncyBzY3JlZW4gc2xpZGUgdHJhbnNpdGlvbi5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIElPU1N3aXBlTmF2aWdhdG9yQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHsgdGltaW5nID0gJ2N1YmljLWJlemllcigwLjMsIC40LCAwLCAuOSknLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40LCAuLi5yZXN0IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24sIC4uLnJlc3QgfSk7XG5cbiAgICB0aGlzLmJhY2tncm91bmRNYXNrID0gdXRpbC5jcmVhdGVFbGVtZW50KFxuICAgICAgYDxkaXYgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHdpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCU7YCArXG4gICAgICAgIGBiYWNrZ3JvdW5kLWNvbG9yOiBibGFjazsgei1pbmRleDogMlwiPjwvZGl2PmBcbiAgICApO1xuICB9XG5cbiAgX2RlY29tcG9zZShwYWdlKSB7XG4gICAgY29uc3QgdG9vbGJhciA9IHBhZ2UuX2dldFRvb2xiYXJFbGVtZW50KCk7XG4gICAgY29uc3QgbGVmdCA9IHRvb2xiYXIuX2dldFRvb2xiYXJMZWZ0SXRlbXNFbGVtZW50KCk7XG4gICAgY29uc3QgcmlnaHQgPSB0b29sYmFyLl9nZXRUb29sYmFyUmlnaHRJdGVtc0VsZW1lbnQoKTtcblxuICAgIGNvbnN0IGV4Y2x1ZGVCYWNrQnV0dG9uID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChlbGVtZW50c1tpXS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSAnb25zLWJhY2stYnV0dG9uJykge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGVsZW1lbnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBjb25zdCBvdGhlciA9IFtdXG4gICAgICAuY29uY2F0KGxlZnQuY2hpbGRyZW4ubGVuZ3RoID09PSAwID8gbGVmdCA6IGV4Y2x1ZGVCYWNrQnV0dG9uKGxlZnQuY2hpbGRyZW4pKVxuICAgICAgLmNvbmNhdChyaWdodC5jaGlsZHJlbi5sZW5ndGggPT09IDAgPyByaWdodCA6IGV4Y2x1ZGVCYWNrQnV0dG9uKHJpZ2h0LmNoaWxkcmVuKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG9vbGJhckNlbnRlcjogdG9vbGJhci5fZ2V0VG9vbGJhckNlbnRlckl0ZW1zRWxlbWVudCgpLFxuICAgICAgYmFja0J1dHRvbkljb246IHRvb2xiYXIuX2dldFRvb2xiYXJCYWNrQnV0dG9uSWNvbkVsZW1lbnQoKSxcbiAgICAgIGJhY2tCdXR0b25MYWJlbDogdG9vbGJhci5fZ2V0VG9vbGJhckJhY2tCdXR0b25MYWJlbEVsZW1lbnQoKSxcbiAgICAgIG90aGVyOiBvdGhlcixcbiAgICAgIGNvbnRlbnQ6IHBhZ2UuX2dldENvbnRlbnRFbGVtZW50KCksXG4gICAgICBiYWNrZ3JvdW5kOiBwYWdlLl9nZXRCYWNrZ3JvdW5kRWxlbWVudCgpLFxuICAgICAgdG9vbGJhcjogdG9vbGJhcixcbiAgICAgIGJvdHRvbVRvb2xiYXI6IHBhZ2UuX2dldEJvdHRvbVRvb2xiYXJFbGVtZW50KClcbiAgICB9O1xuICB9XG5cbiAgX3Nob3VsZEFuaW1hdGVUb29sYmFyKGVudGVyUGFnZSwgbGVhdmVQYWdlKSB7XG4gICAgY29uc3QgdG9vbGJhcnMgPSBlbnRlclBhZ2UuX2NhbkFuaW1hdGVUb29sYmFyKCkgJiYgbGVhdmVQYWdlLl9jYW5BbmltYXRlVG9vbGJhcigpO1xuXG4gICAgY29uc3QgZW50ZXJUb29sYmFyID0gZW50ZXJQYWdlLl9nZXRUb29sYmFyRWxlbWVudCgpO1xuICAgIGNvbnN0IGxlYXZlVG9vbGJhciA9IGxlYXZlUGFnZS5fZ2V0VG9vbGJhckVsZW1lbnQoKTtcblxuICAgIGNvbnN0IGlzU3RhdGljID0gZW50ZXJUb29sYmFyLmhhc0F0dHJpYnV0ZSgnc3RhdGljJykgfHwgbGVhdmVUb29sYmFyLmhhc0F0dHJpYnV0ZSgnc3RhdGljJyk7XG4gICAgY29uc3QgaXNNYXRlcmlhbCA9IHV0aWwuaGFzTW9kaWZpZXIoZW50ZXJUb29sYmFyLCAnbWF0ZXJpYWwnKSB8fCB1dGlsLmhhc01vZGlmaWVyKGxlYXZlVG9vbGJhciwgJ21hdGVyaWFsJyk7XG4gICAgY29uc3QgaXNUcmFuc3BhcmVudCA9IHV0aWwuaGFzTW9kaWZpZXIoZW50ZXJUb29sYmFyLCAndHJhbnNwYXJlbnQnKSB8fCB1dGlsLmhhc01vZGlmaWVyKGxlYXZlVG9vbGJhciwgJ3RyYW5zcGFyZW50Jyk7XG5cbiAgICByZXR1cm4gdG9vbGJhcnMgJiYgIWlzU3RhdGljICYmICFpc01hdGVyaWFsICYmICFpc1RyYW5zcGFyZW50O1xuICB9XG5cbiAgX2NhbGN1bGF0ZURlbHRhKGVsZW1lbnQsIGRlY29tcG9zaXRpb24pIHtcbiAgICBsZXQgdGl0bGUsIGxhYmVsO1xuXG4gICAgY29uc3QgcGFnZVJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmIChkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25MYWJlbC5jbGFzc0xpc3QuY29udGFpbnMoJ2JhY2stYnV0dG9uX19sYWJlbCcpKSB7XG4gICAgICBjb25zdCBsYWJlbFJlY3QgPSBkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25MYWJlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHRpdGxlID0gTWF0aC5yb3VuZChwYWdlUmVjdC53aWR0aCAvIDIgLSBsYWJlbFJlY3Qud2lkdGggLyAyIC0gbGFiZWxSZWN0LmxlZnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aXRsZSA9IE1hdGgucm91bmQoKHBhZ2VSZWN0LndpZHRoIC8gMikgKiAwLjYpO1xuICAgIH1cblxuICAgIGlmIChkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25JY29uLmNsYXNzTGlzdC5jb250YWlucygnYmFjay1idXR0b25fX2ljb24nKSkge1xuICAgICAgbGFiZWwgPSBkZWNvbXBvc2l0aW9uLmJhY2tCdXR0b25JY29uLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0IC0gMjtcbiAgICB9XG5cbiAgICByZXR1cm4ge3RpdGxlLCBsYWJlbH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZW50ZXJQYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBsZWF2ZVBhZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHB1c2goZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5iYWNrZ3JvdW5kTWFzay5yZW1vdmUoKTtcbiAgICBsZWF2ZVBhZ2UucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5iYWNrZ3JvdW5kTWFzaywgbGVhdmVQYWdlKTtcblxuICAgIGNvbnN0IHVuYmxvY2sgPSBzdXBlci5ibG9jayhlbnRlclBhZ2UpO1xuXG4gICAgY29udGVudFJlYWR5KGVudGVyUGFnZSwgKCkgPT4ge1xuICAgICAgY29uc3QgZW50ZXJQYWdlVGFyZ2V0ID0gdXRpbC5maW5kVG9vbGJhclBhZ2UoZW50ZXJQYWdlKSB8fCBlbnRlclBhZ2U7XG4gICAgICBjb25zdCBsZWF2ZVBhZ2VUYXJnZXQgPSB1dGlsLmZpbmRUb29sYmFyUGFnZShsZWF2ZVBhZ2UpIHx8IGxlYXZlUGFnZTtcbiAgICAgIGNvbnN0IGVudGVyUGFnZURlY29tcG9zaXRpb24gPSB0aGlzLl9kZWNvbXBvc2UoZW50ZXJQYWdlVGFyZ2V0KTtcbiAgICAgIGNvbnN0IGxlYXZlUGFnZURlY29tcG9zaXRpb24gPSB0aGlzLl9kZWNvbXBvc2UobGVhdmVQYWdlVGFyZ2V0KTtcblxuICAgICAgY29uc3QgZGVsdGEgPSB0aGlzLl9jYWxjdWxhdGVEZWx0YShsZWF2ZVBhZ2UsIGVudGVyUGFnZURlY29tcG9zaXRpb24pO1xuXG4gICAgICBjb25zdCBzaG91bGRBbmltYXRlVG9vbGJhciA9IHRoaXMuX3Nob3VsZEFuaW1hdGVUb29sYmFyKGVudGVyUGFnZVRhcmdldCwgbGVhdmVQYWdlVGFyZ2V0KTtcblxuICAgICAgaWYgKHNob3VsZEFuaW1hdGVUb29sYmFyKSB7XG5cbiAgICAgICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgICAgIGFuaW1pdChbZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5jb250ZW50LCBlbnRlclBhZ2VEZWNvbXBvc2l0aW9uLmJvdHRvbVRvb2xiYXIsIGVudGVyUGFnZURlY29tcG9zaXRpb24uYmFja2dyb3VuZF0sIHRoaXMuZGVmKVxuICAgICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgnMTAwJScpIH0sXG4gICAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH1cbiAgICAgICAgICAgICksXG5cbiAgICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSksXG5cbiAgICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyQ2VudGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEyNSUnKSwgb3BhY2l0eTogMSB9LFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9XG4gICAgICAgICAgICApLFxuXG4gICAgICAgICAgYW5pbWl0KGVudGVyUGFnZURlY29tcG9zaXRpb24uYmFja0J1dHRvbkxhYmVsLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoYCR7ZGVsdGEudGl0bGV9cHhgKSwgb3BhY2l0eTogMCB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYG9wYWNpdHkgJHt0aGlzLmR1cmF0aW9ufXMgbGluZWFyLCB0cmFuc2Zvcm0gJHt0aGlzLmR1cmF0aW9ufXMgJHt0aGlzLnRpbWluZ31gXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICksXG5cbiAgICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5vdGhlciwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgICAgeyBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgICAgIHsgY3NzOiB7IG9wYWNpdHk6IDEgfSwgdGltaW5nOiAnbGluZWFyJyB9XG4gICAgICAgICAgICApLFxuXG4gICAgICAgICAgYW5pbWl0KFtsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uLmNvbnRlbnQsIGxlYXZlUGFnZURlY29tcG9zaXRpb24uYm90dG9tVG9vbGJhciwgbGVhdmVQYWdlRGVjb21wb3NpdGlvbi5iYWNrZ3JvdW5kXSwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCksIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCctMjUlJyksIG9wYWNpdHk6IDAuOSB9XG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSksXG5cbiAgICAgICAgICBhbmltaXQobGVhdmVQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyQ2VudGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZChgLSR7ZGVsdGEudGl0bGV9cHhgKSxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICAgIHRyYW5zaXRpb246IGBvcGFjaXR5ICR7dGhpcy5kdXJhdGlvbn1zIGxpbmVhciwgdHJhbnNmb3JtICR7dGhpcy5kdXJhdGlvbn1zICR7dGhpcy50aW1pbmd9YFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApLFxuXG4gICAgICAgICAgYW5pbWl0KGxlYXZlUGFnZURlY29tcG9zaXRpb24uYmFja0J1dHRvbkxhYmVsLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9LFxuICAgICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoYC0ke2RlbHRhLmxhYmVsfXB4YCksIG9wYWNpdHk6IDAgfVxuICAgICAgICAgICAgKSxcblxuICAgICAgICAgIGFuaW1pdChsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uLm90aGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAgIC5kZWZhdWx0KCB7IG9wYWNpdHk6IDEgfSwgeyBjc3M6IHsgb3BhY2l0eTogMCB9LCB0aW1pbmc6ICdsaW5lYXInIH0pXG5cbiAgICAgICAgKTtcblxuICAgICAgfSBlbHNlIHtcblxuICAgICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdCggeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCcxMDAlJyksIH0sIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0pLFxuXG4gICAgICAgICAgYW5pbWl0KGxlYXZlUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgICAgICAuZGVmYXVsdCggeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCksIG9wYWNpdHk6IDEgfSwgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCctMjUlJyksIG9wYWNpdHk6IC45IH0pXG4gICAgICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcblxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcG9wKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLmlzU3dpcGluZykge1xuICAgICAgcmV0dXJuIHRoaXMucG9wU3dpcGUoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGVudGVyUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBlbnRlclBhZ2UpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBjb25zdCBlbnRlclBhZ2VUYXJnZXQgPSB1dGlsLmZpbmRUb29sYmFyUGFnZShlbnRlclBhZ2UpIHx8IGVudGVyUGFnZTtcbiAgICBjb25zdCBsZWF2ZVBhZ2VUYXJnZXQgPSB1dGlsLmZpbmRUb29sYmFyUGFnZShsZWF2ZVBhZ2UpIHx8IGxlYXZlUGFnZTtcbiAgICBjb25zdCBlbnRlclBhZ2VEZWNvbXBvc2l0aW9uID0gdGhpcy5fZGVjb21wb3NlKGVudGVyUGFnZVRhcmdldCk7XG4gICAgY29uc3QgbGVhdmVQYWdlRGVjb21wb3NpdGlvbiA9IHRoaXMuX2RlY29tcG9zZShsZWF2ZVBhZ2VUYXJnZXQpO1xuXG4gICAgY29uc3QgZGVsdGEgPSB0aGlzLl9jYWxjdWxhdGVEZWx0YShsZWF2ZVBhZ2UsIGxlYXZlUGFnZURlY29tcG9zaXRpb24pO1xuXG4gICAgY29uc3Qgc2hvdWxkQW5pbWF0ZVRvb2xiYXIgPSB0aGlzLl9zaG91bGRBbmltYXRlVG9vbGJhcihlbnRlclBhZ2VUYXJnZXQsIGxlYXZlUGFnZVRhcmdldCk7XG5cbiAgICBpZiAoc2hvdWxkQW5pbWF0ZVRvb2xiYXIpIHtcbiAgICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgICAgYW5pbWl0KFtlbnRlclBhZ2VEZWNvbXBvc2l0aW9uLmNvbnRlbnQsIGVudGVyUGFnZURlY29tcG9zaXRpb24uYm90dG9tVG9vbGJhciwgZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5iYWNrZ3JvdW5kXSwgdGhpcy5kZWYpXG4gICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJy0yNSUnKSwgb3BhY2l0eTogLjkgfSxcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpLCBvcGFjaXR5OiAxIH1cbiAgICAgICAgICApLFxuXG4gICAgICAgIGFuaW1pdChlbnRlclBhZ2VEZWNvbXBvc2l0aW9uLnRvb2xiYXJDZW50ZXIsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKGAtJHtkZWx0YS50aXRsZX1weGApLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSxcbiAgICAgICAgICAgICAgb3BhY2l0eTogMSxcbiAgICAgICAgICAgICAgdHJhbnNpdGlvbjogYG9wYWNpdHkgJHt0aGlzLmR1cmF0aW9ufXMgbGluZWFyLCB0cmFuc2Zvcm0gJHt0aGlzLmR1cmF0aW9ufXMgJHt0aGlzLnRpbWluZ31gXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5iYWNrQnV0dG9uTGFiZWwsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKGAtJHtkZWx0YS5sYWJlbH1weGApIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQoZW50ZXJQYWdlRGVjb21wb3NpdGlvbi5vdGhlciwgdGhpcy5kZWYpXG4gICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICB7IG9wYWNpdHk6IDAgfSxcbiAgICAgICAgICAgIHsgY3NzOiB7IG9wYWNpdHk6IDEgfSwgdGltaW5nOiAnbGluZWFyJyB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQoW2xlYXZlUGFnZURlY29tcG9zaXRpb24uY29udGVudCwgbGVhdmVQYWdlRGVjb21wb3NpdGlvbi5ib3R0b21Ub29sYmFyLCBsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uLmJhY2tncm91bmRdLCB0aGlzLmRlZilcbiAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEwMCUnKSB9XG4gICAgICAgICAgKVxuICAgICAgICAgIC53YWl0KDApXG4gICAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgICAgdGhpcy5iYWNrZ3JvdW5kTWFzay5yZW1vdmUoKTtcbiAgICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgYW5pbWl0KGxlYXZlUGFnZURlY29tcG9zaXRpb24udG9vbGJhciwgdGhpcy5kZWYpXG4gICAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgICB7IG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICAgIHsgb3BhY2l0eTogMCB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlRGVjb21wb3NpdGlvbi50b29sYmFyQ2VudGVyLCB0aGlzLmRlZilcbiAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEyNSUnKSB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlRGVjb21wb3NpdGlvbi5iYWNrQnV0dG9uTGFiZWwsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCksIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZChgJHtkZWx0YS50aXRsZX1weGApLFxuICAgICAgICAgICAgICBvcGFjaXR5OiAwLFxuICAgICAgICAgICAgICB0cmFuc2l0aW9uOiBgb3BhY2l0eSAke3RoaXMuZHVyYXRpb259cyBsaW5lYXIsIHRyYW5zZm9ybSAke3RoaXMuZHVyYXRpb259cyAke3RoaXMudGltaW5nfWBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICAgIGFuaW1pdChlbnRlclBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgICAgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZTNkKCctMjUlJyksIG9wYWNpdHk6IC45IH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoKSwgb3BhY2l0eTogMSB9XG4gICAgICAgICAgKSxcblxuICAgICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICAgIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGUzZCgpIH0sXG4gICAgICAgICAgICB7IHRyYW5zZm9ybTogdHJhbnNsYXRlM2QoJzEwMCUnKSB9XG4gICAgICAgICAgKVxuICAgICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcblxuLyoqXG4gKiBMaWZ0IHNjcmVlbiB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJT1NMaWZ0TmF2aWdhdG9yQW5pbWF0b3IgZXh0ZW5kcyBOYXZpZ2F0b3JBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40fSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoXG4gICAgICAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsnICtcbiAgICAgICAgJ2JhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudChibGFjaywgd2hpdGUpO1wiPjwvZGl2PidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcHVzaChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGxlYXZlUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBsZWF2ZVBhZ2UpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZW50ZXJQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAxMDAlLCAwKScgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJyB9XG4gICAgICAgICksXG5cbiAgICAgIGFuaW1pdChsZWF2ZVBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJywgb3BhY2l0eTogMSB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgLTEwJSwgMCknLCBvcGFjaXR5OiAuOSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgdW5ibG9jaygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGVudGVyUGFnZVxuICAgKiBAcGFyYW0ge09iamVjdH0gbGVhdmVQYWdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5iYWNrZ3JvdW5kTWFzay5yZW1vdmUoKTtcbiAgICBlbnRlclBhZ2UucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5iYWNrZ3JvdW5kTWFzaywgZW50ZXJQYWdlKTtcblxuICAgIGNvbnN0IHVuYmxvY2sgPSBzdXBlci5ibG9jayhlbnRlclBhZ2UpO1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgLTQzcHgsIDApJywgb3BhY2l0eTogLjkgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNEKDAsIDAsIDApJywgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgdW5ibG9jaygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KGxlYXZlUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgMCwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAxMDAlLCAwKScgfVxuICAgICAgICApXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcblxuY29uc3QgdHJhbnNmb3JtID0gJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJztcblxuLyoqXG4gKiBGYWRlLWluIHNjcmVlbiB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJT1NGYWRlTmF2aWdhdG9yQW5pbWF0b3IgZXh0ZW5kcyBOYXZpZ2F0b3JBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC40fSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZW50ZXJQYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBsZWF2ZVBhZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHB1c2goZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQoZW50ZXJQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm0sIG9wYWNpdHk6IDAgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybSwgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm0sIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybSwgb3BhY2l0eTogMCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuXG4vKipcbiAqIFNsaWRlIGFuaW1hdG9yIGZvciBuYXZpZ2F0b3IgdHJhbnNpdGlvbi5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTURTbGlkZU5hdmlnYXRvckFuaW1hdG9yIGV4dGVuZHMgTmF2aWdhdG9yQW5pbWF0b3Ige1xuXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuM30gPSB7fSkge1xuICAgIHN1cGVyKHt0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbn0pO1xuXG4gICAgdGhpcy5ibGFja01hc2tPcGFjaXR5ID0gMC40O1xuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoXG4gICAgICAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgei1pbmRleDogMjsnICtcbiAgICAgICAgJ2JhY2tncm91bmQtY29sb3I6IGJsYWNrOyBvcGFjaXR5OiAwO1wiPjwvZGl2PidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcHVzaChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGxlYXZlUGFnZS5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBsZWF2ZVBhZ2UubmV4dFNpYmxpbmcpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQodGhpcy5iYWNrZ3JvdW5kTWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyBvcGFjaXR5OiB0aGlzLmJsYWNrTWFza09wYWNpdHkgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdChlbnRlclBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDEwMCUsIDAsIDApJyB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH1cbiAgICAgICAgKSxcblxuICAgICAgYW5pbWl0KGxlYXZlUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgtNDUlLCAwLCAwKScgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZW50ZXJQYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBsZWF2ZVBhZ2VcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIHBvcChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGVudGVyUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBlbnRlclBhZ2UubmV4dFNpYmxpbmcpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQodGhpcy5iYWNrZ3JvdW5kTWFzaywgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiB0aGlzLmJsYWNrTWFza09wYWNpdHkgfSxcbiAgICAgICAgICB7IG9wYWNpdHk6IDAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdChlbnRlclBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKC00NSUsIDAsIDApJywgb3BhY2l0eTogLjkgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9XG4gICAgICAgICksXG5cbiAgICAgIGFuaW1pdChsZWF2ZVBhZ2UsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMTAwJSwgMCwgMCknIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgdW5ibG9jaygpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL2FuaW1hdG9yJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5cbi8qKlxuICogTGlmdCBzY3JlZW4gdHJhbnNpdGlvbi5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IgZXh0ZW5kcyBOYXZpZ2F0b3JBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknLCBkZWxheSA9IDAuMDUsIGR1cmF0aW9uID0gMC40fSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcblxuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sgPSB1dGlsLmNyZWF0ZUVsZW1lbnQoXG4gICAgICAnPGRpdiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsnICtcbiAgICAgICAgJ2JhY2tncm91bmQtY29sb3I6IGJsYWNrO1wiPjwvZGl2PidcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcHVzaChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgIGxlYXZlUGFnZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmJhY2tncm91bmRNYXNrLCBsZWF2ZVBhZ2UpO1xuXG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBjb25zdCBtYXNrQ2xlYXIgPSBhbmltaXQodGhpcy5iYWNrZ3JvdW5kTWFzaylcbiAgICAgIC53YWl0KHRoaXMuZGVsYXkgKyB0aGlzLmR1cmF0aW9uKVxuICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICB0aGlzLmJhY2tncm91bmRNYXNrLnJlbW92ZSgpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIG1hc2tDbGVhcixcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMTAwJSwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScgfVxuICAgICAgICApLFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogLjQgfSlcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcG9wKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgZW50ZXJQYWdlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMuYmFja2dyb3VuZE1hc2ssIGVudGVyUGFnZSk7XG5cbiAgICBjb25zdCB1bmJsb2NrID0gc3VwZXIuYmxvY2soZW50ZXJQYWdlKTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG5cbiAgICAgIGFuaW1pdCh0aGlzLmJhY2tncm91bmRNYXNrKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5ICsgdGhpcy5kdXJhdGlvbilcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHRoaXMuYmFja2dyb3VuZE1hc2sucmVtb3ZlKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogLjQgfSwgeyBvcGFjaXR5OiAxIH0pXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKScgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDEwMCUsIDApJyB9XG4gICAgICAgIClcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuXG4vKipcbiAqIEZhZGUtaW4gKyBMaWZ0IHNjcmVlbiB0cmFuc2l0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNREZhZGVOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIE5hdmlnYXRvckFuaW1hdG9yIHtcblxuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2N1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSknLCB0aW1pbmdQb3AgPSAnY3ViaWMtYmV6aWVyKDAuNCwgMCwgMSwgMSknLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4yfSA9IHt9KSB7XG4gICAgc3VwZXIoe3RpbWluZywgZGVsYXksIGR1cmF0aW9ufSk7XG4gICAgdGhpcy50aW1pbmdQb3AgPSB0aW1pbmdQb3A7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGVudGVyUGFnZVxuICAgKiBAcGFyYW0ge09iamVjdH0gbGVhdmVQYWdlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBwdXNoKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVuYmxvY2sgPSBzdXBlci5ibG9jayhlbnRlclBhZ2UpO1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcblxuICAgICAgYW5pbWl0KGVudGVyUGFnZSwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM0QoMCwgNDJweCwgMCknLCBvcGFjaXR5OiAwIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAwLCAwKScsIG9wYWNpdHk6IDEgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB1bmJsb2NrKCk7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbnRlclBhZ2VcbiAgICogQHBhcmFtIHtPYmplY3R9IGxlYXZlUGFnZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBwb3AoZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgdW5ibG9jayA9IHN1cGVyLmJsb2NrKGVudGVyUGFnZSk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuXG4gICAgICBhbmltaXQobGVhdmVQYWdlLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAwLCAwKScsIG9wYWNpdHk6IDEgfSxcbiAgICAgICAgICB7IGNzczogeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzRCgwLCAzOHB4LCAwKScsIG9wYWNpdHk6IDAgfSwgdGltaW5nOiB0aGlzLnRpbWluZ1BvcCB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIHVuYmxvY2soKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE5vbmVOYXZpZ2F0b3JBbmltYXRvciBleHRlbmRzIE5hdmlnYXRvckFuaW1hdG9yIHtcbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICB9XG4gIHB1c2goZW50ZXJQYWdlLCBsZWF2ZVBhZ2UsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHBvcChlbnRlclBhZ2UsIGxlYXZlUGFnZSwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBpbnRlcm5hbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwnO1xuaW1wb3J0IFN3aXBlUmV2ZWFsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9zd2lwZS1yZXZlYWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL2lvcy1zbGlkZS1hbmltYXRvcic7XG5pbXBvcnQgSU9TTGlmdE5hdmlnYXRvckFuaW1hdG9yIGZyb20gJy4vaW9zLWxpZnQtYW5pbWF0b3InO1xuaW1wb3J0IElPU0ZhZGVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL2lvcy1mYWRlLWFuaW1hdG9yJztcbmltcG9ydCBNRFNsaWRlTmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9tZC1zbGlkZS1hbmltYXRvcic7XG5pbXBvcnQgTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IgZnJvbSAnLi9tZC1saWZ0LWFuaW1hdG9yJztcbmltcG9ydCBNREZhZGVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL21kLWZhZGUtYW5pbWF0b3InO1xuaW1wb3J0IE5vbmVOYXZpZ2F0b3JBbmltYXRvciBmcm9tICcuL25vbmUtYW5pbWF0b3InO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uLy4uL29ucy9wbGF0Zm9ybSc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL2RldmljZS1iYWNrLWJ1dHRvbi1kaXNwYXRjaGVyJztcbmltcG9ydCB7UGFnZUxvYWRlciwgZGVmYXVsdFBhZ2VMb2FkZXIsIGluc3RhbnRQYWdlTG9hZGVyfSBmcm9tICcuLi8uLi9vbnMvcGFnZS1sb2FkZXInO1xuXG5jb25zdCBfYW5pbWF0b3JEaWN0ID0ge1xuICAnZGVmYXVsdCc6ICgpID0+IHBsYXRmb3JtLmlzQW5kcm9pZCgpID8gTURGYWRlTmF2aWdhdG9yQW5pbWF0b3IgOiBJT1NTbGlkZU5hdmlnYXRvckFuaW1hdG9yLFxuICAnc2xpZGUnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IE1EU2xpZGVOYXZpZ2F0b3JBbmltYXRvciA6IElPU1NsaWRlTmF2aWdhdG9yQW5pbWF0b3IsXG4gICdsaWZ0JzogKCkgPT4gcGxhdGZvcm0uaXNBbmRyb2lkKCkgPyBNRExpZnROYXZpZ2F0b3JBbmltYXRvciA6IElPU0xpZnROYXZpZ2F0b3JBbmltYXRvcixcbiAgJ2ZhZGUnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IE1ERmFkZU5hdmlnYXRvckFuaW1hdG9yIDogSU9TRmFkZU5hdmlnYXRvckFuaW1hdG9yLFxuICAnc2xpZGUtaW9zJzogSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvcixcbiAgJ3NsaWRlLW1kJzogTURTbGlkZU5hdmlnYXRvckFuaW1hdG9yLFxuICAnbGlmdC1pb3MnOiBJT1NMaWZ0TmF2aWdhdG9yQW5pbWF0b3IsXG4gICdsaWZ0LW1kJzogTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IsXG4gICdmYWRlLWlvcyc6IElPU0ZhZGVOYXZpZ2F0b3JBbmltYXRvcixcbiAgJ2ZhZGUtbWQnOiBNREZhZGVOYXZpZ2F0b3JBbmltYXRvcixcbiAgJ25vbmUnOiBOb25lTmF2aWdhdG9yQW5pbWF0b3Jcbn07XG5cbmNvbnN0IHJld3JpdGFibGVzID0ge1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBuYXZpZ2F0b3JTaWRlRWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcmVhZHkobmF2aWdhdG9yRWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59O1xuXG5jb25zdCB2ZXJpZnlQYWdlRWxlbWVudCA9IGVsID0+IChlbC5ub2RlTmFtZSAhPT0gJ09OUy1QQUdFJykgJiYgdXRpbC50aHJvdyggJ09ubHkgcGFnZSBlbGVtZW50cyBjYW4gYmUgY2hpbGRyZW4gb2YgbmF2aWdhdG9yJyk7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLW5hdmlnYXRvclxuICogQGNhdGVnb3J5IG5hdmlnYXRpb25cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgQSBjb21wb25lbnQgdGhhdCBwcm92aWRlcyBwYWdlIHN0YWNrIG1hbmFnZW1lbnQgYW5kIG5hdmlnYXRpb24uIFN0YWNrIG5hdmlnYXRpb24gaXMgdGhlIG1vc3QgY29tbW9uIG5hdmlnYXRpb24gcGF0dGVybiBmb3IgbW9iaWxlIGFwcHMuXG4gKlxuICogICAgIFdoZW4gYSBwYWdlIGlzIHB1c2hlZCBvbiB0b3Agb2YgdGhlIHN0YWNrIGl0IGlzIGRpc3BsYXllZCB3aXRoIGEgdHJhbnNpdGlvbiBhbmltYXRpb24uIFdoZW4gdGhlIHVzZXIgcmV0dXJucyB0byB0aGUgcHJldmlvdXMgcGFnZSB0aGUgdG9wIHBhZ2Ugd2lsbCBiZSBwb3BwZWQgZnJvbSB0aGUgdG9wIG9mIHRoZSBzdGFjayBhbmQgaGlkZGVuIHdpdGggYW4gb3Bwb3NpdGUgdHJhbnNpdGlvbiBhbmltYXRpb24uXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4geXJodHZcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9uYXZpZ2F0b3JcbiAqIEBndWlkZSBsaWZlY3ljbGUuaHRtbCNldmVudHNcbiAqICAgW2VuXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9lbl1cbiAqICAgW2phXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy10b29sYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9vbGJhcj5gIGNvbXBvbmVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSB0b29sYmFyIG9uIHRoZSB0b3Agb2YgYSBwYWdlLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLWJhY2stYnV0dG9uXG4gKiAgIFtlbl1UaGUgYDxvbnMtYmFjay1idXR0b24+YCBjb21wb25lbnQgbGV0cyB0aGUgdXNlciByZXR1cm4gdG8gdGhlIHByZXZpb3VzIHBhZ2UuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1uYXZpZ2F0b3IgaWQ9XCJuYXZpZ2F0b3JcIj5cbiAqICAgPG9ucy1wYWdlPlxuICogICAgIDxvbnMtdG9vbGJhcj5cbiAqICAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJcIj5cbiAqICAgICAgICAgVGl0bGVcbiAqICAgICAgIDwvZGl2PlxuICogICAgIDwvb25zLXRvb2xiYXI+XG4gKiAgICAgPHA+XG4gKiAgICAgICA8b25zLWJ1dHRvblxuICogICAgICAgICBvbmNsaWNrPVwiZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25hdmlnYXRvcicpLnB1c2hQYWdlKCdwYWdlLmh0bWwnKVwiPlxuICogICAgICAgICBQdXNoIHBhZ2VcbiAqICAgICAgIDwvb25zLWJ1dHRvbj5cbiAqICAgICA8L3A+XG4gKiAgIDwvb25zLXBhZ2U+XG4gKiA8L29ucy1uYXZpZ2F0b3I+XG4gKlxuICogPHRlbXBsYXRlIGlkPVwicGFnZS5odG1sXCI+XG4gKiAgIDxvbnMtcGFnZT5cbiAqICAgICA8b25zLXRvb2xiYXI+XG4gKiAgICAgICA8ZGl2IGNsYXNzPVwibGVmdFwiPlxuICogICAgICAgICA8b25zLWJhY2stYnV0dG9uPkJhY2s8L29ucy1iYWNrLWJ1dHRvbj5cbiAqICAgICAgIDwvZGl2PlxuICogICAgICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlxuICogICAgICAgICBBbm90aGVyIHBhZ2VcbiAqICAgICAgIDwvZGl2PlxuICogICAgIDwvb25zLXRvb2xiYXI+XG4gKiAgIDwvb25zLXBhZ2U+XG4gKiA8L3RlbXBsYXRlPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOYXZpZ2F0b3JFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHBhZ2VcbiAgICogQGluaXRvbmx5XG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJzdCBwYWdlIHRvIHNob3cgd2hlbiBuYXZpZ2F0b3IgaXMgaW5pdGlhbGl6ZWQuWy9lbl1cbiAgICogICBbamFd44OK44OT44Ky44O844K/44O844GM5Yid5pyf5YyW44GV44KM44Gf5pmC44Gr6KGo56S644GZ44KL44Oa44O844K444KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGVhYmxlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRW5hYmxlIGlPUyBcInN3aXBlIHRvIHBvcFwiIGZlYXR1cmUuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGUtdGFyZ2V0LXdpZHRoXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IDIwcHhcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSB3aWR0aCBvZiBzd2lwZWFibGUgYXJlYSBjYWxjdWxhdGVkIGZyb20gdGhlIGVkZ2UgKGluIHBpeGVscykuIFVzZSB0aGlzIHRvIGVuYWJsZSBzd2lwZSBvbmx5IHdoZW4gdGhlIGZpbmdlciB0b3VjaCBvbiB0aGUgc2NyZWVuIGVkZ2UuWy9lbl1cbiAgICogICBbamFd44K544Ov44Kk44OX44Gu5Yik5a6a6aCY5Z+f44KS44OU44Kv44K744Or5Y2Y5L2N44Gn5oyH5a6a44GX44G+44GZ44CC55S76Z2i44Gu56uv44GL44KJ5oyH5a6a44GX44Gf6Led6Zui44Gr6YGU44GZ44KL44Go44Oa44O844K444GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGUtdGhyZXNob2xkXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZWZhdWx0IDAuMlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IGhvdyBtdWNoIHRoZSBwYWdlIG5lZWRzIHRvIGJlIHN3aXBlZCBiZWZvcmUgcG9wcGluZy4gQSB2YWx1ZSBiZXR3ZWVuIGAwYCBhbmQgYDFgLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVxuICAgKiAgICAgQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJzbGlkZVwiYCwgYFwibGlmdFwiYCwgYFwiZmFkZVwiYCBhbmQgYFwibm9uZVwiYC5cbiAgICpcbiAgICogICAgIFRoZXNlIGFyZSBwbGF0Zm9ybSBiYXNlZCBhbmltYXRpb25zLiBGb3IgZml4ZWQgYW5pbWF0aW9ucywgYWRkIGBcIi1pb3NcImAgb3IgYFwiLW1kXCJgIHN1ZmZpeCB0byB0aGUgYW5pbWF0aW9uIG5hbWUuIEUuZy4gYFwibGlmdC1pb3NcImAsIGBcImxpZnQtbWRcImAuIERlZmF1bHRzIHZhbHVlcyBhcmUgYFwic2xpZGUtaW9zXCJgIGFuZCBgXCJmYWRlLW1kXCJgIGRlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0uXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YFsvZW5dXG4gICAqICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgIJlLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZXB1c2hcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYmVmb3JlIGEgcGFnZSBpcyBwdXNoZWQuWy9lbl1cbiAgICogICBbamFdcGFnZeOBjHB1c2jjgZXjgozjgovnm7TliY3jgavnmbrngavjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQubmF2aWdhdG9yXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmN1cnJlbnRQYWdlXG4gICAqICAgW2VuXUN1cnJlbnQgcGFnZSBvYmplY3QuWy9lbl1cbiAgICogICBbamFd54++5Zyo44GucGFnZeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1DYWxsIHRoaXMgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBwdXNoLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWRvOOBs+WHuuOBmeOBqOOAgXB1c2jlh6bnkIbjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZXBvcFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgYSBwYWdlIGlzIHBvcHBlZC5bL2VuXVxuICAgKiAgIFtqYV1wYWdl44GMcG9w44GV44KM44KL55u05YmN44Gr55m654Gr44GV44KM44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm5hdmlnYXRvclxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jdXJyZW50UGFnZVxuICAgKiAgIFtlbl1DdXJyZW50IHBhZ2Ugb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBrnBhZ2Xjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC5jYW5jZWxcbiAgICogICBbZW5dQ2FsbCB0aGlzIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgcG9wLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWRvOOBs+WHuuOBmeOBqOOAgXBhZ2Xjga5wb3DjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RwdXNoXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIGEgcGFnZSBpcyBwdXNoZWQuWy9lbl1cbiAgICogICBbamFdcGFnZeOBjHB1c2jjgZXjgozjgabjgqLjg4vjg6Hjg7zjgrfjg6fjg7PjgYzntYLkuobjgZfjgabjgYvjgonnmbrngavjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQubmF2aWdhdG9yXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmVudGVyUGFnZVxuICAgKiAgIFtlbl1PYmplY3Qgb2YgdGhlIG5leHQgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV1wdXNo44GV44KM44GfcGFnZeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5sZWF2ZVBhZ2VcbiAgICogICBbZW5dT2JqZWN0IG9mIHRoZSBwcmV2aW91cyBwYWdlLlsvZW5dXG4gICAqICAgW2phXeS7peWJjeOBrnBhZ2Xjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3Rwb3BcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgYSBwYWdlIGlzIHBvcHBlZC5bL2VuXVxuICAgKiAgIFtqYV1wYWdl44GMcG9w44GV44KM44Gm44Ki44OL44Oh44O844K344On44Oz44GM57WC44KP44Gj44Gf5b6M44Gr55m654Gr44GV44KM44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50Lm5hdmlnYXRvclxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5lbnRlclBhZ2VcbiAgICogICBbZW5dT2JqZWN0IG9mIHRoZSBuZXh0IHBhZ2UuWy9lbl1cbiAgICogICBbamFdcG9w44GV44KM44Gm6KGo56S644GV44KM44KL44Oa44O844K444Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LmxlYXZlUGFnZVxuICAgKiAgIFtlbl1PYmplY3Qgb2YgdGhlIHByZXZpb3VzIHBhZ2UuWy9lbl1cbiAgICogICBbamFdcG9w44GV44KM44Gm5raI44GI44KL44Oa44O844K444Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IGFuaW1hdG9yRmFjdG9yeSgpIHtcbiAgICByZXR1cm4gdGhpcy5fYW5pbWF0b3JGYWN0b3J5O1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgdGhpcy5fcGFnZUxvYWRlciA9IGRlZmF1bHRQYWdlTG9hZGVyO1xuICAgIHRoaXMuX3BhZ2VNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG4gICAgdGhpcy5fdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VMb2FkZXJcbiAgICogQHR5cGUge1BhZ2VMb2FkZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1QYWdlTG9hZGVyIGluc3RhbmNlLiBJdCBjYW4gYmUgb3ZlcnJpZGVuIHRvIGNoYW5nZSB0aGUgd2F5IHBhZ2VzIGFyZSBsb2FkZWQgYnkgdGhpcyBlbGVtZW50LiBVc2VmdWwgZm9yIGxpYiBkZXZlbG9wZXJzLlsvZW5dXG4gICAqICAgW2phXVBhZ2VMb2FkZXLjgqTjg7Pjgrnjgr/jg7PjgrnjgpLmoLzntI3jgZfjgabjgYTjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2VMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VMb2FkZXI7XG4gIH1cblxuICBzZXQgcGFnZUxvYWRlcihwYWdlTG9hZGVyKSB7XG4gICAgaWYgKCEocGFnZUxvYWRlciBpbnN0YW5jZW9mIFBhZ2VMb2FkZXIpKSB7XG4gICAgICB1dGlsLnRocm93UGFnZUxvYWRlcigpO1xuICAgIH1cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gcGFnZUxvYWRlcjtcbiAgfVxuXG4gIF9nZXRQYWdlVGFyZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9wYWdlIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdwYWdlJyk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VcbiAgICogQHR5cGUgeyp9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBwYWdlIHRvIGJlIGxvYWRlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24uIFRoaXMgdmFsdWUgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIHRoZSBgcGFnZWAgYXR0cmlidXRlLiBVc2VmdWwgZm9yIGxpYiBkZXZlbG9wZXJzLlsvZW5dXG4gICAqICAgW2phXeWIneacn+WMluaZguOBq+iqreOBv+i+vOOCgOODmuODvOOCuOOCkuaMh+WumuOBl+OBvuOBmeOAgmBwYWdlYOWxnuaAp+OBp+aMh+WumuOBl+OBn+WApOOCiOOCiuOCgmBwYWdlYOODl+ODreODkeODhuOCo+OBq+aMh+WumuOBl+OBn+WApOOCkuWEquWFiOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgcGFnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZTtcbiAgfVxuXG4gIHNldCBwYWdlKHBhZ2UpIHtcbiAgICB0aGlzLl9wYWdlID0gcGFnZTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMub25EZXZpY2VCYWNrQnV0dG9uID0gdGhpcy5fb25EZXZpY2VCYWNrQnV0dG9uLmJpbmQodGhpcyk7XG5cbiAgICBpZiAoIXBsYXRmb3JtLmlzQW5kcm9pZCgpIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdzd2lwZWFibGUnKSA9PT0gJ2ZvcmNlJykge1xuICAgICAgbGV0IHN3aXBlQW5pbWF0b3I7XG5cbiAgICAgIHRoaXMuX3N3aXBlID0gbmV3IFN3aXBlUmV2ZWFsKHtcbiAgICAgICAgZWxlbWVudDogdGhpcyxcbiAgICAgICAgZ2V0VGhyZXNob2xkOiAoKSA9PiBNYXRoLm1heCgwLjIsIHBhcnNlRmxvYXQodGhpcy5nZXRBdHRyaWJ1dGUoJ3N3aXBlLXRocmVzaG9sZCcpKSB8fCAwKSxcblxuICAgICAgICBzd2lwZU1heDogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29uU3dpcGUgJiYgdGhpcy5fb25Td2lwZSgxLCB7IGR1cmF0aW9uOiBzd2lwZUFuaW1hdG9yLmR1cmF0aW9uU3dpcGUsIHRpbWluZzogc3dpcGVBbmltYXRvci50aW1pbmdTd2lwZSB9KTtcbiAgICAgICAgICB0aGlzW3RoaXMuc3dpcGVNYXggPyAnc3dpcGVNYXgnIDogJ3BvcFBhZ2UnXSh7IGFuaW1hdG9yOiBzd2lwZUFuaW1hdG9yIH0pO1xuICAgICAgICAgIHN3aXBlQW5pbWF0b3IgPSBudWxsO1xuICAgICAgICB9LFxuICAgICAgICBzd2lwZU1pZDogKGRpc3RhbmNlLCB3aWR0aCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29uU3dpcGUgJiYgdGhpcy5fb25Td2lwZShkaXN0YW5jZS93aWR0aCk7XG4gICAgICAgICAgc3dpcGVBbmltYXRvci50cmFuc2xhdGUoZGlzdGFuY2UsIHdpZHRoLCB0aGlzLnRvcFBhZ2UucHJldmlvdXNFbGVtZW50U2libGluZywgdGhpcy50b3BQYWdlKTtcbiAgICAgICAgfSxcbiAgICAgICAgc3dpcGVNaW46ICgpID0+IHtcbiAgICAgICAgICB0aGlzLl9vblN3aXBlICYmIHRoaXMuX29uU3dpcGUoMCwgeyBkdXJhdGlvbjogc3dpcGVBbmltYXRvci5kdXJhdGlvblJlc3RvcmUsIHRpbWluZzogc3dpcGVBbmltYXRvci50aW1pbmdTd2lwZSB9KTtcbiAgICAgICAgICBzd2lwZUFuaW1hdG9yLnJlc3RvcmUodGhpcy50b3BQYWdlLnByZXZpb3VzRWxlbWVudFNpYmxpbmcsIHRoaXMudG9wUGFnZSk7XG4gICAgICAgICAgc3dpcGVBbmltYXRvciA9IG51bGw7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaWdub3JlU3dpcGU6IChldmVudCwgZGlzdGFuY2UpID0+IHtcbiAgICAgICAgICAvLyBCYXNpYyBjb25kaXRpb25zXG4gICAgICAgICAgaWYgKCF0aGlzLl9pc1J1bm5pbmcgJiYgdGhpcy5jaGlsZHJlbi5sZW5ndGggPiAxKSB7XG5cbiAgICAgICAgICAgIC8vIEFyZWEgb3IgZGlyZWN0aW9uYWwgaXNzdWVzXG4gICAgICAgICAgICBjb25zdCBhcmVhID0gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3N3aXBlLXRhcmdldC13aWR0aCcpIHx8IDI1LCAxMCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZ2VzdHVyZS5kaXJlY3Rpb24gPT09ICAncmlnaHQnICYmIGFyZWEgPiBkaXN0YW5jZSkge1xuXG4gICAgICAgICAgICAgIC8vIFN3aXBlcyBvbiBvbnMtYmFjay1idXR0b24gYW5kIGl0cyBjaGlsZHJlblxuICAgICAgICAgICAgICBjb25zdCBpc0JCID0gZWwgPT4gL29ucy1iYWNrLWJ1dHRvbi9pLnRlc3QoZWwudGFnTmFtZSk7XG4gICAgICAgICAgICAgIGlmICghaXNCQihldmVudC50YXJnZXQpICYmICF1dGlsLmZpbmRQYXJlbnQoZXZlbnQudGFyZ2V0LCBpc0JCLCBwID0+IC9vbnMtcGFnZS9pLnRlc3QocC50YWdOYW1lKSkpIHtcblxuICAgICAgICAgICAgICAgIC8vIEFuaW1hdG9yIGlzIHN3aXBlYWJsZVxuICAgICAgICAgICAgICAgIGNvbnN0IGFuaW1hdGlvbiA9ICh0aGlzLnRvcFBhZ2UucHVzaGVkT3B0aW9ucyB8fCB7fSkuYW5pbWF0aW9uIHx8IHRoaXMuYW5pbWF0b3JGYWN0b3J5Ll9hbmltYXRpb247XG4gICAgICAgICAgICAgICAgY29uc3QgQW5pbWF0b3IgPSBfYW5pbWF0b3JEaWN0W2FuaW1hdGlvbl0gaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgICAgICAgICAgICAgPyBfYW5pbWF0b3JEaWN0W2FuaW1hdGlvbl0uY2FsbCgpXG4gICAgICAgICAgICAgICAgICA6IF9hbmltYXRvckRpY3RbYW5pbWF0aW9uXTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgQW5pbWF0b3IgIT09ICd1bmRlZmluZWQnICYmIEFuaW1hdG9yLnN3aXBlYWJsZSkge1xuICAgICAgICAgICAgICAgICAgc3dpcGVBbmltYXRvciA9IG5ldyBBbmltYXRvcigpOyAvLyBQcmVwYXJlIGZvciB0aGUgc3dpcGVcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gSWdub3JlIHN3aXBlXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygnc3dpcGVhYmxlJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuXG4gICAgY29uc3QgZGVmZXJyZWQgPSB1dGlsLmRlZmVyKCk7XG4gICAgdGhpcy5sb2FkZWQgPSBkZWZlcnJlZC5wcm9taXNlO1xuXG4gICAgcmV3cml0YWJsZXMucmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2hvdyA9ICF1dGlsLmhhc0FueUNvbXBvbmVudEFzUGFyZW50KHRoaXMpO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IHsgYW5pbWF0aW9uOiAnbm9uZScsIHNob3cgfTtcblxuICAgICAgaWYgKHRoaXMucGFnZXMubGVuZ3RoID09PSAwICYmIHRoaXMuX2dldFBhZ2VUYXJnZXQoKSkge1xuICAgICAgICB0aGlzLnB1c2hQYWdlKHRoaXMuX2dldFBhZ2VUYXJnZXQoKSwgb3B0aW9ucykudGhlbigoKSA9PiBkZWZlcnJlZC5yZXNvbHZlKCkpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQodGhpcy5wYWdlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy50b3BQYWdlKSB7XG4gICAgICAgICAgY29udGVudFJlYWR5KHRoaXMudG9wUGFnZSwgKCkgPT5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKCk7XG4gICAgICAgICAgICAgIHNob3cgJiYgdGhpcy50b3BQYWdlLl9zaG93KCk7XG4gICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxhc3RQYWdlQmFja0J1dHRvbigpO1xuICAgICAgICAgICAgfSwgMClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA9PT0gMCAmJiB0aGlzLl9nZXRQYWdlVGFyZ2V0KCkpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaFBhZ2UodGhpcy5fZ2V0UGFnZVRhcmdldCgpLCBvcHRpb25zKS50aGVuKCgpID0+IGRlZmVycmVkLnJlc29sdmUoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgX3VwZGF0ZUFuaW1hdG9yRmFjdG9yeSgpIHtcbiAgICB0aGlzLl9hbmltYXRvckZhY3RvcnkgPSBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogTmF2aWdhdG9yQW5pbWF0b3IsXG4gICAgICBiYXNlQ2xhc3NOYW1lOiAnTmF2aWdhdG9yQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBudWxsO1xuXG4gICAgdGhpcy5fc3dpcGUgJiYgdGhpcy5fc3dpcGUuZGlzcG9zZSgpO1xuICAgIHRoaXMuX3N3aXBlID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2FuaW1hdGlvbicsICdzd2lwZWFibGUnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdhbmltYXRpb24nOlxuICAgICAgICB0aGlzLl91cGRhdGVBbmltYXRvckZhY3RvcnkoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzd2lwZWFibGUnOlxuICAgICAgICB0aGlzLl9zd2lwZSAmJiB0aGlzLl9zd2lwZS51cGRhdGUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgcG9wUGFnZVxuICAgKiBAc2lnbmF0dXJlIHBvcFBhZ2UoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dXG4gICAqICAgICBBbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcInNsaWRlXCJgLCBgXCJsaWZ0XCJgLCBgXCJmYWRlXCJgIGFuZCBgXCJub25lXCJgLlxuICAgKlxuICAgKiAgICAgVGhlc2UgYXJlIHBsYXRmb3JtIGJhc2VkIGFuaW1hdGlvbnMuIEZvciBmaXhlZCBhbmltYXRpb25zLCBhZGQgYFwiLWlvc1wiYCBvciBgXCItbWRcImAgc3VmZml4IHRvIHRoZSBhbmltYXRpb24gbmFtZS4gRS5nLiBgXCJsaWZ0LWlvc1wiYCwgYFwibGlmdC1tZFwiYC4gRGVmYXVsdHMgdmFsdWVzIGFyZSBgXCJzbGlkZS1pb3NcImAgYW5kIGBcImZhZGUtbWRcImAuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSB0cmFuc2l0aW9uIGhhcyBlbmRlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jg6Hjgr3jg4Pjg4njgavjgojjgovnlLvpnaLpgbfnp7vjgYzntYLkuobjgZfjgZ/pmpvjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuZGF0YV1cbiAgICogICBbZW5dQ3VzdG9tIGRhdGEgdGhhdCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgbmV3IHBhZ2UgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge051bWJlcn0gW29wdGlvbnMudGltZXNdXG4gICAqICAgW2VuXU51bWJlciBvZiBwYWdlcyB0byBiZSBwb3BwZWQuIE9ubHkgb25lIGFuaW1hdGlvbiB3aWxsIGJlIHNob3duLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIHJldmVhbGVkIHBhZ2UuWy9lbl1cbiAgICogICBbamFd5piO44KJ44GL44Gr44GX44Gf44Oa44O844K444KS6Kej5rG644GZ44KLUHJvbWlzZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Qb3BzIHRoZSBjdXJyZW50IHBhZ2UgZnJvbSB0aGUgcGFnZSBzdGFjay4gVGhlIHByZXZpb3VzIHBhZ2Ugd2lsbCBiZSBkaXNwbGF5ZWQuWy9lbl1cbiAgICogICBbamFd54++5Zyo6KGo56S65Lit44Gu44Oa44O844K444KS44Oa44O844K444K544K/44OD44Kv44GL44KJ5Y+W44KK6Zmk44GN44G+44GZ44CC5LiA44Gk5YmN44Gu44Oa44O844K444Gr5oi744KK44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHBvcFBhZ2Uob3B0aW9ucyA9IHt9KSB7XG4gICAgKHtvcHRpb25zfSA9IHRoaXMuX3ByZXBhcmVQYWdlQW5kT3B0aW9ucyhudWxsLCBvcHRpb25zKSk7XG5cbiAgICBpZiAodXRpbC5pc0ludGVnZXIob3B0aW9ucy50aW1lcykgJiYgb3B0aW9ucy50aW1lcyA+IDEpIHtcbiAgICAgIHRoaXMuX3JlbW92ZVBhZ2VzKG9wdGlvbnMudGltZXMpO1xuICAgIH1cblxuICAgIGNvbnN0IHBvcFVwZGF0ZSA9ICgpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICB0aGlzLl9wYWdlTG9hZGVyLnVubG9hZCh0aGlzLnBhZ2VzW3RoaXMucGFnZXMubGVuZ3RoIC0gMV0pO1xuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX3BvcFBhZ2Uob3B0aW9ucywgcG9wVXBkYXRlKTtcbiAgfVxuXG4gIF9wb3BQYWdlKG9wdGlvbnMsIHVwZGF0ZSA9ICgpID0+IFByb21pc2UucmVzb2x2ZSgpKSB7XG4gICAgaWYgKHRoaXMuX2lzUnVubmluZykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdwb3BQYWdlIGlzIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYWdlcy5sZW5ndGggPD0gMSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdvbnMtbmF2aWdhdG9yXFwncyBwYWdlIHN0YWNrIGlzIGVtcHR5LicpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9lbWl0UHJlUG9wRXZlbnQoKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDYW5jZWxlZCBpbiBwcmVwb3AgZXZlbnQuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy5wYWdlcy5sZW5ndGg7XG5cbiAgICB0aGlzLl9pc1J1bm5pbmcgPSB0cnVlO1xuXG4gICAgdGhpcy5wYWdlc1tsZW5ndGggLSAyXS51cGRhdGVCYWNrQnV0dG9uKChsZW5ndGggLSAyKSA+IDApO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgY29uc3QgbGVhdmVQYWdlID0gdGhpcy5wYWdlc1tsZW5ndGggLSAxXTtcbiAgICAgIGNvbnN0IGVudGVyUGFnZSA9IHRoaXMucGFnZXNbbGVuZ3RoIC0gMl07XG5cbiAgICAgIG9wdGlvbnMgPSB1dGlsLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zIHx8IHt9LCBsZWF2ZVBhZ2UucHVzaGVkT3B0aW9ucyB8fCB7fSwgb3B0aW9ucyk7XG5cbiAgICAgIGlmIChvcHRpb25zLmRhdGEpIHtcbiAgICAgICAgZW50ZXJQYWdlLmRhdGEgPSB1dGlsLmV4dGVuZCh7fSwgZW50ZXJQYWdlLmRhdGEgfHwge30sIG9wdGlvbnMuZGF0YSB8fCB7fSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRvbmUgPSAoKSA9PiB7XG4gICAgICAgIHVwZGF0ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2lzUnVubmluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgZW50ZXJQYWdlLl9zaG93KCk7XG4gICAgICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdwb3N0cG9wJywge2xlYXZlUGFnZSwgZW50ZXJQYWdlLCBuYXZpZ2F0b3I6IHRoaXN9KTtcblxuICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2sgJiYgb3B0aW9ucy5jYWxsYmFjayhlbnRlclBhZ2UpO1xuXG4gICAgICAgICAgcmVzb2x2ZShlbnRlclBhZ2UpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIGxlYXZlUGFnZS5faGlkZSgpO1xuICAgICAgZW50ZXJQYWdlLnN0eWxlLmRpc3BsYXkgPSAnJztcblxuICAgICAgY29uc3QgYW5pbWF0b3IgPSBvcHRpb25zLmFuaW1hdG9yIHx8IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcihvcHRpb25zKTtcbiAgICAgIGFuaW1hdG9yLnBvcCh0aGlzLnBhZ2VzW2xlbmd0aCAtIDJdLCB0aGlzLnBhZ2VzW2xlbmd0aCAtIDFdLCBkb25lKTtcbiAgICB9KS5jYXRjaCgoKSA9PiB0aGlzLl9pc1J1bm5pbmcgPSBmYWxzZSk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHB1c2hQYWdlXG4gICAqIEBzaWduYXR1cmUgcHVzaFBhZ2UocGFnZSwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFnZVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gQ2FuIGJlIGVpdGhlciBhIEhUTUwgZG9jdW1lbnQgb3IgYSB0ZW1wbGF0ZSBkZWZpbmVkIHdpdGggdGhlIGA8dGVtcGxhdGU+YCB0YWcuWy9lbl1cbiAgICogICBbamFdcGFnZeOBrlVSTOOBi+OAgeOCguOBl+OBj+OBr2A8dGVtcGxhdGU+YOOBp+Wuo+iogOOBl+OBn+ODhuODs+ODl+ODrOODvOODiOOBrmlk5bGe5oCn44Gu5YCk44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5wYWdlXVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gT25seSBuZWNlc3NhcnkgaWYgYHBhZ2VgIHBhcmFtZXRlciBpcyBudWxsIG9yIHVuZGVmaW5lZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMucGFnZUhUTUxdXG4gICAqICAgW2VuXUhUTUwgY29kZSB0aGF0IHdpbGwgYmUgY29tcHV0ZWQgYXMgYSBuZXcgcGFnZS4gT3ZlcndyaXRlcyBgcGFnZWAgcGFyYW1ldGVyLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXVxuICAgKiAgICAgQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJzbGlkZVwiYCwgYFwibGlmdFwiYCwgYFwiZmFkZVwiYCBhbmQgYFwibm9uZVwiYC5cbiAgICpcbiAgICogICAgIFRoZXNlIGFyZSBwbGF0Zm9ybSBiYXNlZCBhbmltYXRpb25zLiBGb3IgZml4ZWQgYW5pbWF0aW9ucywgYWRkIGBcIi1pb3NcImAgb3IgYFwiLW1kXCJgIHN1ZmZpeCB0byB0aGUgYW5pbWF0aW9uIG5hbWUuIEUuZy4gYFwibGlmdC1pb3NcImAsIGBcImxpZnQtbWRcImAuIERlZmF1bHRzIHZhbHVlcyBhcmUgYFwic2xpZGUtaW9zXCJgIGFuZCBgXCJmYWRlLW1kXCJgLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWBbL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1GdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSB0cmFuc2l0aW9uIGhhcyBlbmRlZC5bL2VuXVxuICAgKiAgIFtqYV1wdXNoUGFnZSgp44Gr44KI44KL55S76Z2i6YG356e744GM57WC5LqG44GX44Gf5pmC44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLmRhdGFdXG4gICAqICAgW2VuXUN1c3RvbSBkYXRhIHRoYXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlIG5ldyBwYWdlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgcHVzaGVkIHBhZ2UuWy9lbl1cbiAgICogICBbamFd6L+95Yqg44GX44Gf44Oa44O844K444KS6Kej5rG644GZ44KLUHJvbWlzZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1QdXNoZXMgdGhlIHNwZWNpZmllZCBwYWdlIGludG8gdGhlIHN0YWNrLlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn3BhZ2XjgpLmlrDjgZfjgYTjg5rjg7zjgrjjgrnjgr/jg4Pjgq/jgavov73liqDjgZfjgb7jgZnjgILmlrDjgZfjgYTjg5rjg7zjgrjjgYzooajnpLrjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcHVzaFBhZ2UocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgKHtwYWdlLCBvcHRpb25zfSA9IHRoaXMuX3ByZXBhcmVQYWdlQW5kT3B0aW9ucyhwYWdlLCBvcHRpb25zKSk7XG5cbiAgICBjb25zdCBwcmVwYXJlID0gcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQocGFnZUVsZW1lbnQpO1xuICAgICAgdGhpcy5fcGFnZU1hcC5zZXQocGFnZUVsZW1lbnQsIHBhZ2UpO1xuICAgICAgcGFnZUVsZW1lbnQgPSB1dGlsLmV4dGVuZChwYWdlRWxlbWVudCwge1xuICAgICAgICBkYXRhOiBvcHRpb25zLmRhdGFcbiAgICAgIH0pO1xuICAgICAgcGFnZUVsZW1lbnQuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucy5wYWdlSFRNTCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3B1c2hQYWdlKG9wdGlvbnMsICgpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBpbnN0YW50UGFnZUxvYWRlci5sb2FkKHtwYWdlOiBvcHRpb25zLnBhZ2VIVE1MLCBwYXJlbnQ6IHRoaXMsIHBhcmFtczogb3B0aW9ucy5kYXRhfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgICAgIHByZXBhcmUocGFnZUVsZW1lbnQpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3B1c2hQYWdlKG9wdGlvbnMsICgpID0+IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgdGhpcy5fcGFnZUxvYWRlci5sb2FkKHtwYWdlLCBwYXJlbnQ6IHRoaXMsIHBhcmFtczogb3B0aW9ucy5kYXRhfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgICBwcmVwYXJlKHBhZ2VFbGVtZW50KTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSk7XG4gICAgfSkpO1xuICB9XG5cbiAgX3B1c2hQYWdlKG9wdGlvbnMgPSB7fSwgdXBkYXRlID0gKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCkpIHtcbiAgICBpZiAodGhpcy5faXNSdW5uaW5nKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ3B1c2hQYWdlIGlzIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZW1pdFByZVB1c2hFdmVudCgpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0NhbmNlbGVkIGluIHByZXB1c2ggZXZlbnQuJyk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNSdW5uaW5nID0gdHJ1ZTtcblxuICAgIGNvbnN0IGFuaW1hdGlvbk9wdGlvbnMgPSBBbmltYXRvckZhY3RvcnkucGFyc2VBbmltYXRpb25PcHRpb25zU3RyaW5nKHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpKTtcbiAgICBvcHRpb25zID0gdXRpbC5leHRlbmQoe30sIHRoaXMub3B0aW9ucyB8fCB7fSwge2FuaW1hdGlvbk9wdGlvbnN9LCBvcHRpb25zKTtcblxuICAgIGNvbnN0IGFuaW1hdG9yID0gdGhpcy5fYW5pbWF0b3JGYWN0b3J5Lm5ld0FuaW1hdG9yKG9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIHVwZGF0ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgcGFnZUxlbmd0aCA9IHRoaXMucGFnZXMubGVuZ3RoO1xuXG4gICAgICBjb25zdCBlbnRlclBhZ2UgID0gdGhpcy5wYWdlc1twYWdlTGVuZ3RoIC0gMV07XG4gICAgICBjb25zdCBsZWF2ZVBhZ2UgPSBvcHRpb25zLmxlYXZlUGFnZSB8fCB0aGlzLnBhZ2VzW3BhZ2VMZW5ndGggLSAyXTtcblxuICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQoZW50ZXJQYWdlKTtcblxuICAgICAgZW50ZXJQYWdlLnVwZGF0ZUJhY2tCdXR0b24ocGFnZUxlbmd0aCA+IChvcHRpb25zLl9yZXBsYWNlUGFnZSA/IDIgOiAxKSk7XG5cbiAgICAgIGVudGVyUGFnZS5wdXNoZWRPcHRpb25zID0gdXRpbC5leHRlbmQoe30sIGVudGVyUGFnZS5wdXNoZWRPcHRpb25zIHx8IHt9LCBvcHRpb25zIHx8IHt9KTtcbiAgICAgIGVudGVyUGFnZS5kYXRhID0gdXRpbC5leHRlbmQoe30sIGVudGVyUGFnZS5kYXRhIHx8IHt9LCBvcHRpb25zLmRhdGEgfHwge30pO1xuICAgICAgZW50ZXJQYWdlLnVubG9hZCA9IGVudGVyUGFnZS51bmxvYWQgfHwgb3B0aW9ucy51bmxvYWQ7XG5cbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgY29uc3QgZG9uZSA9ICgpID0+IHtcbiAgICAgICAgICB0aGlzLl9pc1J1bm5pbmcgPSBmYWxzZTtcblxuICAgICAgICAgIG9wdGlvbnMuc2hvdyAhPT0gZmFsc2UgJiYgc2V0SW1tZWRpYXRlKCgpID0+IGVudGVyUGFnZS5fc2hvdygpKTtcbiAgICAgICAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ3Bvc3RwdXNoJywge2xlYXZlUGFnZSwgZW50ZXJQYWdlLCBuYXZpZ2F0b3I6IHRoaXN9KTtcblxuICAgICAgICAgIGlmIChsZWF2ZVBhZ2UpIHtcbiAgICAgICAgICAgIGxlYXZlUGFnZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2sgJiYgb3B0aW9ucy5jYWxsYmFjayhlbnRlclBhZ2UpO1xuXG4gICAgICAgICAgcmVzb2x2ZShlbnRlclBhZ2UpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGVudGVyUGFnZS5zdHlsZS52aXNpYmlsaXR5ID0gJyc7XG4gICAgICAgIGlmIChsZWF2ZVBhZ2UpIHtcbiAgICAgICAgICBsZWF2ZVBhZ2UuX2hpZGUoKTtcbiAgICAgICAgICBhbmltYXRvci5wdXNoKGVudGVyUGFnZSwgbGVhdmVQYWdlLCBkb25lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgdGhpcy5faXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHJlcGxhY2VQYWdlXG4gICAqIEBzaWduYXR1cmUgcmVwbGFjZVBhZ2UocGFnZSwgW29wdGlvbnNdKVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1Qcm9taXNlIHdoaWNoIHJlc29sdmVzIHRvIHRoZSBuZXcgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3mlrDjgZfjgYTjg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJlcGxhY2VzIHRoZSBjdXJyZW50IHRvcCBwYWdlIHdpdGggdGhlIHNwZWNpZmllZCBvbmUuIEV4dGVuZHMgYHB1c2hQYWdlKClgIHBhcmFtZXRlcnMuWy9lbl1cbiAgICogICBbamFd54++5Zyo6KGo56S65Lit44Gu44Oa44O844K444KS44KS5oyH5a6a44GX44Gf44Oa44O844K444Gr572u44GN5o+b44GI44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHJlcGxhY2VQYWdlKHBhZ2UsIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnB1c2hQYWdlKHBhZ2UsIG9wdGlvbnMpXG4gICAgICAudGhlbihyZXNvbHZlZFZhbHVlID0+IHtcbiAgICAgICAgaWYgKHRoaXMucGFnZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKHRoaXMucGFnZXNbdGhpcy5wYWdlcy5sZW5ndGggLSAyXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdXBkYXRlTGFzdFBhZ2VCYWNrQnV0dG9uKCk7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNvbHZlZFZhbHVlKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaW5zZXJ0UGFnZVxuICAgKiBAc2lnbmF0dXJlIGluc2VydFBhZ2UoaW5kZXgsIHBhZ2UsIFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gICAqICAgW2VuXVRoZSBpbmRleCB3aGVyZSBpdCBzaG91bGQgYmUgaW5zZXJ0ZWQuWy9lbl1cbiAgICogICBbamFd44K544K/44OD44Kv44Gr5oy/5YWl44GZ44KL5L2N572u44Gu44Kk44Oz44OH44OD44Kv44K544KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgaW5zZXJ0ZWQgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3mjIflrprjgZfjgZ/jg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUluc2VydCB0aGUgc3BlY2lmaWVkIHBhZ2UgaW50byB0aGUgc3RhY2sgd2l0aCBhdCBhIHBvc2l0aW9uIGRlZmluZWQgYnkgdGhlIGBpbmRleGAgYXJndW1lbnQuIEV4dGVuZHMgYHB1c2hQYWdlKClgIHBhcmFtZXRlcnMuWy9lbl1cbiAgICogICBbamFd5oyH5a6a44GX44GfcGFnZeOCkuODmuODvOOCuOOCueOCv+ODg+OCr+OBrmluZGV444Gn5oyH5a6a44GX44Gf5L2N572u44Gr6L+95Yqg44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGluc2VydFBhZ2UoaW5kZXgsIHBhZ2UsIG9wdGlvbnMgPSB7fSkge1xuICAgICh7cGFnZSwgb3B0aW9uc30gPSB0aGlzLl9wcmVwYXJlUGFnZUFuZE9wdGlvbnMocGFnZSwgb3B0aW9ucykpO1xuICAgIGluZGV4ID0gdGhpcy5fbm9ybWFsaXplSW5kZXgoaW5kZXgpO1xuXG4gICAgaWYgKGluZGV4ID49IHRoaXMucGFnZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wdXNoUGFnZShwYWdlLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBwYWdlID0gdHlwZW9mIG9wdGlvbnMucGFnZUhUTUwgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5wYWdlSFRNTCA6IHBhZ2U7XG4gICAgY29uc3QgbG9hZGVyID0gdHlwZW9mIG9wdGlvbnMucGFnZUhUTUwgPT09ICdzdHJpbmcnID8gaW5zdGFudFBhZ2VMb2FkZXIgOiB0aGlzLl9wYWdlTG9hZGVyO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgbG9hZGVyLmxvYWQoe3BhZ2UsIHBhcmVudDogdGhpc30sIHBhZ2VFbGVtZW50ID0+IHtcbiAgICAgICAgdmVyaWZ5UGFnZUVsZW1lbnQocGFnZUVsZW1lbnQpO1xuICAgICAgICB0aGlzLl9wYWdlTWFwLnNldChwYWdlRWxlbWVudCwgcGFnZSk7XG4gICAgICAgIHBhZ2VFbGVtZW50ID0gdXRpbC5leHRlbmQocGFnZUVsZW1lbnQsIHtcbiAgICAgICAgICBkYXRhOiBvcHRpb25zLmRhdGEsXG4gICAgICAgICAgcHVzaGVkT3B0aW9uczogb3B0aW9uc1xuICAgICAgICB9KTtcblxuICAgICAgICBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnMgPSB1dGlsLmV4dGVuZChcbiAgICAgICAgICB7fSxcbiAgICAgICAgICBBbmltYXRvckZhY3RvcnkucGFyc2VBbmltYXRpb25PcHRpb25zU3RyaW5nKHRoaXMuZ2V0QXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpKSxcbiAgICAgICAgICBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnMgfHwge31cbiAgICAgICAgKTtcblxuICAgICAgICBwYWdlRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB0aGlzLmluc2VydEJlZm9yZShwYWdlRWxlbWVudCwgdGhpcy5wYWdlc1tpbmRleF0pO1xuICAgICAgICB0aGlzLnRvcFBhZ2UudXBkYXRlQmFja0J1dHRvbih0cnVlKTtcblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBwYWdlRWxlbWVudCA9IG51bGw7XG4gICAgICAgICAgcmVzb2x2ZSh0aGlzLnBhZ2VzW2luZGV4XSk7XG4gICAgICAgIH0sIDEwMDAgLyA2MCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHJlbW92ZVBhZ2VcbiAgICogQHNpZ25hdHVyZSByZW1vdmVQYWdlKGluZGV4LCBbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiAgIFtlbl1UaGUgaW5kZXggd2hlcmUgaXQgc2hvdWxkIGJlIHJlbW92ZWQuWy9lbl1cbiAgICogICBbamFd44K544K/44OD44Kv44GL44KJ5YmK6Zmk44GZ44KL44Oa44O844K444Gu44Kk44Oz44OH44OD44Kv44K544KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgcmV2ZWFsZWQgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3liYrpmaTjgavjgojjgaPjgabooajnpLrjgZXjgozjgZ/jg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVJlbW92ZSB0aGUgc3BlY2lmaWVkIHBhZ2UgYXQgYSBwb3NpdGlvbiBpbiB0aGUgc3RhY2sgZGVmaW5lZCBieSB0aGUgYGluZGV4YCBhcmd1bWVudC4gRXh0ZW5kcyBgcG9wUGFnZSgpYCBwYXJhbWV0ZXJzLlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn+OCpOODs+ODh+ODg+OCr+OCueOBq+OBguOCi+ODmuODvOOCuOOCkuWJiumZpOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICByZW1vdmVQYWdlKGluZGV4LCBvcHRpb25zID0ge30pIHtcbiAgICBpbmRleCA9IHRoaXMuX25vcm1hbGl6ZUluZGV4KGluZGV4KTtcblxuICAgIGlmIChpbmRleCA8IHRoaXMucGFnZXMubGVuZ3RoIC0gMSkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBjb25zdCBsZWF2ZVBhZ2UgPSB0aGlzLnBhZ2VzW2luZGV4XTtcbiAgICAgICAgY29uc3QgZW50ZXJQYWdlID0gdGhpcy50b3BQYWdlO1xuXG4gICAgICAgIHRoaXMuX3BhZ2VNYXAuZGVsZXRlKGxlYXZlUGFnZSk7XG4gICAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKGxlYXZlUGFnZSk7XG4gICAgICAgIGlmICh0aGlzLnBhZ2VzLmxlbmd0aCA9PT0gMSkgeyAvLyBlZGdlIGNhc2VcbiAgICAgICAgICB0aGlzLnRvcFBhZ2UudXBkYXRlQmFja0J1dHRvbihmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXNvbHZlKGVudGVyUGFnZSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMucG9wUGFnZShvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCByZXNldFRvUGFnZVxuICAgKiBAc2lnbmF0dXJlIHJlc2V0VG9QYWdlKHBhZ2UsIFtvcHRpb25zXSlcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byB0aGUgbmV3IHRvcCBwYWdlLlsvZW5dXG4gICAqICAgW2phXeaWsOOBl+OBhOODiOODg+ODl+ODmuODvOOCuOOCkuino+axuuOBmeOCi1Byb21pc2XjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnBvcF1cbiAgICogICBbZW5dUGVyZm9ybXMgJ3BvcCcgZWZmZWN0IGlmIGB0cnVlYCBpbnN0ZWFkIG9mICdwdXNoJyBvciBub25lLiBUaGlzIGFsc28gc2V0cyBgb3B0aW9ucy5hbmltYXRpb25gIHZhbHVlIHRvIGBkZWZhdWx0YCBpbnN0ZWFkIG9mIGBub25lYC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ2xlYXJzIHBhZ2Ugc3RhY2sgYW5kIGFkZHMgdGhlIHNwZWNpZmllZCBwYWdlIHRvIHRoZSBzdGFjay4gRXh0ZW5kcyBgcHVzaFBhZ2UoKWAgcGFyYW1ldGVycy5bL2VuXVxuICAgKiAgIFtqYV3jg5rjg7zjgrjjgrnjgr/jg4Pjgq/jgpLjg6rjgrvjg4Pjg4jjgZfjgIHmjIflrprjgZfjgZ/jg5rjg7zjgrjjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgcmVzZXRUb1BhZ2UocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgKHtwYWdlLCBvcHRpb25zfSA9IHRoaXMuX3ByZXBhcmVQYWdlQW5kT3B0aW9ucyhwYWdlLCBvcHRpb25zKSk7XG5cbiAgICBpZiAoIW9wdGlvbnMuYW5pbWF0b3IgJiYgIW9wdGlvbnMuYW5pbWF0aW9uICYmICFvcHRpb25zLnBvcCkge1xuICAgICAgb3B0aW9ucy5hbmltYXRpb24gPSAnbm9uZSc7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLnBhZ2UgJiYgIW9wdGlvbnMucGFnZUhUTUwgJiYgdGhpcy5fZ2V0UGFnZVRhcmdldCgpKSB7XG4gICAgICBwYWdlID0gb3B0aW9ucy5wYWdlID0gdGhpcy5fZ2V0UGFnZVRhcmdldCgpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnBvcCkge1xuICAgICAgdGhpcy5fcmVtb3ZlUGFnZXMoKVxuICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0UGFnZSgwLCBwYWdlLCB7IGRhdGE6IG9wdGlvbnMuZGF0YSB9KVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLnBvcFBhZ2Uob3B0aW9ucykpO1xuICAgIH1cblxuICAgIC8vIFRpcDogY2FsbGJhY2sgcnVucyBiZWZvcmUgcmVzb2x2ZWQgcHJvbWlzZVxuICAgIGNvbnN0IGNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICBvcHRpb25zLmNhbGxiYWNrID0gbmV3UGFnZSA9PiB7XG4gICAgICB0aGlzLl9yZW1vdmVQYWdlcygpXG4gICAgICBuZXdQYWdlLnVwZGF0ZUJhY2tCdXR0b24oZmFsc2UpO1xuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2sobmV3UGFnZSk7XG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLnB1c2hQYWdlKHBhZ2UsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgYnJpbmdQYWdlVG9wXG4gICAqIEBzaWduYXR1cmUgYnJpbmdQYWdlVG9wKGl0ZW0sIFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSBpdGVtXG4gICAqICAgW2VuXVBhZ2UgVVJMIG9yIGluZGV4IG9mIGFuIGV4aXN0aW5nIHBhZ2UgaW4gbmF2aWdhdG9yJ3Mgc3RhY2suWy9lbl1cbiAgICogICBbamFd44Oa44O844K444GuVVJM44GL44KC44GX44GP44Gvb25zLW5hdmlnYXRvcuOBruODmuODvOOCuOOCueOCv+ODg+OCr+OBruOCpOODs+ODh+ODg+OCr+OCueWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gdGhlIG5ldyB0b3AgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV3mlrDjgZfjgYTjg4jjg4Pjg5fjg5rjg7zjgrjjgpLop6PmsbrjgZnjgotQcm9taXNl44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUJyaW5ncyB0aGUgZ2l2ZW4gcGFnZSB0byB0aGUgdG9wIG9mIHRoZSBwYWdlIHN0YWNrIGlmIGl0IGFscmVhZHkgZXhpc3RzIG9yIHB1c2hlcyBpdCBpbnRvIHRoZSBzdGFjayBpZiBkb2Vzbid0LiBFeHRlbmRzIGBwdXNoUGFnZSgpYCBwYXJhbWV0ZXJzLlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn+ODmuODvOOCuOOCkuODmuODvOOCuOOCueOCv+ODg+OCr+OBruS4gOeVquS4iuOBq+enu+WLleOBl+OBvuOBmeOAguOCguOBl+aMh+WumuOBl+OBn+ODmuODvOOCuOOBjOeEoeOBi+OBo+OBn+WgtOWQiOaWsOOBl+OBj3B1c2jjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgYnJpbmdQYWdlVG9wKGl0ZW0sIG9wdGlvbnMgPSB7fSkge1xuICAgIGlmIChbJ251bWJlcicsICdzdHJpbmcnXS5pbmRleE9mKHR5cGVvZiBpdGVtKSA9PT0gLTEpIHtcbiAgICAgIHV0aWwudGhyb3coJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBwYWdlIG5hbWUgb3IgdGhlIGluZGV4IG9mIGFuIGV4aXN0aW5nIHBhZ2UuIFlvdSBzdXBwbGllZCAnICsgaXRlbSk7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gdHlwZW9mIGl0ZW0gPT09ICdudW1iZXInID8gdGhpcy5fbm9ybWFsaXplSW5kZXgoaXRlbSkgOiB0aGlzLl9sYXN0SW5kZXhPZlBhZ2UoaXRlbSk7XG4gICAgY29uc3QgcGFnZSA9IHRoaXMucGFnZXNbaW5kZXhdO1xuXG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuIHRoaXMucHVzaFBhZ2UoaXRlbSwgb3B0aW9ucyk7XG4gICAgfVxuICAgICh7b3B0aW9uc30gPSB0aGlzLl9wcmVwYXJlUGFnZUFuZE9wdGlvbnMocGFnZSwgb3B0aW9ucykpO1xuXG4gICAgaWYgKGluZGV4ID09PSB0aGlzLnBhZ2VzLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocGFnZSk7XG4gICAgfVxuICAgIGlmICghcGFnZSkge1xuICAgICAgdXRpbC50aHJvdygnRmFpbGVkIHRvIGZpbmQgaXRlbSAnICsgaXRlbSk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9pc1J1bm5pbmcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgncHVzaFBhZ2UgaXMgYWxyZWFkeSBydW5uaW5nLicpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fZW1pdFByZVB1c2hFdmVudCgpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0NhbmNlbGVkIGluIHByZXB1c2ggZXZlbnQuJyk7XG4gICAgfVxuXG4gICAgcGFnZS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgcGFnZS5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgcGFnZS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHBhZ2UpO1xuICAgIHJldHVybiB0aGlzLl9wdXNoUGFnZShvcHRpb25zKTtcbiAgfVxuXG4gIF9wcmVwYXJlUGFnZUFuZE9wdGlvbnMocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zICE9ICdvYmplY3QnKSB7XG4gICAgICB1dGlsLnRocm93KCdvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0LiBZb3Ugc3VwcGxpZWQgJyArIG9wdGlvbnMpO1xuICAgIH1cblxuICAgIGlmICgocGFnZSA9PT0gbnVsbCB8fCBwYWdlID09PSB1bmRlZmluZWQpICYmIG9wdGlvbnMucGFnZSkge1xuICAgICAgcGFnZSA9IG9wdGlvbnMucGFnZTtcbiAgICB9XG5cbiAgICBvcHRpb25zID0gdXRpbC5leHRlbmQoe30sIHRoaXMub3B0aW9ucyB8fCB7fSwgb3B0aW9ucywge3BhZ2V9KTtcblxuICAgIHJldHVybiB7cGFnZSwgb3B0aW9uc307XG4gIH1cblxuICBfcmVtb3ZlUGFnZXModGltZXMpIHtcbiAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFnZXM7XG4gICAgbGV0IHVudGlsID0gdGltZXMgPT09IHVuZGVmaW5lZCA/IDAgOiBwYWdlcy5sZW5ndGggLSB0aW1lcztcbiAgICB1bnRpbCA9IHVudGlsIDwgMCA/IDEgOiB1bnRpbDtcblxuICAgIGZvciAobGV0IGkgPSBwYWdlcy5sZW5ndGggLSAyOyBpID49IHVudGlsOyBpLS0pIHtcbiAgICAgIHRoaXMuX3BhZ2VNYXAuZGVsZXRlKHBhZ2VzW2ldKTtcbiAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKHBhZ2VzW2ldKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlTGFzdFBhZ2VCYWNrQnV0dG9uKCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wYWdlcy5sZW5ndGggLSAxO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB0aGlzLnBhZ2VzW2luZGV4XS51cGRhdGVCYWNrQnV0dG9uKGluZGV4ID4gMCk7XG4gICAgfVxuICB9XG5cbiAgX25vcm1hbGl6ZUluZGV4KGluZGV4KSB7XG4gICAgcmV0dXJuIGluZGV4ID49IDAgPyBpbmRleCA6IE1hdGguYWJzKHRoaXMucGFnZXMubGVuZ3RoICsgaW5kZXgpICUgdGhpcy5wYWdlcy5sZW5ndGg7XG4gIH1cblxuICBfb25EZXZpY2VCYWNrQnV0dG9uKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMucGFnZXMubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5wb3BQYWdlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50LmNhbGxQYXJlbnRIYW5kbGVyKCk7XG4gICAgfVxuICB9XG5cbiAgX2xhc3RJbmRleE9mUGFnZShwYWdlTmFtZSkge1xuICAgIGxldCBpbmRleDtcbiAgICBmb3IgKGluZGV4ID0gdGhpcy5wYWdlcy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleC0tKSB7XG4gICAgICBpZiAocGFnZU5hbWUgPT09IHRoaXMuX3BhZ2VNYXAuZ2V0KHRoaXMucGFnZXNbaW5kZXhdKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgX2VtaXRQcmVFdmVudChuYW1lLCBkYXRhID0ge30pIHtcbiAgICBsZXQgaXNDYW5jZWxlZCA9IGZhbHNlO1xuXG4gICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdwcmUnICsgbmFtZSwgdXRpbC5leHRlbmQoe1xuICAgICAgbmF2aWdhdG9yOiB0aGlzLFxuICAgICAgY3VycmVudFBhZ2U6IHRoaXMucGFnZXNbdGhpcy5wYWdlcy5sZW5ndGggLSAxXSxcbiAgICAgIGNhbmNlbDogKCkgPT4gaXNDYW5jZWxlZCA9IHRydWVcbiAgICB9LCBkYXRhKSk7XG5cbiAgICByZXR1cm4gaXNDYW5jZWxlZDtcbiAgfVxuXG4gIF9lbWl0UHJlUHVzaEV2ZW50KCkge1xuICAgIHJldHVybiB0aGlzLl9lbWl0UHJlRXZlbnQoJ3B1c2gnKTtcbiAgfVxuXG4gIF9lbWl0UHJlUG9wRXZlbnQoKSB7XG4gICAgY29uc3QgbCA9IHRoaXMucGFnZXMubGVuZ3RoO1xuICAgIHJldHVybiB0aGlzLl9lbWl0UHJlRXZlbnQoJ3BvcCcsIHtcbiAgICAgIGxlYXZlUGFnZTogdGhpcy5wYWdlc1tsIC0gMV0sXG4gICAgICBlbnRlclBhZ2U6IHRoaXMucGFnZXNbbCAtIDJdXG4gICAgfSk7XG4gIH1cblxuICAvLyBUT0RPOiDmm7jjgY3nm7TjgZlcbiAgX2NyZWF0ZVBhZ2VFbGVtZW50KHRlbXBsYXRlSFRNTCkge1xuICAgIGNvbnN0IHBhZ2VFbGVtZW50ID0gdXRpbC5jcmVhdGVFbGVtZW50KGludGVybmFsLm5vcm1hbGl6ZVBhZ2VIVE1MKHRlbXBsYXRlSFRNTCkpO1xuICAgIHZlcmlmeVBhZ2VFbGVtZW50KHBhZ2VFbGVtZW50KTtcbiAgICByZXR1cm4gcGFnZUVsZW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cbiAgZ2V0IG9uRGV2aWNlQmFja0J1dHRvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fYmFja0J1dHRvbkhhbmRsZXI7XG4gIH1cblxuICBzZXQgb25EZXZpY2VCYWNrQnV0dG9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlci5jcmVhdGVIYW5kbGVyKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdG9wUGFnZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCB0b3AgcGFnZSBlbGVtZW50LiBVc2UgdGhpcyBtZXRob2QgdG8gYWNjZXNzIG9wdGlvbnMgcGFzc2VkIGJ5IGBwdXNoUGFnZSgpYC1saWtlIG1ldGhvZHMuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu44Oa44O844K444KS5Y+W5b6X44GX44G+44GZ44CCcHVzaFBhZ2UoKeOChHJlc2V0VG9QYWdlKCnjg6Hjgr3jg4Pjg4njga7lvJXmlbDjgpLlj5blvpfjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHRvcFBhZ2UoKSB7XG4gICAgbGV0IGxhc3QgPSB0aGlzLmxhc3RFbGVtZW50Q2hpbGQ7XG4gICAgd2hpbGUgKGxhc3QgJiYgbGFzdC50YWdOYW1lICE9PSAnT05TLVBBR0UnKSB7IGxhc3QgPSBsYXN0LnByZXZpb3VzRWxlbWVudFNpYmxpbmc7IH1cbiAgICByZXR1cm4gbGFzdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgcGFnZXNcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtBcnJheX1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUNvcHkgb2YgdGhlIG5hdmlnYXRvcidzIHBhZ2Ugc3RhY2suWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBwYWdlcygpIHtcbiAgICByZXR1cm4gdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZHJlbilcbiAgICAgIC5maWx0ZXIoZWxlbWVudCA9PiBlbGVtZW50LnRhZ05hbWUgPT09ICdPTlMtUEFHRScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvblN3aXBlXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhvb2sgY2FsbGVkIHdoZW5ldmVyIHRoZSB1c2VyIHNsaWRlcyB0aGUgbmF2aWdhdG9yIChzd2lwZS10by1wb3ApLiBJdCBnZXRzIGEgZGVjaW1hbCByYXRpbyAoMC0xKSBhbmQgYW4gYW5pbWF0aW9uT3B0aW9ucyBvYmplY3QgYXMgYXJndW1lbnRzLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgb25Td2lwZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fb25Td2lwZTtcbiAgfVxuXG4gIHNldCBvblN3aXBlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wib25Td2lwZVwiIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICB0aGlzLl9vblN3aXBlID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9wdGlvbnNcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXURlZmF1bHQgb3B0aW9ucyBvYmplY3QuIEF0dHJpYnV0ZXMgaGF2ZSBwcmlvcml0eSBvdmVyIHRoaXMgcHJvcGVydHkuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBBbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcInNsaWRlXCJgLCBgXCJsaWZ0XCJgLCBgXCJmYWRlXCJgIGFuZCBgXCJub25lXCJgLlxuICAgKiAgICAgVGhlc2UgYXJlIHBsYXRmb3JtIGJhc2VkIGFuaW1hdGlvbnMuIEZvciBmaXhlZCBhbmltYXRpb25zLCBhZGQgYFwiLWlvc1wiYCBvciBgXCItbWRcImAgc3VmZml4IHRvIHRoZSBhbmltYXRpb24gbmFtZS4gRS5nLiBgXCJsaWZ0LWlvc1wiYCwgYFwibGlmdC1tZFwiYC4gRGVmYXVsdHMgdmFsdWVzIGFyZSBgXCJzbGlkZS1pb3NcImAgYW5kIGBcImZhZGUtbWRcImAuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb3B0aW9ucy5jYWxsYmFja1xuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgdHJhbnNpdGlvbiBoYXMgZW5kZWQuWy9lbl1cbiAgICogICBbamFd44GT44Gu44Oh44K944OD44OJ44Gr44KI44KL55S76Z2i6YG356e744GM57WC5LqG44GX44Gf6Zqb44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgZ2V0IG9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnM7XG4gIH1cbiAgc2V0IG9wdGlvbnMob2JqZWN0KSB7XG4gICAgdGhpcy5fb3B0aW9ucyA9IG9iamVjdDtcbiAgfVxuXG4gIHNldCBfaXNSdW5uaW5nKHZhbHVlKSB7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ19pcy1ydW5uaW5nJywgdmFsdWUgPyAndHJ1ZScgOiAnZmFsc2UnKTtcbiAgfVxuICBnZXQgX2lzUnVubmluZygpIHtcbiAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMuZ2V0QXR0cmlidXRlKCdfaXMtcnVubmluZycpKTtcbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIHRoaXMubG9hZGVkLnRoZW4oKCkgPT4gdGhpcy50b3BQYWdlICYmIHRoaXMudG9wUGFnZS5fc2hvdygpKVxuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgdGhpcy50b3BQYWdlICYmIHRoaXMudG9wUGFnZS5faGlkZSgpXG4gIH1cblxuICBfZGVzdHJveSgpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5wYWdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGhpcy5fcGFnZUxvYWRlci51bmxvYWQodGhpcy5wYWdlc1tpXSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZW1vdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBBbmltYXRvclxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyQW5pbWF0b3IobmFtZSwgQW5pbWF0b3IpIHtcbiAgICBpZiAoIShBbmltYXRvci5wcm90b3R5cGUgaW5zdGFuY2VvZiBOYXZpZ2F0b3JBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignTmF2aWdhdG9yJyk7XG4gICAgfVxuXG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cblxuICBzdGF0aWMgZ2V0IE5hdmlnYXRvckFuaW1hdG9yKCkge1xuICAgIHJldHVybiBOYXZpZ2F0b3JBbmltYXRvcjtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ3ByZXB1c2gnLCAncG9zdHB1c2gnLCAncHJlcG9wJywgJ3Bvc3Rwb3AnXTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgcmV3cml0YWJsZXMoKSB7XG4gICAgcmV0dXJuIHJld3JpdGFibGVzO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLk5hdmlnYXRvciA9IE5hdmlnYXRvckVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1uYXZpZ2F0b3InLCBOYXZpZ2F0b3JFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcblxuY29uc3QgZGVmYXVsdENsYXNzTmFtZSA9ICd0b29sYmFyJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ3Rvb2xiYXItLSonLFxuICAnLnRvb2xiYXJfX2xlZnQnOiAndG9vbGJhci0tKl9fbGVmdCcsXG4gICcudG9vbGJhcl9fY2VudGVyJzogJ3Rvb2xiYXItLSpfX2NlbnRlcicsXG4gICcudG9vbGJhcl9fcmlnaHQnOiAndG9vbGJhci0tKl9fcmlnaHQnXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy10b29sYmFyXG4gKiBAY2F0ZWdvcnkgcGFnZVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gdG9vbGJhci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBtb2RpZmllciB0cmFuc3BhcmVudFxuICogICBbZW5dVHJhbnNwYXJlbnQgdG9vbGJhci5bL2VuXVxuICogICBbamFd6YCP5piO44Gq6IOM5pmv44KS5oyB44Gk44OE44O844Or44OQ44O844KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBjb3Zlci1jb250ZW50XG4gKiAgIFtlbl1EaXNwbGF5cyB0aGUgdG9vbGJhciBvbiB0b3Agb2YgdGhlIHBhZ2UncyBjb250ZW50LiBTaG91bGQgYmUgY29tYmluZWQgd2l0aCBgdHJhbnNwYXJlbnRgIG1vZGlmaWVyLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIG5vc2hhZG93XG4gKiAgIFtlbl1Ub29sYmFyIHdpdGhvdXQgc2hhZG93LlsvZW5dXG4gKiAgIFtqYV3jg4Tjg7zjg6vjg5Djg7zjgavlvbHjgpLku5jjgZHjgZrjgavooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBUb29sYmFyIGNvbXBvbmVudCB0aGF0IGNhbiBiZSB1c2VkIHdpdGggbmF2aWdhdGlvbi5cbiAqXG4gKiAgICAgTGVmdCwgY2VudGVyIGFuZCByaWdodCBjb250YWluZXJzIGNhbiBiZSBzcGVjaWZpZWQgYnkgY2xhc3MgbmFtZXMuXG4gKlxuICogICAgIFRoaXMgY29tcG9uZW50IHdpbGwgYXV0b21hdGljYWxseSBkaXNwbGF5IGFzIGEgTWF0ZXJpYWwgRGVzaWduIHRvb2xiYXIgd2hlbiBydW5uaW5nIG9uIEFuZHJvaWQgZGV2aWNlcy5cbiAqICAgWy9lbl1cbiAqICAgW2phXeODiuODk+OCsuODvOOCt+ODp+ODs+OBp+S9v+eUqOOBmeOCi+ODhOODvOODq+ODkOODvOeUqOOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAguOCr+ODqeOCueWQjeOBq+OCiOOCiuOAgeW3puOAgeS4reWkruOAgeWPs+OBruOCs+ODs+ODhuODiuOCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gKiBAY29kZXBlbiBhSG1HTFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3Rvb2xiYXJcbiAqIEBndWlkZSBjb21waWxhdGlvbi5odG1sI3Rvb2xiYXItY29tcGlsYXRpb24gW2VuXUFkZGluZyBhIHRvb2xiYXJbL2VuXVtqYV3jg4Tjg7zjg6vjg5Djg7zjga7ov73liqBbL2phXVxuICogQHNlZWFsc28gb25zLWJvdHRvbS10b29sYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtYm90dG9tLXRvb2xiYXI+YCBkaXNwbGF5cyBhIHRvb2xiYXIgb24gdGhlIGJvdHRvbSBvZiB0aGUgcGFnZS5bL2VuXVxuICogICBbamFdb25zLWJvdHRvbS10b29sYmFy44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1iYWNrLWJ1dHRvblxuICogICBbZW5dVGhlIGA8b25zLWJhY2stYnV0dG9uPmAgY29tcG9uZW50IGRpc3BsYXlzIGEgYmFjayBidXR0b24gaW5zaWRlIHRoZSB0b29sYmFyLlsvZW5dXG4gKiAgIFtqYV1vbnMtYmFjay1idXR0b27jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQHNlZWFsc28gb25zLXRvb2xiYXItYnV0dG9uXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9vbGJhci1idXR0b24+YCBjb21wb25lbnQgZGlzcGxheXMgYSB0b29sYmFyIGJ1dHRvbiBpbnNpZGUgdGhlIHRvb2xiYXIuWy9lbl1cbiAqICAgW2phXW9ucy10b29sYmFyLWJ1dHRvbuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1wYWdlPlxuICogICA8b25zLXRvb2xiYXI+XG4gKiAgICAgPGRpdiBjbGFzcz1cImxlZnRcIj5cbiAqICAgICAgIDxvbnMtYmFjay1idXR0b24+XG4gKiAgICAgICAgIEJhY2tcbiAqICAgICAgIDwvb25zLWJhY2stYnV0dG9uPlxuICogICAgIDwvZGl2PlxuICogICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJcIj5cbiAqICAgICAgIFRpdGxlXG4gKiAgICAgPC9kaXY+XG4gKiAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+XG4gKiAgICAgICA8b25zLXRvb2xiYXItYnV0dG9uPlxuICogICAgICAgICA8b25zLWljb24gaWNvbj1cIm1kLW1lbnVcIj48L29ucy1pY29uPlxuICogICAgICAgPC9vbnMtdG9vbGJhci1idXR0b24+XG4gKiAgICAgPC9kaXY+XG4gKiAgIDwvb25zLXRvb2xiYXI+XG4gKiA8L29ucy1wYWdlPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvb2xiYXJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGlubGluZVxuICAgKiBAaW5pdG9ubHlcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXURpc3BsYXkgdGhlIHRvb2xiYXIgYXMgYW4gaW5saW5lIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFd44OE44O844Or44OQ44O844KS44Kk44Oz44Op44Kk44Oz44Gr572u44GN44G+44GZ44CC44K544Kv44Ot44O844Or6aCY5Z+f5YaF44Gr44Gd44Gu44G+44G+6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3RhdGljXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TdGF0aWMgdG9vbGJhcnMgYXJlIG5vdCBhbmltYXRlZCBieSBgb25zLW5hdmlnYXRvcmAgd2hlbiBwdXNoaW5nIG9yIHBvcHBpbmcgcGFnZXMuIFRoaXMgY2FuIGJlIHVzZWZ1bCB0byBpbXByb3ZlIHBlcmZvcm1hbmNlIGluIHNvbWUgc2l0dWF0aW9ucy5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHRvb2xiYXIuWy9lbl1cbiAgICogICBbamFd44OE44O844Or44OQ44O844Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKCk7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdjbGFzcyddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzZXRWaXNpYmlsaXR5XG4gICAqIEBzaWduYXR1cmUgc2V0VmlzaWJpbGl0eSh2aXNpYmxlKVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHZpc2libGVcbiAgICogICBbZW5dU2V0IHRvIHRydWUgdG8gc2hvdyB0aGUgdG9vbGJhciwgZmFsc2UgdG8gaGlkZSBpdFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93cyB0aGUgdG9vbGJhciBpZiB2aXNpYmxlIGlzIHRydWUsIG90aGVyd2lzZSBoaWRlcyBpdC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgc2V0VmlzaWJpbGl0eSh2aXNpYmxlKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9IHZpc2libGUgPyAnJyA6ICdub25lJztcblxuICAgICAgaWYgKHRoaXMucGFyZW50Tm9kZSkge1xuICAgICAgICBjb25zdCBzaWJsaW5nQmFja2dyb3VuZCA9IHV0aWwuZmluZENoaWxkKHRoaXMucGFyZW50Tm9kZSwgJy5wYWdlX19iYWNrZ3JvdW5kJyk7XG4gICAgICAgIGlmIChzaWJsaW5nQmFja2dyb3VuZCkge1xuICAgICAgICAgIHNpYmxpbmdCYWNrZ3JvdW5kLnN0eWxlLnRvcCA9IHZpc2libGUgPyBudWxsIDogMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNpYmxpbmdDb250ZW50ID0gdXRpbC5maW5kQ2hpbGQodGhpcy5wYXJlbnROb2RlLCAnLnBhZ2VfX2NvbnRlbnQnKTtcbiAgICAgICAgaWYgKHNpYmxpbmdDb250ZW50KSB7XG4gICAgICAgICAgc2libGluZ0NvbnRlbnQuc3R5bGUudG9wID0gdmlzaWJsZSA/IG51bGwgOiAwO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSB0b29sYmFyLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzaG93KCkge1xuICAgIHRoaXMuc2V0VmlzaWJpbGl0eSh0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhpZGVcbiAgICogQHNpZ25hdHVyZSBoaWRlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhpZGUgdGhlIHRvb2xiYXIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGhpZGUoKSB7XG4gICAgdGhpcy5zZXRWaXNpYmlsaXR5KGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIF9nZXRUb29sYmFyTGVmdEl0ZW1zRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCcubGVmdCcpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICAgKi9cbiAgX2dldFRvb2xiYXJDZW50ZXJJdGVtc0VsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcignLmNlbnRlcicpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICAgKi9cbiAgX2dldFRvb2xiYXJSaWdodEl0ZW1zRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCcucmlnaHQnKSB8fCBpbnRlcm5hbC5udWxsRWxlbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAgICovXG4gIF9nZXRUb29sYmFyQmFja0J1dHRvbkxhYmVsRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCdvbnMtYmFjay1idXR0b24gLmJhY2stYnV0dG9uX19sYWJlbCcpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICAgKi9cbiAgX2dldFRvb2xiYXJCYWNrQnV0dG9uSWNvbkVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3Rvcignb25zLWJhY2stYnV0dG9uIC5iYWNrLWJ1dHRvbl9faWNvbicpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgIHRoaXMuX2Vuc3VyZVRvb2xiYXJJdGVtRWxlbWVudHMoKTtcbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG4gIH1cblxuICBfZW5zdXJlVG9vbGJhckl0ZW1FbGVtZW50cygpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMCA7IGktLSkge1xuICAgICAgLy8gY2FzZSBvZiBub3QgZWxlbWVudFxuICAgICAgaWYgKHRoaXMuY2hpbGROb2Rlc1tpXS5ub2RlVHlwZSAhPSAxKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlQ2hpbGQodGhpcy5jaGlsZE5vZGVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjZW50ZXIgPSB0aGlzLl9lbnN1cmVUb29sYmFyRWxlbWVudCgnY2VudGVyJyk7XG4gICAgY2VudGVyLmNsYXNzTGlzdC5hZGQoJ3Rvb2xiYXJfX3RpdGxlJyk7XG5cbiAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggIT09IDEgfHwgIXRoaXMuY2hpbGRyZW5bMF0uY2xhc3NMaXN0LmNvbnRhaW5zKCdjZW50ZXInKSkge1xuICAgICAgY29uc3QgbGVmdCA9IHRoaXMuX2Vuc3VyZVRvb2xiYXJFbGVtZW50KCdsZWZ0Jyk7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMuX2Vuc3VyZVRvb2xiYXJFbGVtZW50KCdyaWdodCcpO1xuXG4gICAgICBpZiAodGhpcy5jaGlsZHJlblswXSAhPT0gbGVmdCB8fCB0aGlzLmNoaWxkcmVuWzFdICE9PSBjZW50ZXIgfHwgdGhpcy5jaGlsZHJlblsyXSAhPT0gcmlnaHQpIHtcbiAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChsZWZ0KTtcbiAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChjZW50ZXIpO1xuICAgICAgICB0aGlzLmFwcGVuZENoaWxkKHJpZ2h0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfZW5zdXJlVG9vbGJhckVsZW1lbnQobmFtZSkge1xuICAgIGlmICh1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnRvb2xiYXJfXycgKyBuYW1lKSkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcudG9vbGJhcl9fJyArIG5hbWUpO1xuICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKG5hbWUpO1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcuJyArIG5hbWUpIHx8IHV0aWwuY3JlYXRlKCcuJyArIG5hbWUpO1xuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgndG9vbGJhcl9fJyArIG5hbWUpO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cbn1cblxub25zRWxlbWVudHMuVG9vbGJhciA9IFRvb2xiYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtdG9vbGJhcicsIFRvb2xiYXJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgZGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIgZnJvbSAnLi4vb25zL2ludGVybmFsL2RldmljZS1iYWNrLWJ1dHRvbi1kaXNwYXRjaGVyJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5pbXBvcnQgJy4vb25zLXRvb2xiYXInOyAvLyBlbnN1cmVzIHRoYXQgJ29ucy10b29sYmFyJyBlbGVtZW50IGlzIHJlZ2lzdGVyZWRcblxuY29uc3QgZGVmYXVsdENsYXNzTmFtZSA9ICdwYWdlJztcbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdwYWdlLS0qJyxcbiAgJy5wYWdlX19jb250ZW50JzogJ3BhZ2UtLSpfX2NvbnRlbnQnLFxuICAnLnBhZ2VfX2JhY2tncm91bmQnOiAncGFnZS0tKl9fYmFja2dyb3VuZCdcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXBhZ2VcbiAqIEBjYXRlZ29yeSBwYWdlXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBzdHlsZVsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBUaGlzIGNvbXBvbmVudCBkZWZpbmVzIHRoZSByb290IG9mIGVhY2ggcGFnZS4gSWYgdGhlIGNvbnRlbnQgaXMgbGFyZ2UgaXQgd2lsbCBiZWNvbWUgc2Nyb2xsYWJsZS5cbiAqXG4gKiAgICAgQSBuYXZpZ2F0aW9uIGJhciBjYW4gYmUgYWRkZWQgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZSB1c2luZyB0aGUgYDxvbnMtdG9vbGJhcj5gIGVsZW1lbnQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg5rjg7zjgrjlrprnvqnjga7jgZ/jgoHjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjgafjgZnjgILjgZPjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7lhoXlrrnjga/jgrnjgq/jg63jg7zjg6vjgYzoqLHlj6/jgZXjgozjgb7jgZnjgIJbL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3BhZ2VcbiAqIEBndWlkZSBsaWZlY3ljbGUuaHRtbCNldmVudHNcbiAqICAgW2VuXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9lbl1cbiAqICAgW2phXU92ZXJ2aWV3IG9mIHBhZ2UgZXZlbnRzWy9qYV1cbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogICBbZW5dTWFuYWdpbmcgbXVsdGlwbGUgcGFnZXNbL2VuXVxuICogICBbamFd6KSH5pWw44Gu44Oa44O844K444KS566h55CG44GZ44KLWy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQHNlZWFsc28gb25zLXRvb2xiYXJcbiAqICAgW2VuXVVzZSB0aGUgYDxvbnMtdG9vbGJhcj5gIGVsZW1lbnQgdG8gYWRkIGEgbmF2aWdhdGlvbiBiYXIgdG8gdGhlIHRvcCBvZiB0aGUgcGFnZS5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXBhZ2U+XG4gKiAgIDxvbnMtdG9vbGJhcj5cbiAqICAgICA8ZGl2IGNsYXNzPVwibGVmdFwiPlxuICogICAgICAgPG9ucy1iYWNrLWJ1dHRvbj5CYWNrPC9vbnMtYmFjay1idXR0b24+XG4gKiAgICAgPC9kaXY+XG4gKiAgICAgPGRpdiBjbGFzcz1cImNlbnRlclwiPlRpdGxlPC9kaXY+XG4gKiAgICAgPGRpdiBjbGFzcz1cInJpZ2h0XCI+XG4gKiAgICAgICA8b25zLXRvb2xiYXItYnV0dG9uPlxuICogICAgICAgICA8b25zLWljb24gaWNvbj1cIm1kLW1lbnVcIj48L29ucy1pY29uPlxuICogICAgICAgPC9vbnMtdG9vbGJhci1idXR0b24+XG4gKiAgICAgPC9kaXY+XG4gKiAgIDwvb25zLXRvb2xiYXI+XG4gKlxuICogICA8cD5QYWdlIGNvbnRlbnQ8L3A+XG4gKiA8L29ucy1wYWdlPlxuICpcbiAqIEBleGFtcGxlXG4gKiA8c2NyaXB0PlxuICogICBteUFwcC5oYW5kbGVyID0gZnVuY3Rpb24oZG9uZSkge1xuICogICAgIGxvYWRNb3JlKCkudGhlbihkb25lKTtcbiAqICAgfVxuICogPC9zY3JpcHQ+XG4gKlxuICogPG9ucy1wYWdlIG9uLWluZmluaXRlLXNjcm9sbD1cIm15QXBwLmhhbmRsZXJcIj5cbiAqICAgPG9ucy10b29sYmFyPlxuICogICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJcIj5MaXN0PC9kaXY+XG4gKiAgIDwvb25zLXRvb2xiYXI+XG4gKlxuICogICA8b25zLWxpc3Q+XG4gKiAgICAgPG9ucy1saXN0LWl0ZW0+IzE8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgPG9ucy1saXN0LWl0ZW0+IzI8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgPG9ucy1saXN0LWl0ZW0+IzM8L29ucy1saXN0LWl0ZW0+XG4gKiAgICAgLi4uXG4gKiAgIDwvb25zLWxpc3Q+XG4gKiA8L29ucy1wYWdlPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYWdlRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGV2ZW50IGluaXRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHJpZ2h0IGFmdGVyIHRoZSBwYWdlIGlzIGF0dGFjaGVkLlsvZW5dXG4gICAqICAgW2phXeODmuODvOOCuOOBjOOCouOCv+ODg+ODgeOBleOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgc2hvd1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgcmlnaHQgYWZ0ZXIgdGhlIHBhZ2UgaXMgc2hvd24uWy9lbl1cbiAgICogICBbamFd44Oa44O844K444GM6KGo56S644GV44KM44Gf5b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBoaWRlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCByaWdodCBhZnRlciB0aGUgcGFnZSBpcyBoaWRkZW4uWy9lbl1cbiAgICogICBbamFd44Oa44O844K444GM6Zqg44KM44Gf5b6M44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBkZXN0cm95XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCByaWdodCBiZWZvcmUgdGhlIHBhZ2UgaXMgZGVzdHJveWVkLlsvZW5dXG4gICAqICAgW2phXeODmuODvOOCuOOBjOegtOajhOOBleOCjOOCi+WJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IG1vZGlmaWVyIG5hbWUgdG8gc3BlY2lmeSBjdXN0b20gc3R5bGVzLlsvZW5dXG4gICAqICAgW2phXeOCueOCv+OCpOODq+Wumue+qeOCkuOCq+OCueOCv+ODnuOCpOOCuuOBmeOCi+OBn+OCgeOBruWQjeWJjeOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG9uLWluZmluaXRlLXNjcm9sbFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUGF0aCBvZiB0aGUgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgb24gaW5maW5pdGUgc2Nyb2xsaW5nLiBFeGFtcGxlOiBgYXBwLmxvYWREYXRhYC4gVGhlIGZ1bmN0aW9uIHJlY2VpdmVzIGEgZG9uZSBjYWxsYmFjayB0aGF0IG11c3QgYmUgY2FsbGVkIHdoZW4gaXQncyBmaW5pc2hlZC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fZGVyaXZlSG9va3MoKTtcblxuICAgIHRoaXMuX2RlZmF1bHRDbGFzc05hbWUgPSBkZWZhdWx0Q2xhc3NOYW1lO1xuICAgIHRoaXMuY2xhc3NMaXN0LmFkZChkZWZhdWx0Q2xhc3NOYW1lKTtcblxuICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuXG4gICAgICB0aGlzLl9pc1Nob3duID0gZmFsc2U7XG4gICAgICB0aGlzLl9jb250ZW50RWxlbWVudCA9IHRoaXMuX2dldENvbnRlbnRFbGVtZW50KCk7XG4gICAgICB0aGlzLl9iYWNrZ3JvdW5kRWxlbWVudCA9IHRoaXMuX2dldEJhY2tncm91bmRFbGVtZW50KCk7XG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIGNvbnN0IHRvb2xiYXIgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLXRvb2xiYXInKTtcblxuICAgIGNvbnN0IGJhY2tncm91bmQgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBhZ2VfX2JhY2tncm91bmQnKSB8fCB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLmJhY2tncm91bmQnKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBiYWNrZ3JvdW5kLmNsYXNzTGlzdC5hZGQoJ3BhZ2VfX2JhY2tncm91bmQnKTtcbiAgICB0aGlzLmluc2VydEJlZm9yZShiYWNrZ3JvdW5kLCAhdG9vbGJhciAmJiB0aGlzLmZpcnN0Q2hpbGQgfHwgdG9vbGJhciAmJiB0b29sYmFyLm5leHRTaWJsaW5nKTtcblxuICAgIGNvbnN0IGNvbnRlbnQgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBhZ2VfX2NvbnRlbnQnKSB8fCB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLmNvbnRlbnQnKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBjb250ZW50LmNsYXNzTGlzdC5hZGQoJ3BhZ2VfX2NvbnRlbnQnKTtcbiAgICBpZiAoIWNvbnRlbnQucGFyZW50RWxlbWVudCkge1xuICAgICAgdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZE5vZGVzKS5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gMSB8fCB0aGlzLl9lbGVtZW50U2hvdWxkQmVNb3ZlZChub2RlKSkge1xuICAgICAgICAgIGNvbnRlbnQuYXBwZW5kQ2hpbGQobm9kZSk7IC8vIENhbiB0cmlnZ2VyIGRldGFjaGVkIGNvbm5lY3RlZENhbGxiYWNrc1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl90cnlUb0ZpbGxTdGF0dXNCYXIoY29udGVudCk7IC8vIE11c3QgcnVuIGJlZm9yZSBjaGlsZCBwYWdlcyB0cnkgdG8gZmlsbCBzdGF0dXMgYmFyLlxuICAgIHRoaXMuaW5zZXJ0QmVmb3JlKGNvbnRlbnQsIGJhY2tncm91bmQubmV4dFNpYmxpbmcpOyAvLyBDYW4gdHJpZ2dlciBhdHRhY2hlZCBjb25uZWN0ZWRDYWxsYmFja3NcblxuICAgIGlmICgoIXRvb2xiYXIgfHwgIXV0aWwuaGFzTW9kaWZpZXIodG9vbGJhciwgJ3RyYW5zcGFyZW50JykpXG4gICAgICAmJiBjb250ZW50LmNoaWxkcmVuLmxlbmd0aCA9PT0gMVxuICAgICAgJiYgdXRpbC5pc1BhZ2VDb250cm9sKGNvbnRlbnQuY2hpbGRyZW5bMF0pXG4gICAgKSB7XG4gICAgICB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lICs9ICcgcGFnZS0td3JhcHBlcic7XG4gICAgICB0aGlzLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjaygnY2xhc3MnKTtcbiAgICB9XG5cbiAgICBjb25zdCBib3R0b21Ub29sYmFyID0gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1ib3R0b20tdG9vbGJhcicpO1xuICAgIGlmIChib3R0b21Ub29sYmFyKSB7XG4gICAgICB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lICs9ICcgcGFnZS13aXRoLWJvdHRvbS10b29sYmFyJztcbiAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdjbGFzcycpO1xuICAgIH1cblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIF9lbGVtZW50U2hvdWxkQmVNb3ZlZChlbCkge1xuICAgIGlmIChlbC5jbGFzc0xpc3QuY29udGFpbnMoJ3BhZ2VfX2JhY2tncm91bmQnKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCB0YWdOYW1lID0gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICh0YWdOYW1lID09PSAnb25zLWZhYicpIHtcbiAgICAgIHJldHVybiAhZWwuaGFzQXR0cmlidXRlKCdwb3NpdGlvbicpO1xuICAgIH1cbiAgICBjb25zdCBmaXhlZEVsZW1lbnRzID0gWydzY3JpcHQnLCAnb25zLXRvb2xiYXInLCAnb25zLWJvdHRvbS10b29sYmFyJywgJ29ucy1tb2RhbCcsICdvbnMtc3BlZWQtZGlhbCcsICdvbnMtZGlhbG9nJywgJ29ucy1hbGVydC1kaWFsb2cnLCAnb25zLXBvcG92ZXInLCAnb25zLWFjdGlvbi1zaGVldCddO1xuICAgIHJldHVybiBlbC5oYXNBdHRyaWJ1dGUoJ2lubGluZScpIHx8IGZpeGVkRWxlbWVudHMuaW5kZXhPZih0YWdOYW1lKSA9PT0gLTE7XG4gIH1cblxuICBfdHJ5VG9GaWxsU3RhdHVzQmFyKGNvbnRlbnQgPSB0aGlzLl9jb250ZW50RWxlbWVudCkge1xuICAgIGludGVybmFsLmF1dG9TdGF0dXNCYXJGaWxsKCgpID0+IHtcbiAgICAgIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdzdGF0dXMtYmFyLWZpbGwnLFxuICAgICAgICAhdXRpbC5maW5kUGFyZW50KHRoaXMsIGUgPT4gZS5oYXNBdHRyaWJ1dGUoJ3N0YXR1cy1iYXItZmlsbCcpKSAvLyBOb3QgYWxyZWFkeSBmaWxsZWRcbiAgICAgICAgJiYgKHRoaXMuX2NhbkFuaW1hdGVUb29sYmFyKGNvbnRlbnQpIHx8ICF1dGlsLmZpbmRDaGlsZChjb250ZW50LCB1dGlsLmlzUGFnZUNvbnRyb2wpKSAvLyBIYXMgdG9vbGJhciBvciBjYW5ub3QgZGVsZWdhdGVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBfY2FuQW5pbWF0ZVRvb2xiYXIoY29udGVudCA9IHRoaXMuX2NvbnRlbnRFbGVtZW50KSB7XG4gICAgaWYgKHV0aWwuZmluZENoaWxkKHRoaXMsICdvbnMtdG9vbGJhcicpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gISF1dGlsLmZpbmRDaGlsZChjb250ZW50LCBlbCA9PiB7XG4gICAgICByZXR1cm4gdXRpbC5tYXRjaChlbCwgJ29ucy10b29sYmFyJykgJiYgIWVsLmhhc0F0dHJpYnV0ZSgnaW5saW5lJyk7XG4gICAgfSk7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAoIXV0aWwuaXNBdHRhY2hlZCh0aGlzKSkgeyAvLyBBdm9pZCBkZXRhY2hlZCBjYWxsc1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl90cnlUb0ZpbGxTdGF0dXNCYXIoKTsgLy8gRW5zdXJlIHN0YXR1cyBiYXIgd2hlbiB0aGUgZWxlbWVudCB3YXMgY29tcGlsZWQgYmVmb3JlIGNvbm5lY3RlZFxuXG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ29uLWluZmluaXRlLXNjcm9sbCcpKSB7XG4gICAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdvbi1pbmZpbml0ZS1zY3JvbGwnLCBudWxsLCB0aGlzLmdldEF0dHJpYnV0ZSgnb24taW5maW5pdGUtc2Nyb2xsJykpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMub25Jbml0ICYmIHRoaXMub25Jbml0KCk7XG4gICAgICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdpbml0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghdXRpbC5oYXNBbnlDb21wb25lbnRBc1BhcmVudCh0aGlzKSkge1xuICAgICAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9zaG93KCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVCYWNrQnV0dG9uKHNob3cpIHtcbiAgICBpZiAodGhpcy5iYWNrQnV0dG9uKSB7XG4gICAgICBzaG93ID8gdGhpcy5iYWNrQnV0dG9uLnNob3coKSA6IHRoaXMuYmFja0J1dHRvbi5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgc2V0IG5hbWUoc3RyKSB7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBzdHIpO1xuICB9XG5cbiAgZ2V0IG5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCduYW1lJyk7XG4gIH1cblxuICBnZXQgYmFja0J1dHRvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCdvbnMtYmFjay1idXR0b24nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb25JbmZpbml0ZVNjcm9sbFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1GdW5jdGlvbiB0byBiZSBleGVjdXRlZCB3aGVuIHNjcm9sbGluZyB0byB0aGUgYm90dG9tIG9mIHRoZSBwYWdlLiBUaGUgZnVuY3Rpb24gcmVjZWl2ZXMgYSBkb25lIGNhbGxiYWNrIGFzIGFuIGFyZ3VtZW50IHRoYXQgbXVzdCBiZSBjYWxsZWQgd2hlbiBpdCdzIGZpbmlzaGVkLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG4gIHNldCBvbkluZmluaXRlU2Nyb2xsKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wib25JbmZpbml0ZVNjcm9sbFwiIG11c3QgYmUgZnVuY3Rpb24gb3IgbnVsbCcpO1xuICAgIH1cblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2NvbnRlbnRFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX2JvdW5kT25TY3JvbGwpO1xuICAgICAgfSBlbHNlIGlmICghdGhpcy5fb25JbmZpbml0ZVNjcm9sbCkge1xuICAgICAgICB0aGlzLl9pbmZpbml0ZVNjcm9sbExpbWl0ID0gMC45O1xuICAgICAgICB0aGlzLl9ib3VuZE9uU2Nyb2xsID0gdGhpcy5fb25TY3JvbGwuYmluZCh0aGlzKTtcbiAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHRoaXMuX2NvbnRlbnRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX2JvdW5kT25TY3JvbGwpKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX29uSW5maW5pdGVTY3JvbGwgPSB2YWx1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBvbkluZmluaXRlU2Nyb2xsKCkge1xuICAgIHJldHVybiB0aGlzLl9vbkluZmluaXRlU2Nyb2xsO1xuICB9XG5cbiAgX29uU2Nyb2xsKCkge1xuICAgIGNvbnN0IGMgPSB0aGlzLl9jb250ZW50RWxlbWVudCxcbiAgICAgIG92ZXJMaW1pdCA9IChjLnNjcm9sbFRvcCArIGMuY2xpZW50SGVpZ2h0KSAvIGMuc2Nyb2xsSGVpZ2h0ID49IHRoaXMuX2luZmluaXRlU2Nyb2xsTGltaXQ7XG5cbiAgICBpZiAodGhpcy5fb25JbmZpbml0ZVNjcm9sbCAmJiAhdGhpcy5fbG9hZGluZ0NvbnRlbnQgJiYgb3ZlckxpbWl0KSB7XG4gICAgICB0aGlzLl9sb2FkaW5nQ29udGVudCA9IHRydWU7XG4gICAgICB0aGlzLl9vbkluZmluaXRlU2Nyb2xsKCgpID0+IHRoaXMuX2xvYWRpbmdDb250ZW50ID0gZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb25EZXZpY2VCYWNrQnV0dG9uXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1CYWNrLWJ1dHRvbiBoYW5kbGVyLlsvZW5dXG4gICAqICAgW2phXeODkOODg+OCr+ODnOOCv+ODs+ODj+ODs+ODieODqeOAglsvamFdXG4gICAqL1xuICBnZXQgb25EZXZpY2VCYWNrQnV0dG9uKCkge1xuICAgIHJldHVybiB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlcjtcbiAgfVxuXG4gIHNldCBvbkRldmljZUJhY2tCdXR0b24oY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5fYmFja0J1dHRvbkhhbmRsZXIpIHtcbiAgICAgIHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlciA9IGRldmljZUJhY2tCdXR0b25EaXNwYXRjaGVyLmNyZWF0ZUhhbmRsZXIodGhpcywgY2FsbGJhY2spO1xuICB9XG5cbiAgZ2V0IHNjcm9sbFRvcCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuICB9XG5cbiAgc2V0IHNjcm9sbFRvcChuZXdWYWx1ZSkge1xuICAgIHRoaXMuX2NvbnRlbnRFbGVtZW50LnNjcm9sbFRvcCA9IG5ld1ZhbHVlO1xuICB9XG5cbiAgX2dldENvbnRlbnRFbGVtZW50KCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcucGFnZV9fY29udGVudCcpO1xuICAgIGlmIChyZXN1bHQpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHV0aWwudGhyb3coJ0ZhaWwgdG8gZ2V0IFwiLnBhZ2VfX2NvbnRlbnRcIiBlbGVtZW50Jyk7XG4gIH1cblxuICBfZ2V0QmFja2dyb3VuZEVsZW1lbnQoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gdXRpbC5maW5kQ2hpbGQodGhpcywgJy5wYWdlX19iYWNrZ3JvdW5kJyk7XG4gICAgaWYgKHJlc3VsdCkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgdXRpbC50aHJvdygnRmFpbCB0byBnZXQgXCIucGFnZV9fYmFja2dyb3VuZFwiIGVsZW1lbnQnKTtcbiAgfVxuXG4gIF9nZXRCb3R0b21Ub29sYmFyRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1ib3R0b20tdG9vbGJhcicpIHx8IGludGVybmFsLm51bGxFbGVtZW50O1xuICB9XG5cbiAgX2dldFRvb2xiYXJFbGVtZW50KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLXRvb2xiYXInKSB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdvbnMtdG9vbGJhcicpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnb24taW5maW5pdGUtc2Nyb2xsJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCB0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vZGlmaWVyJzpcbiAgICAgICAgTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnb24taW5maW5pdGUtc2Nyb2xsJzpcbiAgICAgICAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm9uSW5maW5pdGVTY3JvbGwgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMub25JbmZpbml0ZVNjcm9sbCA9IChkb25lKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmID0gdXRpbC5maW5kRnJvbVBhdGgoY3VycmVudCk7XG4gICAgICAgICAgICB0aGlzLm9uSW5maW5pdGVTY3JvbGwgPSBmO1xuICAgICAgICAgICAgZihkb25lKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIGlmICghdGhpcy5faXNTaG93biAmJiB1dGlsLmlzQXR0YWNoZWQodGhpcykpIHtcbiAgICAgIHRoaXMuX2lzU2hvd24gPSB0cnVlO1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoJ3Nob3duJywgJycpO1xuICAgICAgdGhpcy5vblNob3cgJiYgdGhpcy5vblNob3coKTtcbiAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAnc2hvdycpO1xuICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ19zaG93Jyk7XG4gICAgfVxuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24pIHtcbiAgICAgIHRoaXMuX2lzU2hvd24gPSBmYWxzZTtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKCdzaG93bicpO1xuICAgICAgdGhpcy5vbkhpZGUgJiYgdGhpcy5vbkhpZGUoKTtcbiAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAnaGlkZScpO1xuICAgICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ19oaWRlJyk7XG4gICAgfVxuICB9XG5cbiAgX2Rlc3Ryb3koKSB7XG4gICAgdGhpcy5faGlkZSgpO1xuXG4gICAgdGhpcy5vbkRlc3Ryb3kgJiYgdGhpcy5vbkRlc3Ryb3koKTtcbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ2Rlc3Ryb3knKTtcblxuICAgIGlmICh0aGlzLm9uRGV2aWNlQmFja0J1dHRvbikge1xuICAgICAgdGhpcy5vbkRldmljZUJhY2tCdXR0b24uZGVzdHJveSgpO1xuICAgIH1cblxuICAgIHV0aWwucHJvcGFnYXRlQWN0aW9uKHRoaXMsICdfZGVzdHJveScpO1xuXG4gICAgdGhpcy5yZW1vdmUoKTtcbiAgfVxuXG4gIF9kZXJpdmVIb29rcygpIHtcbiAgICB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGtleSA9ICdvbicgKyBldmVudC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGV2ZW50LnNsaWNlKDEpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGtleSwge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGdldDogKCkgPT4gdGhpc1tgXyR7a2V5fWBdLFxuICAgICAgICBzZXQ6IHZhbHVlID0+IHtcbiAgICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgICAgICAgdXRpbC50aHJvdyhgXCIke2tleX1cIiBob29rIG11c3QgYmUgYSBmdW5jdGlvbmApO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzW2BfJHtrZXl9YF0gPSB2YWx1ZS5iaW5kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ2luaXQnLCAnc2hvdycsICdoaWRlJywgJ2Rlc3Ryb3knXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGF0YVxuICAgKiBAdHlwZSB7Kn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVVzZXIncyBjdXN0b20gZGF0YSBwYXNzZWQgdG8gYHB1c2hQYWdlKClgLWxpa2UgbWV0aG9kcy5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuUGFnZSA9IFBhZ2VFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcGFnZScsIFBhZ2VFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IEJhc2VBbmltYXRvciBmcm9tICcuLi8uLi9vbnMvYmFzZS1hbmltYXRvcic7XG5cbmV4cG9ydCBjbGFzcyBQb3BvdmVyQW5pbWF0b3IgZXh0ZW5kcyBCYXNlQW5pbWF0b3Ige1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy50aW1pbmdcbiAgICogQHBhcmFtIHtOdW1iZXJ9IG9wdGlvbnMuZHVyYXRpb25cbiAgICogQHBhcmFtIHtOdW1iZXJ9IG9wdGlvbnMuZGVsYXlcbiAgICovXG4gIGNvbnN0cnVjdG9yKHt0aW1pbmcgPSAnY3ViaWMtYmV6aWVyKC4xLCAuNywgLjQsIDEpJywgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDAuMn0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gIH1cblxuICBzaG93KHBvcG92ZXIsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIGhpZGUocG9wb3ZlciwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG5cbiAgX2FuaW1hdGUoZWxlbWVudCwge2Zyb20sIHRvLCBvcHRpb25zLCBjYWxsYmFjaywgcmVzdG9yZSA9IGZhbHNlLCBhbmltYXRpb259KSB7XG4gICAgb3B0aW9ucyA9IHV0aWwuZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgaWYgKGFuaW1hdGlvbikge1xuICAgICAgZnJvbSA9IGFuaW1hdGlvbi5mcm9tO1xuICAgICAgdG8gPSBhbmltYXRpb24udG87XG4gICAgfVxuXG4gICAgYW5pbWF0aW9uID0gYW5pbWl0KGVsZW1lbnQpO1xuICAgIGlmIChyZXN0b3JlKSB7XG4gICAgICBhbmltYXRpb24gPSBhbmltYXRpb24uc2F2ZVN0eWxlKCk7XG4gICAgfVxuICAgIGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5xdWV1ZShmcm9tKS53YWl0KHRoaXMuZGVsYXkpLnF1ZXVlKHtcbiAgICAgIGNzczogdG8sXG4gICAgICBkdXJhdGlvbjogdGhpcy5kdXJhdGlvbixcbiAgICAgIHRpbWluZzogdGhpcy50aW1pbmdcbiAgICB9KTtcbiAgICBpZiAocmVzdG9yZSkge1xuICAgICAgYW5pbWF0aW9uID0gYW5pbWF0aW9uLnJlc3RvcmVTdHlsZSgpO1xuICAgIH1cbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIGFuaW1hdGlvbiA9IGFuaW1hdGlvbi5xdWV1ZSgoZG9uZSkgPT4ge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGFuaW1hdGlvbjtcbiAgfVxuXG4gIF9hbmltYXRlQWxsKGVsZW1lbnQsIGFuaW1hdGlvbnMpIHtcbiAgICBPYmplY3Qua2V5cyhhbmltYXRpb25zKS5mb3JFYWNoKGtleSA9PiB0aGlzLl9hbmltYXRlKGVsZW1lbnRba2V5XSwgYW5pbWF0aW9uc1trZXldKS5wbGF5KCkpO1xuICB9XG5cbn1cblxuY29uc3QgZmFkZSA9IHtcbiAgb3V0OiB7XG4gICAgZnJvbToge29wYWNpdHk6IDEuMH0sXG4gICAgdG86IHtvcGFjaXR5OiAwfVxuICB9LFxuICBpbjoge1xuICAgIGZyb206IHtvcGFjaXR5OiAwfSxcbiAgICB0bzoge29wYWNpdHk6IDEuMH1cbiAgfVxufTtcblxuZXhwb3J0IGNsYXNzIE1ERmFkZVBvcG92ZXJBbmltYXRvciBleHRlbmRzIFBvcG92ZXJBbmltYXRvciB7XG4gIHNob3cocG9wb3ZlciwgY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hbmltYXRlQWxsKHBvcG92ZXIsIHtcbiAgICAgIF9tYXNrOiBmYWRlLmluLFxuICAgICAgX3BvcG92ZXI6IHthbmltYXRpb246IGZhZGUuaW4sIHJlc3RvcmU6IHRydWUsIGNhbGxiYWNrfVxuICAgIH0pO1xuICB9XG5cbiAgaGlkZShwb3BvdmVyLCBjYWxsYmFjaykge1xuICAgIHRoaXMuX2FuaW1hdGVBbGwocG9wb3Zlciwge1xuICAgICAgX21hc2s6IGZhZGUub3V0LFxuICAgICAgX3BvcG92ZXI6IHthbmltYXRpb246IGZhZGUub3V0LCByZXN0b3JlOiB0cnVlLCBjYWxsYmFja31cbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSU9TRmFkZVBvcG92ZXJBbmltYXRvciBleHRlbmRzIE1ERmFkZVBvcG92ZXJBbmltYXRvciB7XG4gIHNob3cocG9wb3ZlciwgY2FsbGJhY2spIHtcbiAgICB0aGlzLl9hbmltYXRlQWxsKHBvcG92ZXIsIHtcbiAgICAgIF9tYXNrOiBmYWRlLmluLFxuICAgICAgX3BvcG92ZXI6IHtcbiAgICAgICAgZnJvbToge1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3NjYWxlM2QoMS4zLCAxLjMsIDEuMCknLFxuICAgICAgICAgIG9wYWNpdHk6IDBcbiAgICAgICAgfSxcbiAgICAgICAgdG86IHtcbiAgICAgICAgICB0cmFuc2Zvcm06ICdzY2FsZTNkKDEuMCwgMS4wLCAgMS4wKScsXG4gICAgICAgICAgb3BhY2l0eTogMS4wXG4gICAgICAgIH0sXG4gICAgICAgIHJlc3RvcmU6IHRydWUsXG4gICAgICAgIGNhbGxiYWNrXG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi8uLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi8uLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgeyBQb3BvdmVyQW5pbWF0b3IsIElPU0ZhZGVQb3BvdmVyQW5pbWF0b3IsIE1ERmFkZVBvcG92ZXJBbmltYXRvciB9IGZyb20gJy4vYW5pbWF0b3InO1xuaW1wb3J0IHBsYXRmb3JtIGZyb20gJy4uLy4uL29ucy9wbGF0Zm9ybSc7XG5pbXBvcnQgaVBob25lWFBhdGNoIGZyb20gJy4uLy4uL29ucy9pcGhvbmV4LXBhdGNoJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcucG9wb3Zlcic6ICdwb3BvdmVyLS0qJyxcbiAgJy5wb3BvdmVyLW1hc2snOiAncG9wb3Zlci1tYXNrLS0qJyxcbiAgJy5wb3BvdmVyX19jb250ZW50JzogJ3BvcG92ZXItLSpfX2NvbnRlbnQnLFxuICAnLnBvcG92ZXJfX2Fycm93JzogJ3BvcG92ZXItLSpfX2Fycm93J1xufTtcblxuY29uc3QgX2FuaW1hdG9yRGljdCA9IHtcbiAgJ2RlZmF1bHQnOiAoKSA9PiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IE1ERmFkZVBvcG92ZXJBbmltYXRvciA6IElPU0ZhZGVQb3BvdmVyQW5pbWF0b3IsXG4gICdub25lJzogUG9wb3ZlckFuaW1hdG9yLFxuICAnZmFkZS1pb3MnOiBJT1NGYWRlUG9wb3ZlckFuaW1hdG9yLFxuICAnZmFkZS1tZCc6IE1ERmFkZVBvcG92ZXJBbmltYXRvclxufTtcblxuY29uc3QgcG9zaXRpb25zID0ge1xuICB1cDogJ2JvdHRvbScsXG4gIGxlZnQ6ICdyaWdodCcsXG4gIGRvd246ICd0b3AnLFxuICByaWdodDogJ2xlZnQnXG59O1xuXG5jb25zdCBkaXJlY3Rpb25zID0gT2JqZWN0LmtleXMocG9zaXRpb25zKTtcbi8qKlxuICogQGVsZW1lbnQgb25zLXBvcG92ZXJcbiAqIEBjYXRlZ29yeSBkaWFsb2dcbiAqIEBkZXNjcmlwdGlvblxuICogIFtlbl1cbiAqICAgIEEgY29tcG9uZW50IHRoYXQgZGlzcGxheXMgYSBwb3BvdmVyIG5leHQgdG8gYW4gZWxlbWVudC4gVGhlIHBvcG92ZXIgY2FuIGJlIHVzZWQgdG8gZGlzcGxheSBleHRyYSBpbmZvcm1hdGlvbiBhYm91dCBhIGNvbXBvbmVudCBvciBhIHRvb2x0aXAuXG4gKlxuICogICAgVG8gdXNlIHRoZSBlbGVtZW50IGl0IGNhbiBlaXRoZXIgYmUgYXR0YWNoZWQgZGlyZWN0bHkgdG8gdGhlIGA8Ym9keT5gIGVsZW1lbnQgb3IgZHluYW1pY2FsbHkgY3JlYXRlZCBmcm9tIGEgdGVtcGxhdGUgdXNpbmcgdGhlIGBvbnMuY3JlYXRlUG9wb3Zlcih0ZW1wbGF0ZSlgIHV0aWxpdHkgZnVuY3Rpb24gYW5kIHRoZSBgPHRlbXBsYXRlPmAgdGFnLlxuICpcbiAqICAgIEFub3RoZXIgY29tbW9uIHdheSB0byB1c2UgdGhlIHBvcG92ZXIgaXMgdG8gZGlzcGxheSBhIG1lbnUgd2hlbiBhIGJ1dHRvbiBvbiB0aGUgc2NyZWVuIGlzIHRhcHBlZC4gRm9yIE1hdGVyaWFsIERlc2lnbiwgcG9wb3ZlciBsb29rcyBleGFjdGx5IGFzIGEgZHJvcGRvd24gbWVudS5cbiAqICBbL2VuXVxuICogIFtqYV3jgYLjgovopoHntKDjgpLlr77osaHjgajjgZnjgovjg53jg4Pjg5fjgqrjg7zjg5Djg7zjgpLooajnpLrjgZnjgovjgrPjg7Pjg53jg7zjg43jg7Pjg4jjgafjgZnjgIJbL2phXVxuICogQGNvZGVwZW4gWllZUktvXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvcG9wb3ZlclxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNtb2RpZmllcnMgW2VuXU1vcmUgZGV0YWlscyBhYm91dCB0aGUgYG1vZGlmaWVyYCBhdHRyaWJ1dGVbL2VuXVtqYV1tb2RpZmllcuWxnuaAp+OBruS9v+OBhOaWuVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1idXR0b24gb25jbGljaz1cInNob3dQb3BvdmVyKHRoaXMpXCI+XG4gKiAgIENsaWNrIG1lIVxuICogPC9vbnMtYnV0dG9uPlxuICpcbiAqIDxvbnMtcG9wb3ZlciBkaXJlY3Rpb249XCJkb3duXCIgaWQ9XCJwb3BvdmVyXCI+XG4gKiAgIDxwPlRoaXMgaXMgYSBwb3BvdmVyITwvcD5cbiAqIDwvb25zLXBvcG92ZXI+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgdmFyIHNob3dQb3BvdmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICogICAgIHZhciBwb3BvdmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3BvcG92ZXInKTtcbiAqICAgICBwb3BvdmVyLnNob3coZWxlbWVudCk7XG4gKiAgIH07XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9wb3ZlckVsZW1lbnQgZXh0ZW5kcyBCYXNlRGlhbG9nRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGJlZm9yZSB0aGUgcG9wb3ZlciBpcyBkaXNwbGF5ZWQuWy9lbl1cbiAgICogICBbamFd44Od44OD44OX44Kq44O844OQ44O844GM6KGo56S644GV44KM44KL55u05YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LnBvcG92ZXJcbiAgICogICBbZW5dQ29tcG9uZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7jgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBldmVudC5jYW5jZWxcbiAgICogICBbZW5dQ2FsbCB0aGlzIGZ1bmN0aW9uIHRvIHN0b3AgdGhlIHBvcG92ZXIgZnJvbSBiZWluZyBzaG93bi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7plqLmlbDjgpLlkbzjgbPlh7rjgZnjgajjgIHjg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7ooajnpLrjgYzjgq3jg6Pjg7Pjgrvjg6vjgZXjgozjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RzaG93XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBwb3BvdmVyIGlzIGRpc3BsYXllZC5bL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzooajnpLrjgZXjgozjgZ/nm7TlvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQucG9wb3ZlclxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcHJlaGlkZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIHBvcG92ZXIgaXMgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeODneODg+ODl+OCquODvOODkOODvOOBjOmaoOOCjOOCi+ebtOWJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5wb3BvdmVyXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUNhbGwgdGhpcyBmdW5jdGlvbiB0byBzdG9wIHRoZSBwb3BvdmVyIGZyb20gYmVpbmcgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeOBk+OBrumWouaVsOOCkuWRvOOBs+WHuuOBmeOBqOOAgeODneODg+ODl+OCquODvOODkOODvOOBjOmaoOOCjOOCi+WHpueQhuOCkuOCreODo+ODs+OCu+ODq+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcG9zdGhpZGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYWZ0ZXIgdGhlIHBvcG92ZXIgaXMgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXeODneODg+ODl+OCquODvOODkOODvOOBjOmaoOOCjOOBn+W+jOOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5wb3BvdmVyXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHBvcG92ZXIuWy9lbl1cbiAgICogIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXJlY3Rpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dXG4gICAqICAgIEEgc3BhY2Ugc2VwYXJhdGVkIGxpc3Qgb2YgZGlyZWN0aW9ucy4gSWYgbW9yZSB0aGFuIG9uZSBkaXJlY3Rpb24gaXMgc3BlY2lmaWVkLFxuICAgKiAgICBpdCB3aWxsIGJlIGNob3NlbiBhdXRvbWF0aWNhbGx5LiBWYWxpZCBkaXJlY3Rpb25zIGFyZSBgXCJ1cFwiYCwgYFwiZG93blwiYCwgYFwibGVmdFwiYCBhbmQgYFwicmlnaHRcImAuXG4gICAqICBbL2VuXVxuICAgKiAgW2phXVxuICAgKiAgICDjg53jg4Pjg5fjgqrjg7zjg5Djg7zjgpLooajnpLrjgZnjgovmlrnlkJHjgpLnqbrnmb3ljLrliIfjgorjgafopIfmlbDmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICAg5oyH5a6a44Gn44GN44KL5pa55ZCR44Gv44CBXCJ1cFwiLCBcImRvd25cIiwgXCJsZWZ0XCIsIFwicmlnaHRcIuOBrjTjgaTjgafjgZnjgILnqbrnmb3ljLrliIfjgorjgafopIfmlbDmjIflrprjgZnjgovjgZPjgajjgoLjgafjgY3jgb7jgZnjgIJcbiAgICogICAg6KSH5pWw5oyH5a6a44GV44KM44Gf5aC05ZCI44CB5a++6LGh44Go44GZ44KL6KaB57Sg44Gr5ZCI44KP44Gb44Gm5oyH5a6a44GX44Gf5YCk44GL44KJ6Ieq5YuV55qE44Gr6YG45oqe44GV44KM44G+44GZ44CCXG4gICAqICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjYW5jZWxhYmxlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIHBvcG92ZXIgY2FuIGJlIGNsb3NlZCBieSB0YXBwaW5nIHRoZSBiYWNrZ3JvdW5kIG9yIGJ5IHByZXNzaW5nIHRoZSBiYWNrIGJ1dHRvbi5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovjgajjgIHjg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzooajnpLrjgZXjgozjgZ/mmYLjgavjgIHog4zmma/jgoTjg5Djg4Pjgq/jg5zjgr/jg7PjgpLjgr/jg4Pjg5fjgZfjgZ/mmYLjgavjgpLjg53jg4Pjg5fjgqrjg7zjg5Djg7zplonjgZjjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjb3Zlci10YXJnZXRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHNldCB0aGUgcG9wb3ZlciB3aWxsIGNvdmVyIHRoZSB0YXJnZXQgb24gdGhlIHNjcmVlbi5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhbmltYXRpb24gdXNlZCB3aGVuIHNob3dpbmcgYW4gaGlkaW5nIHRoZSBwb3BvdmVyLiBDYW4gYmUgZWl0aGVyIGBcIm5vbmVcImAsIGBcImRlZmF1bHRcImAsIGBcImZhZGUtaW9zXCJgIG9yIGBcImZhZGUtbWRcImAuWy9lbl1cbiAgICogICBbamFd44Od44OD44OX44Kq44O844OQ44O844KS6KGo56S644GZ44KL6Zqb44Gu44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1hc2stY29sb3JcbiAgICogQHR5cGUge0NvbG9yfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ29sb3Igb2YgdGhlIGJhY2tncm91bmQgbWFzay4gRGVmYXVsdCBpcyBgXCJyZ2JhKDAsIDAsIDAsIDAuMilcImAuWy9lbl1cbiAgICogICBbamFd6IOM5pmv44Gu44Oe44K544Kv44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CC44OH44OV44Kp44Or44OI44GvXCJyZ2JhKDAsIDAsIDAsIDAuMilcIuOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9ib3VuZE9uQ2hhbmdlID0gdGhpcy5fb25DaGFuZ2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKCk7XG4gICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgX3NjaGVtZSgpIHtcbiAgICByZXR1cm4gc2NoZW1lO1xuICB9XG5cbiAgZ2V0IF9tYXNrKCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBvcG92ZXItbWFzaycpO1xuICB9XG5cbiAgZ2V0IF9wb3BvdmVyKCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnBvcG92ZXInKTtcbiAgfVxuXG4gIGdldCBfY29udGVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcy5fcG9wb3ZlciwgJy5wb3BvdmVyX19jb250ZW50Jyk7XG4gIH1cblxuICBnZXQgX2Fycm93KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLl9wb3BvdmVyLCAnLnBvcG92ZXJfX2Fycm93Jyk7XG4gIH1cblxuICBfdXBkYXRlQW5pbWF0b3JGYWN0b3J5KCkge1xuICAgIHJldHVybiBuZXcgQW5pbWF0b3JGYWN0b3J5KHtcbiAgICAgIGFuaW1hdG9yczogX2FuaW1hdG9yRGljdCxcbiAgICAgIGJhc2VDbGFzczogUG9wb3ZlckFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ1BvcG92ZXJBbmltYXRvcicsXG4gICAgICBkZWZhdWx0QW5pbWF0aW9uOiB0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uJykgfHwgJ2RlZmF1bHQnXG4gICAgfSk7XG4gIH1cblxuICBfdG9nZ2xlU3R5bGUoc2hvdWxkU2hvdywgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHNob3VsZFNob3cpIHtcbiAgICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICB0aGlzLl9jdXJyZW50VGFyZ2V0ID0gb3B0aW9ucy50YXJnZXQ7XG4gICAgICB0aGlzLl9wb3NpdGlvblBvcG92ZXIob3B0aW9ucy50YXJnZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB0aGlzLl9jbGVhclN0eWxlcygpO1xuICAgIH1cbiAgfVxuXG4gIF9wb3NpdGlvblBvcG92ZXIodGFyZ2V0KSB7XG4gICAgY29uc3Qge19yYWRpdXM6IHJhZGl1cywgX2NvbnRlbnQ6IGNvbnRlbnRFbGVtZW50LCBfbWFyZ2luOiBtYXJnaW59ID0gdGhpcztcbiAgICBjb25zdCBzYWZlQXJlYUxlbmd0aHMgPSBpUGhvbmVYUGF0Y2guZ2V0U2FmZUFyZWFMZW5ndGhzKCk7XG4gICAgY29uc3Qgc2FmZUFyZWFSZWN0ID0gaVBob25lWFBhdGNoLmdldFNhZmVBcmVhRE9NUmVjdCgpO1xuICAgIGNvbnN0IHRhcmdldFJlY3QgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgaXNNRCA9IHV0aWwuaGFzTW9kaWZpZXIodGhpcywgJ21hdGVyaWFsJyk7XG4gICAgY29uc3QgY292ZXIgPSBpc01EICYmIHRoaXMuaGFzQXR0cmlidXRlKCdjb3Zlci10YXJnZXQnKTtcbiAgICBjb25zdCBwYXJlbnQgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1wYWdlJykgfHwgZG9jdW1lbnQuYm9keTtcbiAgICBjb25zdCBwYXJlbnREaW1lbnNpb25zID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IG1heFBvc2l0aW9ucyA9IHtcbiAgICAgIHRvcDogTWF0aC5tYXgocGFyZW50RGltZW5zaW9ucy50b3AsIHNhZmVBcmVhUmVjdC50b3ApLFxuICAgICAgbGVmdDogTWF0aC5tYXgocGFyZW50RGltZW5zaW9ucy5sZWZ0LCBzYWZlQXJlYVJlY3QubGVmdCksXG4gICAgICBib3R0b206IE1hdGgubWluKHBhcmVudERpbWVuc2lvbnMuYm90dG9tLCBzYWZlQXJlYVJlY3QuYm90dG9tKSxcbiAgICAgIHJpZ2h0OiBNYXRoLm1pbihwYXJlbnREaW1lbnNpb25zLnJpZ2h0LCBzYWZlQXJlYVJlY3QucmlnaHQpLFxuICAgIH07XG5cbiAgICAvLyBEaXN0YW5jZSBmcm9tIGVhY2ggc2lkZSBvZiB0aGUgc2FmZSBhcmVhICh3aXRoIG1hcmdpbikgdG8gdGhlIHRhcmdldCBlbGVtZW50XG4gICAgY29uc3QgdGFyZ2V0RGlzdGFuY2UgPSB7XG4gICAgICB0b3A6IHRhcmdldFJlY3QudG9wIC0gKG1heFBvc2l0aW9ucy50b3AgKyBtYXJnaW4pLFxuICAgICAgbGVmdDogdGFyZ2V0UmVjdC5sZWZ0IC0gKG1heFBvc2l0aW9ucy5sZWZ0ICsgbWFyZ2luKSxcbiAgICAgIGJvdHRvbTogKG1heFBvc2l0aW9ucy5ib3R0b20gLSBtYXJnaW4pIC0gdGFyZ2V0UmVjdC5ib3R0b20sXG4gICAgICByaWdodDogKG1heFBvc2l0aW9ucy5yaWdodCAtIG1hcmdpbikgLSB0YXJnZXRSZWN0LnJpZ2h0XG4gICAgfTtcblxuICAgIC8vIERpc3RhbmNlIGZyb20gZWFjaCBzaWRlIG9mIHRoZSBzYWZlIGFyZWEgKHdpdGggbWFyZ2luKSB0byB0aGUgZ2VvbWV0cmljIGNlbnRlciBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICBjb25zdCB0YXJnZXRDZW50ZXJEaXN0YW5jZUZyb20gPSB7XG4gICAgICB0b3A6IHRhcmdldFJlY3QudG9wICsgTWF0aC5yb3VuZCh0YXJnZXRSZWN0LmhlaWdodCAvIDIpIC0gKG1heFBvc2l0aW9ucy50b3AgKyBtYXJnaW4pLFxuICAgICAgbGVmdDogdGFyZ2V0UmVjdC5sZWZ0ICsgTWF0aC5yb3VuZCh0YXJnZXRSZWN0LndpZHRoIC8gMikgLSAobWF4UG9zaXRpb25zLmxlZnQgKyBtYXJnaW4pLFxuICAgICAgYm90dG9tOiAobWF4UG9zaXRpb25zLmJvdHRvbSAtIG1hcmdpbikgLSB0YXJnZXRSZWN0LmJvdHRvbSArIE1hdGgucm91bmQodGFyZ2V0UmVjdC5oZWlnaHQgLyAyKSxcbiAgICAgIHJpZ2h0OiAobWF4UG9zaXRpb25zLnJpZ2h0IC0gbWFyZ2luKSAtIHRhcmdldFJlY3QucmlnaHQgKyBNYXRoLnJvdW5kKHRhcmdldFJlY3Qud2lkdGggLyAyKVxuICAgIH07XG5cbiAgICBjb25zdCB7dmVydGljYWwsIHByaW1hcnk6IHByaW1hcnlEaXJlY3Rpb24sIHNlY29uZGFyeTogc2Vjb25kYXJ5RGlyZWN0aW9ufSA9IHRoaXMuX2NhbGN1bGF0ZURpcmVjdGlvbnModGFyZ2V0RGlzdGFuY2UpO1xuICAgIHRoaXMuX2N1cnJlbnREaXJlY3Rpb24gPSBwcmltYXJ5RGlyZWN0aW9uO1xuICAgIHV0aWwuYWRkTW9kaWZpZXIodGhpcywgcHJpbWFyeURpcmVjdGlvbik7XG5cbiAgICBjb25zdCBzaXplTmFtZSA9IHZlcnRpY2FsID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICAgIC8vIEdldCAucG9wb3Zlcl9fY29udGVudCBzaXplXG4gICAgY29uc3QgY29udGVudFNpemUgPSAoc3R5bGUgPT4gKHtcbiAgICAgIHdpZHRoOiBwYXJzZUludChzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpLCAxMCksXG4gICAgICBoZWlnaHQ6IHBhcnNlSW50KHN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2hlaWdodCcpLCAxMClcbiAgICB9KSkod2luZG93LmdldENvbXB1dGVkU3R5bGUoY29udGVudEVsZW1lbnQpKTtcblxuICAgIC8vIFNldHRpbmcgLnBvcG92ZXIgcG9zaXRpb24uXG4gICAgY29uc3QgdGFyZ2V0QW5kQXJyb3dMZW5ndGggPSBjb3ZlciA/IDAgOiAodmVydGljYWwgPyB0YXJnZXRSZWN0LmhlaWdodCA6IHRhcmdldFJlY3Qud2lkdGgpICsgKGlzTUQgPyAwIDogMTQpO1xuICAgIGNvbnN0IHByaW1hcnlPZmZzZXQgPSBNYXRoLm1heChcbiAgICAgIHNhZmVBcmVhTGVuZ3Roc1twcmltYXJ5RGlyZWN0aW9uXSArIG1hcmdpbixcbiAgICAgIHNhZmVBcmVhTGVuZ3Roc1twcmltYXJ5RGlyZWN0aW9uXSArIG1hcmdpbiArIHRhcmdldERpc3RhbmNlW3ByaW1hcnlEaXJlY3Rpb25dICsgdGFyZ2V0QW5kQXJyb3dMZW5ndGhcbiAgICApO1xuICAgIGNvbnN0IHNlY29uZGFyeU9mZnNldCA9IE1hdGgubWF4KFxuICAgICAgc2FmZUFyZWFMZW5ndGhzW3NlY29uZGFyeURpcmVjdGlvbl0gKyBtYXJnaW4sXG4gICAgICBzYWZlQXJlYUxlbmd0aHNbc2Vjb25kYXJ5RGlyZWN0aW9uXSArIG1hcmdpbiArIHRhcmdldENlbnRlckRpc3RhbmNlRnJvbVtzZWNvbmRhcnlEaXJlY3Rpb25dIC0gKGNvbnRlbnRTaXplW3NpemVOYW1lXSAvIDIpXG4gICAgKTtcbiAgICB0aGlzLl9wb3BvdmVyLnN0eWxlW3ByaW1hcnlEaXJlY3Rpb25dID0gcHJpbWFyeU9mZnNldCArICdweCc7XG4gICAgdGhpcy5fcG9wb3Zlci5zdHlsZVtzZWNvbmRhcnlEaXJlY3Rpb25dID0gc2Vjb25kYXJ5T2Zmc2V0ICsgJ3B4JztcblxuICAgIC8vIFNldHRpbmcgLnBvcG92ZXJfX2Fycm93IHBvc2l0aW9uLlxuICAgIHRoaXMuX2Fycm93LnN0eWxlW3NlY29uZGFyeURpcmVjdGlvbl0gPSBNYXRoLm1heChcbiAgICAgIHJhZGl1cyxcbiAgICAgIChzYWZlQXJlYUxlbmd0aHNbc2Vjb25kYXJ5RGlyZWN0aW9uXSArIG1hcmdpbikgKyB0YXJnZXRDZW50ZXJEaXN0YW5jZUZyb21bc2Vjb25kYXJ5RGlyZWN0aW9uXSAtIHNlY29uZGFyeU9mZnNldFxuICAgICkgKyAncHgnO1xuICB9XG5cbiAgX2NhbGN1bGF0ZURpcmVjdGlvbnMoZGlzdGFuY2UpIHtcbiAgICBjb25zdCBvcHRpb25zID0gKHRoaXMuZ2V0QXR0cmlidXRlKCdkaXJlY3Rpb24nKSB8fCAndXAgZG93biBsZWZ0IHJpZ2h0Jykuc3BsaXQoL1xccysvKS5tYXAoZSA9PiBwb3NpdGlvbnNbZV0pO1xuICAgIGNvbnN0IHByaW1hcnkgPSBvcHRpb25zLnNvcnQoKGEsIGIpID0+IGRpc3RhbmNlW2FdIC0gZGlzdGFuY2VbYl0pWzBdO1xuICAgIGNvbnN0IHZlcnRpY2FsID0gJ3RvcCcgPT0gcHJpbWFyeSB8fCAnYm90dG9tJyA9PSBwcmltYXJ5O1xuICAgIGxldCBzZWNvbmRhcnk7XG5cbiAgICBpZiAodmVydGljYWwpIHtcbiAgICAgIHNlY29uZGFyeSA9IGRpc3RhbmNlLmxlZnQgPCBkaXN0YW5jZS5yaWdodCA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlY29uZGFyeSA9IGRpc3RhbmNlLnRvcCA8IGRpc3RhbmNlLmJvdHRvbSA/ICd0b3AnIDogJ2JvdHRvbSc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHt2ZXJ0aWNhbCwgcHJpbWFyeSwgc2Vjb25kYXJ5fTtcbiAgfVxuXG4gIF9jbGVhclN0eWxlcygpIHtcbiAgICB0aGlzLl9jdXJyZW50RGlyZWN0aW9uID0gbnVsbDtcbiAgICBbJ3RvcCcsICdib3R0b20nLCAnbGVmdCcsICdyaWdodCddLmZvckVhY2goZSA9PiB7XG4gICAgICB0aGlzLl9hcnJvdy5zdHlsZVtlXSA9IHRoaXMuX2NvbnRlbnQuc3R5bGVbZV0gPSB0aGlzLl9wb3BvdmVyLnN0eWxlW2VdID0gJyc7XG4gICAgICB1dGlsLnJlbW92ZU1vZGlmaWVyKHRoaXMsIGUpO1xuICAgIH0pO1xuICB9XG5cbiAgX29uQ2hhbmdlKCkge1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fY3VycmVudFRhcmdldCkge1xuICAgICAgICB0aGlzLl9wb3NpdGlvblBvcG92ZXIodGhpcy5fY3VycmVudFRhcmdldCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIGlmICh0aGlzLl9wb3BvdmVyICYmIHRoaXMuX21hc2spIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNEZWZhdWx0Q29udGFpbmVyID0gdGhpcy5fcG9wb3ZlciAmJiB0aGlzLl9jb250ZW50O1xuXG4gICAgaWYgKGhhc0RlZmF1bHRDb250YWluZXIpIHtcblxuICAgICAgaWYgKCF0aGlzLl9tYXNrKSB7XG4gICAgICAgIGNvbnN0IG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgbWFzay5jbGFzc0xpc3QuYWRkKCdwb3BvdmVyLW1hc2snKTtcbiAgICAgICAgdGhpcy5pbnNlcnRCZWZvcmUobWFzaywgdGhpcy5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLl9hcnJvdykge1xuICAgICAgICBjb25zdCBhcnJvdyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBhcnJvdy5jbGFzc0xpc3QuYWRkKCdwb3BvdmVyX19hcnJvdycpO1xuICAgICAgICB0aGlzLl9wb3BvdmVyLmFwcGVuZENoaWxkKGFycm93KTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gdXRpbC5jcmVhdGVGcmFnbWVudChgXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwb3BvdmVyLW1hc2tcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBvcG92ZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9wb3Zlcl9fY29udGVudFwiPjwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwb3BvdmVyX19hcnJvd1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIGApO1xuICAgICAgY29uc3QgY29udGVudCA9IHRlbXBsYXRlLnF1ZXJ5U2VsZWN0b3IoJy5wb3BvdmVyX19jb250ZW50Jyk7XG5cbiAgICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgICAgY29udGVudC5hcHBlbmRDaGlsZCh0aGlzLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFwcGVuZENoaWxkKHRlbXBsYXRlKTtcbiAgICB9XG5cbiAgICAvLyBGSVhNRSFcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ3N0eWxlJykpIHtcbiAgICAgIHRoaXMuX3BvcG92ZXIuc2V0QXR0cmlidXRlKCdzdHlsZScsIHRoaXMuZ2V0QXR0cmlidXRlKCdzdHlsZScpKTtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuICAgIH1cblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgdGhpcy5fc2NoZW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dcbiAgICogQHNpZ25hdHVyZSBzaG93KHRhcmdldCwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge1N0cmluZ3xFdmVudHxIVE1MRWxlbWVudH0gdGFyZ2V0XG4gICAqICAgW2VuXVRhcmdldCBlbGVtZW50LiBDYW4gYmUgZWl0aGVyIGEgQ1NTIHNlbGVjdG9yLCBhbiBldmVudCBvYmplY3Qgb3IgYSBET00gZWxlbWVudC4gSXQgY2FuIGJlIGFsc28gcHJvdmlkZWQgYXMgJ29wdGlvbnMudGFyZ2V0JyBpbnN0ZWFkLiBbL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjga7jgr/jg7zjgrLjg4Pjg4jjgajjgarjgovopoHntKDjgpLmjIflrprjgZfjgb7jgZnjgIJDU1Pjgrvjg6zjgq/jgr/jgYtldmVudOOCquODluOCuOOCp+OCr+ODiOOBi0RPTeimgee0oOOBruOBhOOBmuOCjOOBi+OCkua4oeOBm+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gIFVzZSBvbmUgb2YgYFwiZmFkZS1pb3NcImAsIGBcImZhZGUtbWRcImAsIGBcIm5vbmVcImAgYW5kIGBcImRlZmF1bHRcImAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCXCJmYWRlLWlvc1wiLCBcImZhZGUtbWRcIiwgXCJub25lXCIsIFwiZGVmYXVsdFwi44Gu44GE44Ga44KM44GL44KS5oyH5a6a44Gn44GN44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiAgIFtlbl1UaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgcG9wb3ZlciBoYXMgYmVlbiByZXZlYWxlZC5bL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzooajnpLrjgZXjgozntYLjgo/jgaPjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dT3BlbiB0aGUgcG9wb3ZlciBhbmQgcG9pbnQgaXQgYXQgYSB0YXJnZXQuIFRoZSB0YXJnZXQgY2FuIGJlIGVpdGhlciBhbiBldmVudCwgYSBDU1Mgc2VsZWN0b3Igb3IgYSBET00gZWxlbWVudC4uWy9lbl1cbiAgICogICBbamFd5a++6LGh44Go44GZ44KL6KaB57Sg44Gr44Od44OD44OX44Kq44O844OQ44O844KS6KGo56S644GX44G+44GZ44CCdGFyZ2V05byV5pWw44Gr44Gv44CBJGV2ZW5044Kq44OW44K444Kn44Kv44OI44KERE9N44Ko44Os44Oh44Oz44OI44KEQ1NT44K744Os44Kv44K/44KS5rih44GZ44GT44Go44GM5Ye65p2l44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNob3codGFyZ2V0LCBvcHRpb25zID0ge30pIHtcbiAgICAvLyBDb3B5IG9wdGlvbnMgYW5kIGluY2x1ZGUgb3B0aW9ucy50YXJnZXRcbiAgICBpZiAodGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnICYmICEodGFyZ2V0IGluc3RhbmNlb2YgRXZlbnQpICYmICEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICBvcHRpb25zID0geyAuLi50YXJnZXQgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucywgdGFyZ2V0IH07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnRhcmdldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMudGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihvcHRpb25zLnRhcmdldCk7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLnRhcmdldCBpbnN0YW5jZW9mIEV2ZW50KSB7XG4gICAgICBvcHRpb25zLnRhcmdldCA9IG9wdGlvbnMudGFyZ2V0LnRhcmdldDtcbiAgICB9XG5cbiAgICBpZiAoIShvcHRpb25zLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICB1dGlsLnRocm93KCdJbnZhbGlkIHRhcmdldCB0eXBlIG9yIHVuZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5zaG93KG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuICBVc2Ugb25lIG9mIGBcImZhZGUtaW9zXCJgLCBgXCJmYWRlLW1kXCJgLCBgXCJub25lXCJgIGFuZCBgXCJkZWZhdWx0XCJgLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+WQjeOCkuaMh+WumuOBl+OBvuOBmeOAglwiZmFkZS1pb3NcIiwgXCJmYWRlLW1kXCIsIFwibm9uZVwiLCBcImRlZmF1bHRcIuOBruOBhOOBmuOCjOOBi+OCkuaMh+WumuOBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbnMgaXMgY2FsbGVkIGFmdGVyIHRoZSBwb3BvdmVyIGhhcyBiZWVuIGhpZGRlbi5bL2VuXVxuICAgKiAgIFtqYV3jg53jg4Pjg5fjgqrjg7zjg5Djg7zjgYzpmqDjgozjgZ/lvozjgavlkbzjgbPlh7rjgZXjgozjgovplqLmlbDjgqrjg5bjgrjjgqfjgq/jg4jjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ2xvc2UgdGhlIHBvcG92ZXIuWy9lbl1cbiAgICogICBbamFd44Od44OD44OX44Kq44O844OQ44O844KS6ZaJ44GY44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGhpZGRlbiBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjYW5jZWxhYmxlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBBIGJvb2xlYW4gdmFsdWUgdGhhdCBzcGVjaWZpZXMgd2hldGhlciB0aGUgcG9wb3ZlciBpcyBjYW5jZWxhYmxlIG9yIG5vdC5cbiAgICpcbiAgICogICAgIFdoZW4gdGhlIHBvcG92ZXIgaXMgY2FuY2VsYWJsZSBpdCBjYW4gYmUgY2xvc2VkIGJ5IHRhcHBpbmcgdGhlIGJhY2tncm91bmQgb3IgYnkgcHJlc3NpbmcgdGhlIGJhY2sgYnV0dG9uIG9uIEFuZHJvaWQgZGV2aWNlcy5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuX2JvdW5kT25DaGFuZ2UsIGZhbHNlKTtcbiAgICB0aGlzLl9tYXJnaW4gPSB0aGlzLl9tYXJnaW4gfHwgcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcykuZ2V0UHJvcGVydHlWYWx1ZSgndG9wJykpO1xuICAgIHRoaXMuX21hcmdpbiA9IHRoaXMuX21hcmdpbiB8fCA2OyAvLyBGaXggZm9yIGlmcmFtZXNcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9yYWRpdXMgPSBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLl9jb250ZW50KS5nZXRQcm9wZXJ0eVZhbHVlKCdib3JkZXItdG9wLWxlZnQtcmFkaXVzJykpO1xuICAgIH0pO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc3VwZXIuZGlzY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fYm91bmRPbkNoYW5nZSwgZmFsc2UpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsuLi5zdXBlci5vYnNlcnZlZEF0dHJpYnV0ZXMsICdkaXJlY3Rpb24nXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdkaXJlY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYm91bmRPbkNoYW5nZSgpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ21vZGlmaWVyJykge1xuICAgICAgdGhpcy5fY3VycmVudERpcmVjdGlvbiAmJiB1dGlsLmFkZE1vZGlmaWVyKHRoaXMsIHRoaXMuX2N1cnJlbnREaXJlY3Rpb24pO1xuICAgIH1cbiAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtQb3BvdmVyQW5pbWF0b3J9IEFuaW1hdG9yXG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yLnByb3RvdHlwZSBpbnN0YW5jZW9mIFBvcG92ZXJBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignUG9wb3ZlcicpO1xuICAgIH1cbiAgICBfYW5pbWF0b3JEaWN0W25hbWVdID0gQW5pbWF0b3I7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGFuaW1hdG9ycygpIHtcbiAgICByZXR1cm4gX2FuaW1hdG9yRGljdDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgUG9wb3ZlckFuaW1hdG9yKCkge1xuICAgIHJldHVybiBQb3BvdmVyQW5pbWF0b3I7XG4gIH1cbn1cblxub25zRWxlbWVudHMuUG9wb3ZlciA9IFBvcG92ZXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcG9wb3ZlcicsIFBvcG92ZXJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5wcm9ncmVzcy1iYXInOiAncHJvZ3Jlc3MtYmFyLS0qJyxcbiAgJy5wcm9ncmVzcy1iYXJfX3ByaW1hcnknOiAncHJvZ3Jlc3MtYmFyLS0qX19wcmltYXJ5JyxcbiAgJy5wcm9ncmVzcy1iYXJfX3NlY29uZGFyeSc6ICdwcm9ncmVzcy1iYXItLSpfX3NlY29uZGFyeSdcbn07XG5cbmNvbnN0IHRlbXBsYXRlID0gdXRpbC5jcmVhdGVFbGVtZW50KGBcbiAgPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhclwiPlxuICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1iYXJfX3NlY29uZGFyeVwiPjwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1iYXJfX3ByaW1hcnlcIj48L2Rpdj5cbiAgPC9kaXY+XG5gKTtcblxuY29uc3QgSU5ERVQgPSAnaW5kZXRlcm1pbmF0ZSc7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXByb2dyZXNzLWJhclxuICogQGNhdGVnb3J5IHZpc3VhbFxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1EaXNwbGF5IGEgTWF0ZXJpYWwgRGVzaWduIHByb2dyZXNzIGJhci5bL2VuXVxuICogICBbamFd44Oe44OG44Oq44Ki44Or44OH44K244Kk44Oz44Gu44K544K/44Kk44Or44Gn44OX44Ot44Kw44Os44K544OQ44O844KS6KGo56S644GX44G+44GZ44CCWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhlIGNvbXBvbmVudCBpcyB1c2VkIHRvIGRpc3BsYXkgYSBsaW5lYXIgcHJvZ3Jlc3MgYmFyLiBJdCBjYW4gZWl0aGVyIGRpc3BsYXkgYSBwcm9ncmVzcyBiYXIgdGhhdCBzaG93cyB0aGUgdXNlciBob3cgbXVjaCBvZiBhIHRhc2sgaGFzIGJlZW4gY29tcGxldGVkLiBJbiB0aGUgY2FzZSB3aGVyZSB0aGUgcGVyY2VudGFnZSBpcyBub3Qga25vd24gaXQgY2FuIGJlIHVzZWQgdG8gZGlzcGxheSBhbiBhbmltYXRlZCBwcm9ncmVzcyBiYXIgc28gdGhlIHVzZXIgY2FuIHNlZSB0aGF0IGFuIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcy5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiB6dlFiR2pcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9wcm9ncmVzc1xuICogQHNlZWFsc28gb25zLXByb2dyZXNzLWNpcmN1bGFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtcHJvZ3Jlc3MtY2lyY3VsYXI+YCBjb21wb25lbnQgZGlzcGxheXMgYSBjaXJjdWxhciBwcm9ncmVzcyBpbmRpY2F0b3IuWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1wcm9ncmVzcy1iYXJcbiAqICB2YWx1ZT1cIjU1XCJcbiAqICBzZWNvbmRhcnktdmFsdWU9XCI4N1wiPlxuICogPC9vbnMtcHJvZ3Jlc3MtYmFyPlxuICpcbiAqIDxvbnMtcHJvZ3Jlc3MtYmFyXG4gKiAgaW5kZXRlcm1pbmF0ZT5cbiAqIDwvb25zLXByb2dyZXNzLWJhcj5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvZ3Jlc3NCYXJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DaGFuZ2UgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHByb2dyZXNzIGluZGljYXRvci5bL2VuXVxuICAgKiAgIFtqYV3jg5fjg63jgrDjg6zjgrnjgqTjg7PjgrjjgrHjg7zjgr/jga7opovjgZ/nm67jgpLlpInmm7TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB2YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBwcm9ncmVzcy4gU2hvdWxkIGJlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAxMDAuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu6YCy6KGM54q25rOB44Gu5YCk44KS5oyH5a6a44GX44G+44GZ44CCMOOBi+OCiTEwMOOBrumWk+OBruWApOOCkuaMh+WumuOBl+OBpuS4i+OBleOBhOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNlY29uZGFyeS12YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBzZWNvbmRhcnkgcHJvZ3Jlc3MuIFNob3VsZCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMTAwLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBru+8kueVquebruOBrumAsuihjOeKtuazgeOBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAgjDjgYvjgokxMDDjga7plpPjga7lgKTjgpLmjIflrprjgZfjgabkuIvjgZXjgYTjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbmRldGVybWluYXRlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgaWYgKCF0aGlzLl9pc0NvbXBpbGVkKCkpIHtcbiAgICAgIHRoaXMuX3RlbXBsYXRlID0gdGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZSA9IHV0aWwuZmluZENoaWxkKHRoaXMsICcucHJvZ3Jlc3MtYmFyJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJpbWFyeSA9IHV0aWwuZmluZENoaWxkKHRoaXMuX3RlbXBsYXRlLCAnLnByb2dyZXNzLWJhcl9fcHJpbWFyeScpO1xuICAgIHRoaXMuX3NlY29uZGFyeSA9IHV0aWwuZmluZENoaWxkKHRoaXMuX3RlbXBsYXRlLCAnLnByb2dyZXNzLWJhcl9fc2Vjb25kYXJ5Jyk7XG5cbiAgICB0aGlzLl91cGRhdGVEZXRlcm1pbmF0ZSgpO1xuICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG5cbiAgICB0aGlzLmFwcGVuZENoaWxkKHRoaXMuX3RlbXBsYXRlKTtcblxuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIF9pc0NvbXBpbGVkKCkge1xuICAgIGlmICghdXRpbC5maW5kQ2hpbGQodGhpcywgJy5wcm9ncmVzcy1iYXInKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGJhckVsZW1lbnQgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWJhcicpO1xuXG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZChiYXJFbGVtZW50LCAnLnByb2dyZXNzLWJhcl9fc2Vjb25kYXJ5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKGJhckVsZW1lbnQsICcucHJvZ3Jlc3MtYmFyX19wcmltYXJ5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ3ZhbHVlJywgJ3NlY29uZGFyeS12YWx1ZScsIElOREVUXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgdGhpcy5oYXNBdHRyaWJ1dGUoSU5ERVQpICYmIHRoaXMuX3VwZGF0ZURldGVybWluYXRlKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAndmFsdWUnIHx8IG5hbWUgPT09ICdzZWNvbmRhcnktdmFsdWUnKSB7XG4gICAgICB0aGlzLl91cGRhdGVWYWx1ZSgpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gSU5ERVQpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURldGVybWluYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZURldGVybWluYXRlKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB1dGlsLnRvZ2dsZU1vZGlmaWVyKHRoaXMsIElOREVULCB7IGZvcmNlOiB0aGlzLmhhc0F0dHJpYnV0ZShJTkRFVCkgfSkpO1xuICB9XG5cbiAgX3VwZGF0ZVZhbHVlKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9wcmltYXJ5LnN0eWxlLndpZHRoID0gKHRoaXMuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSA/IHRoaXMuZ2V0QXR0cmlidXRlKCd2YWx1ZScpICsgJyUnIDogJzAlJztcbiAgICAgIHRoaXMuX3NlY29uZGFyeS5zdHlsZS53aWR0aCA9IHRoaXMuaGFzQXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSA/IHRoaXMuZ2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSArICclJyA6ICcwJSc7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DdXJyZW50IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCd2YWx1ZScsIE1hdGguZmxvb3IodmFsdWUpKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykgfHwgJzAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgc2Vjb25kYXJ5VmFsdWVcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUN1cnJlbnQgc2Vjb25kYXJ5IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7vvJLnlarnm67jga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCBzZWNvbmRhcnlWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnLCBNYXRoLmZsb29yKHZhbHVlKSk7XG4gIH1cblxuICBnZXQgc2Vjb25kYXJ5VmFsdWUoKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSB8fCAnMCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpbmRldGVybWluYXRlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHNldCBpbmRldGVybWluYXRlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShJTkRFVCwgJycpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKElOREVUKTtcbiAgICB9XG4gIH1cblxuICBnZXQgaW5kZXRlcm1pbmF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoSU5ERVQpO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLlByb2dyZXNzQmFyID0gUHJvZ3Jlc3NCYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcHJvZ3Jlc3MtYmFyJywgUHJvZ3Jlc3NCYXJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJy5wcm9ncmVzcy1jaXJjdWxhcic6ICdwcm9ncmVzcy1jaXJjdWxhci0tKicsXG4gICcucHJvZ3Jlc3MtY2lyY3VsYXJfX2JhY2tncm91bmQnOiAncHJvZ3Jlc3MtY2lyY3VsYXItLSpfX2JhY2tncm91bmQnLFxuICAnLnByb2dyZXNzLWNpcmN1bGFyX19wcmltYXJ5JzogJ3Byb2dyZXNzLWNpcmN1bGFyLS0qX19wcmltYXJ5JyxcbiAgJy5wcm9ncmVzcy1jaXJjdWxhcl9fc2Vjb25kYXJ5JzogJ3Byb2dyZXNzLWNpcmN1bGFyLS0qX19zZWNvbmRhcnknXG59O1xuXG5jb25zdCB0ZW1wbGF0ZSA9IHV0aWwuY3JlYXRlRWxlbWVudChgXG4gIDxzdmcgY2xhc3M9XCJwcm9ncmVzcy1jaXJjdWxhclwiPlxuICAgIDxjaXJjbGUgY2xhc3M9XCJwcm9ncmVzcy1jaXJjdWxhcl9fYmFja2dyb3VuZFwiIC8+XG4gICAgPGNpcmNsZSBjbGFzcz1cInByb2dyZXNzLWNpcmN1bGFyX19zZWNvbmRhcnlcIiBjeD1cIjUwJVwiIGN5PVwiNTAlXCIgcj1cIjQwJVwiIC8+XG4gICAgPGNpcmNsZSBjbGFzcz1cInByb2dyZXNzLWNpcmN1bGFyX19wcmltYXJ5XCIgY3g9XCI1MCVcIiBjeT1cIjUwJVwiIHI9XCI0MCVcIiAvPlxuICA8L3N2Zz5cbmApO1xuXG5jb25zdCBJTkRFVCA9ICdpbmRldGVybWluYXRlJztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtcHJvZ3Jlc3MtY2lyY3VsYXJcbiAqIEBjYXRlZ29yeSB2aXN1YWxcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhpcyBjb21wb25lbnQgZGlzcGxheXMgYSBjaXJjdWxhciBwcm9ncmVzcyBpbmRpY2F0b3IuIEl0IGNhbiBlaXRoZXIgYmUgdXNlZCB0byBzaG93IGhvdyBtdWNoIG9mIGEgdGFzayBoYXMgYmVlbiBjb21wbGV0ZWQgb3IgdG8gc2hvdyBhIGxvb3BpbmcgYW5pbWF0aW9uIHRvIGluZGljYXRlIHRoYXQgYW4gb3BlcmF0aW9uIGlzIGN1cnJlbnRseSBydW5uaW5nLlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIEVWek1qUlxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3Byb2dyZXNzLWNpcmN1bGFyXG4gKiBAc2VlYWxzbyBvbnMtcHJvZ3Jlc3MtYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtcHJvZ3Jlc3MtYmFyPmAgY29tcG9uZW50IGRpc3BsYXlzIGEgYmFyIHByb2dyZXNzIGluZGljYXRvci5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXByb2dyZXNzLWNpcmN1bGFyXG4gKiAgdmFsdWU9XCI1NVwiXG4gKiAgc2Vjb25kYXJ5LXZhbHVlPVwiODdcIj5cbiAqIDwvb25zLXByb2dyZXNzLWNpcmN1bGFyPlxuICpcbiAqIDxvbnMtcHJvZ3Jlc3MtY2lyY3VsYXJcbiAqICBpbmRldGVybWluYXRlPlxuICogPC9vbnMtcHJvZ3Jlc3MtY2lyY3VsYXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFByb2dyZXNzQ2lyY3VsYXJFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DaGFuZ2UgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHByb2dyZXNzIGluZGljYXRvci5bL2VuXVxuICAgKiAgIFtqYV3jg5fjg63jgrDjg6zjgrnjgqTjg7PjgrjjgrHjg7zjgr/jga7opovjgZ/nm67jgpLlpInmm7TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB2YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBwcm9ncmVzcy4gU2hvdWxkIGJlIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAxMDAuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu6YCy6KGM54q25rOB44Gu5YCk44KS5oyH5a6a44GX44G+44GZ44CCMOOBi+OCiTEwMOOBrumWk+OBruWApOOCkuaMh+WumuOBl+OBpuS4i+OBleOBhOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNlY29uZGFyeS12YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBzZWNvbmRhcnkgcHJvZ3Jlc3MuIFNob3VsZCBiZSBhIHZhbHVlIGJldHdlZW4gMCBhbmQgMTAwLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBru+8kueVquebruOBrumAsuihjOeKtuazgeOBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAgjDjgYvjgokxMDDjga7plpPjga7lgKTjgpLmjIflrprjgZfjgabkuIvjgZXjgYTjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpbmRldGVybWluYXRlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAndmFsdWUnLCAnc2Vjb25kYXJ5LXZhbHVlJywgSU5ERVRdO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBpZiAobmFtZSA9PT0gJ21vZGlmaWVyJykge1xuICAgICAgTW9kaWZpZXJVdGlsLm9uTW9kaWZpZXJDaGFuZ2VkKGxhc3QsIGN1cnJlbnQsIHRoaXMsIHNjaGVtZSk7XG4gICAgICB0aGlzLmhhc0F0dHJpYnV0ZShJTkRFVCkgJiYgdGhpcy5fdXBkYXRlRGV0ZXJtaW5hdGUoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICd2YWx1ZScgfHwgbmFtZSA9PT0gJ3NlY29uZGFyeS12YWx1ZScpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVZhbHVlKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSBJTkRFVCkge1xuICAgICAgdGhpcy5fdXBkYXRlRGV0ZXJtaW5hdGUoKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlRGV0ZXJtaW5hdGUoKSB7XG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHV0aWwudG9nZ2xlTW9kaWZpZXIodGhpcywgSU5ERVQsIHsgZm9yY2U6IHRoaXMuaGFzQXR0cmlidXRlKElOREVUKSB9KSk7XG4gIH1cblxuICBfdXBkYXRlVmFsdWUoKSB7XG4gICAgaWYgKHRoaXMuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICBjb25zdCBwZXIgPSBNYXRoLmNlaWwodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykgKiAyNTEuMzIgKiAwLjAxKTtcbiAgICAgICAgdGhpcy5fcHJpbWFyeS5zdHlsZVsnc3Ryb2tlLWRhc2hhcnJheSddID0gcGVyICsgJyUsIDI1MS4zMiUnO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnc2Vjb25kYXJ5LXZhbHVlJykpIHtcbiAgICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBlciA9ICBNYXRoLmNlaWwodGhpcy5nZXRBdHRyaWJ1dGUoJ3NlY29uZGFyeS12YWx1ZScpICogMjUxLjMyICogMC4wMSk7XG4gICAgICAgIHRoaXMuX3NlY29uZGFyeS5zdHlsZS5kaXNwbGF5ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc2Vjb25kYXJ5LnN0eWxlWydzdHJva2UtZGFzaGFycmF5J10gPSBwZXIgKyAnJSwgMjUxLjMyJSc7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgICAgdGhpcy5fc2Vjb25kYXJ5LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZhbHVlXG4gICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DdXJyZW50IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCd2YWx1ZScsIE1hdGguZmxvb3IodmFsdWUpKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpIHtcbiAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ3ZhbHVlJykgfHwgJzAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgc2Vjb25kYXJ5VmFsdWVcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUN1cnJlbnQgc2Vjb25kYXJ5IHByb2dyZXNzLiBTaG91bGQgYmUgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEwMC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7vvJLnlarnm67jga7pgLLooYznirbms4Hjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIIw44GL44KJMTAw44Gu6ZaT44Gu5YCk44KS5oyH5a6a44GX44Gm5LiL44GV44GE44CCWy9qYV1cbiAgICovXG4gIHNldCBzZWNvbmRhcnlWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEwMCkge1xuICAgICAgdXRpbC50aHJvdygnSW52YWxpZCB2YWx1ZScpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnLCBNYXRoLmZsb29yKHZhbHVlKSk7XG4gIH1cblxuICBnZXQgc2Vjb25kYXJ5VmFsdWUoKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ2V0QXR0cmlidXRlKCdzZWNvbmRhcnktdmFsdWUnKSB8fCAnMCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpbmRldGVybWluYXRlXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBwcm9wZXJ0eSBpcyBgdHJ1ZWAsIGFuIGluZmluaXRlIGxvb3BpbmcgYW5pbWF0aW9uIHdpbGwgYmUgc2hvd24uWy9lbl1cbiAgICogICBbamFd44GT44Gu5bGe5oCn44GM6Kit5a6a44GV44KM44Gf5aC05ZCI44CB44Or44O844OX44GZ44KL44Ki44OL44Oh44O844K344On44Oz44GM6KGo56S644GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG4gIHNldCBpbmRldGVybWluYXRlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShJTkRFVCwgJycpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKElOREVUKTtcbiAgICB9XG4gIH1cblxuICBnZXQgaW5kZXRlcm1pbmF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoSU5ERVQpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzQ29tcGlsZWQoKSkge1xuICAgICAgdGhpcy5fdGVtcGxhdGUgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWNpcmN1bGFyJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RlbXBsYXRlID0gdGVtcGxhdGUuY2xvbmVOb2RlKHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuX3ByaW1hcnkgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLl90ZW1wbGF0ZSwgJy5wcm9ncmVzcy1jaXJjdWxhcl9fcHJpbWFyeScpO1xuICAgIHRoaXMuX3NlY29uZGFyeSA9IHV0aWwuZmluZENoaWxkKHRoaXMuX3RlbXBsYXRlLCAnLnByb2dyZXNzLWNpcmN1bGFyX19zZWNvbmRhcnknKTtcblxuICAgIHRoaXMuX3VwZGF0ZURldGVybWluYXRlKCk7XG4gICAgdGhpcy5fdXBkYXRlVmFsdWUoKTtcblxuICAgIHRoaXMuYXBwZW5kQ2hpbGQodGhpcy5fdGVtcGxhdGUpO1xuXG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgX2lzQ29tcGlsZWQoKSB7XG4gICAgaWYgKCF1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWNpcmN1bGFyJykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBzdmcgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnLnByb2dyZXNzLWNpcmN1bGFyJyk7XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHN2ZywgJy5wcm9ncmVzcy1jaXJjdWxhcl9fc2Vjb25kYXJ5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXV0aWwuZmluZENoaWxkKHN2ZywgJy5wcm9ncmVzcy1jaXJjdWxhcl9fcHJpbWFyeScpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxub25zRWxlbWVudHMuUHJvZ3Jlc3NDaXJjdWxhciA9IFByb2dyZXNzQ2lyY3VsYXJFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcHJvZ3Jlc3MtY2lyY3VsYXInLCBQcm9ncmVzc0NpcmN1bGFyRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBzdHlsZXIgZnJvbSAnLi4vb25zL3N0eWxlcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vb25zL2dlc3R1cmUtZGV0ZWN0b3InO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi9vbnMvYW5pbWl0JztcblxuY29uc3QgU1RBVEVfSU5JVElBTCA9ICdpbml0aWFsJztcbmNvbnN0IFNUQVRFX1BSRUFDVElPTiA9ICdwcmVhY3Rpb24nO1xuY29uc3QgU1RBVEVfQUNUSU9OID0gJ2FjdGlvbic7XG5cbmNvbnN0IHRocm93VHlwZSA9IChlbCwgdHlwZSkgPT4gdXRpbC50aHJvdyhgXCIke2VsfVwiIG11c3QgYmUgJHt0eXBlfWApO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1wdWxsLWhvb2tcbiAqIEBjYXRlZ29yeSBjb250cm9sXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIENvbXBvbmVudCB0aGF0IGFkZHMgKipQdWxsIHRvIHJlZnJlc2gqKiBmdW5jdGlvbmFsaXR5IHRvIGFuIGA8b25zLXBhZ2U+YCBlbGVtZW50LlxuICpcbiAqICAgICBJdCBjYW4gYmUgdXNlZCB0byBwZXJmb3JtIGEgdGFzayB3aGVuIHRoZSB1c2VyIHB1bGxzIGRvd24gYXQgdGhlIHRvcCBvZiB0aGUgcGFnZS4gQSBjb21tb24gdXNhZ2UgaXMgdG8gcmVmcmVzaCB0aGUgZGF0YSBkaXNwbGF5ZWQgaW4gYSBwYWdlLlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIFdiSm9nTVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3B1bGwtaG9va1xuICogQGV4YW1wbGVcbiAqIDxvbnMtcGFnZT5cbiAqICAgPG9ucy1wdWxsLWhvb2s+XG4gKiAgICAgUmVsZWFzZSB0byByZWZyZXNoXG4gKiAgIDwvb25zLXB1bGwtaG9vaz5cbiAqIDwvb25zLXBhZ2U+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgZG9jdW1lbnQucXVlcnlTZWxlY3Rvcignb25zLXB1bGwtaG9vaycpLm9uQWN0aW9uID0gZnVuY3Rpb24oZG9uZSkge1xuICogICAgIHNldFRpbWVvdXQoZG9uZSwgMTAwMCk7XG4gKiAgIH07XG4gKiA8L3NjcmlwdD5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHVsbEhvb2tFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgY2hhbmdlc3RhdGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIHdoZW4gdGhlIHN0YXRlIGlzIGNoYW5nZWQuIFRoZSBzdGF0ZSBjYW4gYmUgZWl0aGVyIFwiaW5pdGlhbFwiLCBcInByZWFjdGlvblwiIG9yIFwiYWN0aW9uXCIuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu54q25oWL44GM5aSJ44KP44Gj44Gf5aC05ZCI44Gr55m654Gr44GX44G+44GZ44CC54q25oWL44Gv44CBXCJpbml0aWFsXCIsIFwicHJlYWN0aW9uXCIsIFwiYWN0aW9uXCLjga7jgYTjgZrjgozjgYvjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5wdWxsSG9va1xuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudC5zdGF0ZVxuICAgKiAgIFtlbl1DdXJyZW50IHN0YXRlLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBrueKtuaFi+WQjeOCkuWPgueFp+OBp+OBjeOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdGhlIFwicHVsbC10by1yZWZyZXNoXCIgZnVuY3Rpb25hbGl0eSBpcyBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIFkaXNhYmxlZOeKtuaFi+OBq+OBquOCiuOCouOCr+OCt+ODp+ODs+OBjOWun+ihjOOBleOCjOOBquOBj+OBquOCiuOBvuOBmVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGhlaWdodFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgaGVpZ2h0IG9mIHRoZSBjb21wb25lbnQuIFdoZW4gcHVsbGVkIGRvd24gZnVydGhlciB0aGFuIHRoaXMgdmFsdWUgaXQgd2lsbCBzd2l0Y2ggdG8gdGhlIFwicHJlYWN0aW9uXCIgc3RhdGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwiNjRweFwiLlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBrumrmOOBleOCkuaMh+WumuOBl+OBvuOBmeOAguOBk+OBrumrmOOBleS7peS4iuOBq3B1bGwgZG93buOBmeOCi+OBqFwicHJlYWN0aW9uXCLnirbmhYvjgavnp7vooYzjgZfjgb7jgZnjgILjg4fjg5Xjgqnjg6vjg4jjga7lgKTjga9cIjY0cHhcIuOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHRocmVzaG9sZC1oZWlnaHRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIHRocmVzaG9sZCBoZWlnaHQuIFRoZSBjb21wb25lbnQgYXV0b21hdGljYWxseSBzd2l0Y2hlcyB0byB0aGUgXCJhY3Rpb25cIiBzdGF0ZSB3aGVuIHB1bGxlZCBmdXJ0aGVyIHRoYW4gdGhpcyB2YWx1ZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCI5NnB4XCIuIEEgbmVnYXRpdmUgdmFsdWUgd2lsbCBkaXNhYmxlIHRoaXMgcHJvcGVydHkuIElmIHRoaXMgdmFsdWUgaXMgbG93ZXIgdGhhbiB0aGUgaGVpZ2h0LCBpdCB3aWxsIHNraXAgXCJwcmVhY3Rpb25cIiBzdGF0ZS5bL2VuXVxuICAgKiAgIFtqYV3plr7lgKTjgajjgarjgovpq5jjgZXjgpLmjIflrprjgZfjgb7jgZnjgILjgZPjga7lgKTjgafmjIflrprjgZfjgZ/pq5jjgZXjgojjgorjgoJwdWxsIGRvd27jgZnjgovjgajjgIHjgZPjga7jgrPjg7Pjg53jg7zjg43jg7Pjg4jjga/oh6rli5XnmoTjgatcImFjdGlvblwi54q25oWL44Gr56e76KGM44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZml4ZWQtY29udGVudFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSBjb250ZW50IG9mIHRoZSBwYWdlIHdpbGwgbm90IG1vdmUgd2hlbiBwdWxsaW5nLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruWxnuaAp+OBjOOBguOCi+aZguOAgeODl+ODq+ODleODg+OCr+OBjOW8leOBjeWHuuOBleOCjOOBpuOBhOOCi+aZguOBq+OCguOCs+ODs+ODhuODs+ODhOOBr+WLleOBjeOBvuOBm+OCk+OAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9zaG91bGRGaXhTY3JvbGwgPSB1dGlsLmdsb2JhbHMuaXNVSVdlYlZpZXc7XG5cbiAgICB0aGlzLl9vbkRyYWcgPSB0aGlzLl9vbkRyYWcuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vbkRyYWdTdGFydCA9IHRoaXMuX29uRHJhZ1N0YXJ0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25EcmFnRW5kID0gdGhpcy5fb25EcmFnRW5kLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25TY3JvbGwgPSB0aGlzLl9vblNjcm9sbC5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5fc2V0U3RhdGUoU1RBVEVfSU5JVElBTCwgdHJ1ZSk7XG4gICAgdGhpcy5faGlkZSgpOyAvLyBGaXggZm9yIHRyYW5zcGFyZW50IHRvb2xiYXIgdHJhbnNpdGlvbnNcbiAgfVxuXG4gIF9zZXRTdHlsZSgpIHtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLmhlaWdodCArICdweCc7XG4gICAgc3R5bGVyKHRoaXMsIHsgaGVpZ2h0LCBsaW5lSGVpZ2h0OiBoZWlnaHQgfSk7XG4gICAgdGhpcy5zdHlsZS5kaXNwbGF5ID09PSAnJyAmJiB0aGlzLl9zaG93KCk7XG4gIH1cblxuICBfb25TY3JvbGwoZXZlbnQpIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fcGFnZUVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudC5zY3JvbGxUb3AgPCAwKSB7XG4gICAgICBlbGVtZW50LnNjcm9sbFRvcCA9IDA7XG4gICAgfVxuICB9XG5cbiAgX2NhbkNvbnN1bWVHZXN0dXJlKGdlc3R1cmUpIHtcbiAgICByZXR1cm4gZ2VzdHVyZS5kaXJlY3Rpb24gPT09ICd1cCcgfHwgZ2VzdHVyZS5kaXJlY3Rpb24gPT09ICdkb3duJztcbiAgfVxuXG4gIF9vbkRyYWdTdGFydChldmVudCkge1xuICAgIGlmICghZXZlbnQuZ2VzdHVyZSB8fCB0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGFwWSA9IGV2ZW50Lmdlc3R1cmUuY2VudGVyLmNsaWVudFkgKyB0aGlzLl9wYWdlRWxlbWVudC5zY3JvbGxUb3A7XG4gICAgY29uc3QgbWF4WSA9IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICAvLyBPbmx5IHVzZSBkcmFncyB0aGF0IHN0YXJ0IG5lYXIgdGhlIHB1bGxIb29rIHRvIHJlZHVjZSBmbGlja2VyaW5nc1xuICAgIGNvbnN0IGRyYWdnYWJsZUFyZWFSYXRpbyA9IHRoaXMuX3Nob3VsZEZpeFNjcm9sbCA/IC44IDogMTtcblxuICAgIHRoaXMuX2lnbm9yZURyYWcgPSBldmVudC5jb25zdW1lZCB8fCAodGFwWSA+IG1heFkgKiBkcmFnZ2FibGVBcmVhUmF0aW8pO1xuXG4gICAgaWYgKCF0aGlzLl9pZ25vcmVEcmFnKSB7XG4gICAgICBjb25zdCBjb25zdW1lID0gZXZlbnQuY29uc3VtZTtcbiAgICAgIGV2ZW50LmNvbnN1bWUgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN1bWUgJiYgY29uc3VtZSgpO1xuICAgICAgICB0aGlzLl9pZ25vcmVEcmFnID0gdHJ1ZTtcbiAgICAgICAgLy8gVGhpcyBlbGVtZW50cyByZXNpemVzIC5wYWdlX19jb250ZW50IHNvIGl0IGlzIHNhZmVyXG4gICAgICAgIC8vIHRvIGhpZGUgaXQgd2hlbiBvdGhlciBjb21wb25lbnRzIGFyZSBkcmFnZ2VkLlxuICAgICAgICB0aGlzLl9oaWRlKCk7XG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5fY2FuQ29uc3VtZUdlc3R1cmUoZXZlbnQuZ2VzdHVyZSkpIHtcbiAgICAgICAgY29uc3VtZSAmJiBjb25zdW1lKCk7XG4gICAgICAgIGV2ZW50LmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fc2hvdygpOyAvLyBOb3QgZW5vdWdoIGR1ZSB0byAnZHJhZ0xvY2tBeGlzJ1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX3N0YXJ0U2Nyb2xsID0gdGhpcy5fcGFnZUVsZW1lbnQuc2Nyb2xsVG9wO1xuICB9XG5cbiAgX29uRHJhZyhldmVudCkge1xuICAgIGlmICghZXZlbnQuZ2VzdHVyZSB8fCB0aGlzLmRpc2FibGVkIHx8IHRoaXMuX2lnbm9yZURyYWcgfHwgIXRoaXMuX2NhbkNvbnN1bWVHZXN0dXJlKGV2ZW50Lmdlc3R1cmUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTmVjZXNzYXJ5IGR1ZSB0byAnZHJhZ0xvY2tBeGlzJyAoMjVweClcbiAgICBpZiAodGhpcy5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIHRoaXMuX3Nob3coKTtcbiAgICB9XG5cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIGNvbnN0IHRhcFkgPSBldmVudC5nZXN0dXJlLmNlbnRlci5jbGllbnRZICsgdGhpcy5fcGFnZUVsZW1lbnQuc2Nyb2xsVG9wO1xuICAgIGNvbnN0IG1heFkgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cbiAgICAvLyBIYWNrIHRvIG1ha2UgaXQgd29yayBvbiBBbmRyb2lkIDQuNCBXZWJWaWV3IGFuZCBpT1MgVUlXZWJWaWV3LiBTY3JvbGxzIG1hbnVhbGx5XG4gICAgLy8gbmVhciB0aGUgdG9wIG9mIHRoZSBwYWdlIHNvIHRoZXJlIHdpbGwgYmUgbm8gaW5lcnRpYWwgc2Nyb2xsIHdoZW4gc2Nyb2xsaW5nIGRvd24uXG4gICAgLy8gQWxsb3dpbmcgZGVmYXVsdCBzY3JvbGxpbmcgd2lsbCBraWxsIGFsbCAndG91Y2htb3ZlJyBldmVudHMuXG4gICAgaWYgKHRoaXMuX3Nob3VsZEZpeFNjcm9sbCkge1xuICAgICAgdGhpcy5fcGFnZUVsZW1lbnQuc2Nyb2xsVG9wID0gdGhpcy5fc3RhcnRTY3JvbGwgLSBldmVudC5nZXN0dXJlLmRlbHRhWTtcbiAgICAgIC8vIEFsbG93IGluZXJ0aWEgd2hlbiBzY3JvbGxpbmcgZG93biBiZWxvdyA1MCUgb2YgdGhlIHZpZXcgdG8gcmVkdWNlIGZsaWNrZXJpbmdzXG4gICAgICBpZiAoZXZlbnQuZ2VzdHVyZS5pbnRlcmltRGlyZWN0aW9uICE9PSAndXAnIHx8ICh0YXBZIDw9IG1heFkgKiAuNSkpIHtcbiAgICAgICAgZXZlbnQuZ2VzdHVyZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNjcm9sbCA9IE1hdGgubWF4KGV2ZW50Lmdlc3R1cmUuZGVsdGFZIC0gdGhpcy5fc3RhcnRTY3JvbGwsIDApO1xuICAgIGlmIChzY3JvbGwgIT09IHRoaXMuX2N1cnJlbnRUcmFuc2xhdGlvbikge1xuXG4gICAgICBjb25zdCB0aCA9IHRoaXMudGhyZXNob2xkSGVpZ2h0O1xuICAgICAgaWYgKHRoID4gMCAmJiBzY3JvbGwgPj0gdGgpIHtcbiAgICAgICAgZXZlbnQuZ2VzdHVyZS5zdG9wRGV0ZWN0KCk7XG4gICAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9maW5pc2goKSk7XG5cbiAgICAgIH0gZWxzZSBpZiAoc2Nyb2xsID49IHRoaXMuaGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuX3NldFN0YXRlKFNUQVRFX1BSRUFDVElPTik7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3NldFN0YXRlKFNUQVRFX0lOSVRJQUwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl90cmFuc2xhdGVUbyhzY3JvbGwpO1xuICAgIH1cbiAgfVxuXG4gIF9vbkRyYWdFbmQoZXZlbnQpIHtcbiAgICBpZiAoIWV2ZW50Lmdlc3R1cmUgfHwgdGhpcy5kaXNhYmxlZCB8fCB0aGlzLl9pZ25vcmVEcmFnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBpZiAodGhpcy5fY3VycmVudFRyYW5zbGF0aW9uID4gMCkge1xuICAgICAgY29uc3Qgc2Nyb2xsID0gdGhpcy5fY3VycmVudFRyYW5zbGF0aW9uO1xuXG4gICAgICBpZiAoc2Nyb2xsID4gdGhpcy5oZWlnaHQpIHtcbiAgICAgICAgdGhpcy5fZmluaXNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl90cmFuc2xhdGVUbygwLCB7YW5pbWF0ZTogdHJ1ZX0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgb25BY3Rpb25cbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhpcyB3aWxsIGJlIGNhbGxlZCBpbiB0aGUgYGFjdGlvbmAgc3RhdGUgaWYgaXQgZXhpc3RzLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBnaXZlbiBhIGBkb25lYCBjYWxsYmFjayBhcyBpdCdzIGZpcnN0IGFyZ3VtZW50LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgb25BY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX29uQWN0aW9uO1xuICB9XG5cbiAgc2V0IG9uQWN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHRocm93VHlwZSgnb25BY3Rpb24nLCAnZnVuY3Rpb24gb3IgbnVsbCcpO1xuICAgIH1cbiAgICB0aGlzLl9vbkFjdGlvbiA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvblB1bGxcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIHVzZXIgcHVsbHMgdGhlIGVsZW1lbnQuIEl0IGdldHMgdGhlIHB1bGxlZCBkaXN0YW5jZSByYXRpbyAoc2Nyb2xsIC8gaGVpZ2h0KSBhbmQgYW4gYW5pbWF0aW9uT3B0aW9ucyBvYmplY3QgYXMgYXJndW1lbnRzLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgb25QdWxsKCkge1xuICAgIHJldHVybiB0aGlzLl9vblB1bGw7XG4gIH1cblxuICBzZXQgb25QdWxsKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmICEodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgIHRocm93VHlwZSgnb25QdWxsJywgJ2Z1bmN0aW9uIG9yIG51bGwnKTtcbiAgICB9XG4gICAgdGhpcy5fb25QdWxsID0gdmFsdWU7XG4gIH1cblxuICBfZmluaXNoKCkge1xuICAgIHRoaXMuX3NldFN0YXRlKFNUQVRFX0FDVElPTik7XG4gICAgdGhpcy5fdHJhbnNsYXRlVG8odGhpcy5oZWlnaHQsIHthbmltYXRlOiB0cnVlfSk7XG4gICAgY29uc3QgYWN0aW9uID0gdGhpcy5vbkFjdGlvbiB8fCAoZG9uZSA9PiBkb25lKCkpO1xuICAgIGFjdGlvbigoKSA9PiB7XG4gICAgICB0aGlzLl90cmFuc2xhdGVUbygwLCB7YW5pbWF0ZTogdHJ1ZX0pO1xuICAgICAgdGhpcy5fc2V0U3RhdGUoU1RBVEVfSU5JVElBTCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGhlaWdodFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGhlaWdodCBvZiB0aGUgcHVsbCBob29rIGluIHBpeGVscy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYDY0cHhgLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzZXQgaGVpZ2h0KHZhbHVlKSB7XG4gICAgaWYgKCF1dGlsLmlzSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgIHRocm93VHlwZSgnaGVpZ2h0JywgJ2ludGVnZXInKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7dmFsdWV9cHhgKTtcbiAgfVxuXG4gIGdldCBoZWlnaHQoKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuZ2V0QXR0cmlidXRlKCdoZWlnaHQnKSB8fCAnNjQnLCAxMCk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHRocmVzaG9sZEhlaWdodFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHRocmVzaG9sZEhlaWdodCBvZiB0aGUgcHVsbCBob29rIGluIHBpeGVscy4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYDk2cHhgLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzZXQgdGhyZXNob2xkSGVpZ2h0KHZhbHVlKSB7XG4gICAgaWYgKCF1dGlsLmlzSW50ZWdlcih2YWx1ZSkpIHtcbiAgICAgIHRocm93VHlwZSgndGhyZXNob2xkSGVpZ2h0JywgJ2ludGVnZXInKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldEF0dHJpYnV0ZSgndGhyZXNob2xkLWhlaWdodCcsIGAke3ZhbHVlfXB4YCk7XG4gIH1cblxuICBnZXQgdGhyZXNob2xkSGVpZ2h0KCkge1xuICAgIHJldHVybiBwYXJzZUludCh0aGlzLmdldEF0dHJpYnV0ZSgndGhyZXNob2xkLWhlaWdodCcpIHx8ICc5NicsIDEwKTtcbiAgfVxuXG4gIF9zZXRTdGF0ZShzdGF0ZSwgbm9FdmVudCkge1xuICAgIGNvbnN0IGxhc3RTdGF0ZSA9IHRoaXMuc3RhdGU7XG5cbiAgICB0aGlzLnNldEF0dHJpYnV0ZSgnc3RhdGUnLCBzdGF0ZSk7XG5cbiAgICBpZiAoIW5vRXZlbnQgJiYgbGFzdFN0YXRlICE9PSB0aGlzLnN0YXRlKSB7XG4gICAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ2NoYW5nZXN0YXRlJywge1xuICAgICAgICBwdWxsSG9vazogdGhpcyxcbiAgICAgICAgc3RhdGU6IHN0YXRlLFxuICAgICAgICBsYXN0U3RhdGU6IGxhc3RTdGF0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzdGF0ZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUN1cnJlbnQgc3RhdGUgb2YgdGhlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBzdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoJ3N0YXRlJyk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHB1bGxEaXN0YW5jZVxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBjdXJyZW50IG51bWJlciBvZiBwaXhlbHMgdGhlIHB1bGwgaG9vayBoYXMgbW92ZWQuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu44OX44Or44OV44OD44Kv44GM5byV44GN5Ye644GV44KM44Gf6Led6Zui44KS44OU44Kv44K744Or5pWw44CCWy9qYV1cbiAgICovXG4gIGdldCBwdWxsRGlzdGFuY2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUcmFuc2xhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBlbGVtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdkaXNhYmxlZCcsIHZhbHVlKTtcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICAvLyBSdW4gYXN5bmNyaG9ub3VzbHkgdG8gYXZvaWQgY29uZmxpY3RzIHdpdGggQW5pbWl0J3Mgc3R5bGUgY2xlYW5cbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgdGhpcy5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICBpZiAodGhpcy5fcGFnZUVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5fcGFnZUVsZW1lbnQuc3R5bGUubWFyZ2luVG9wID0gYC0ke3RoaXMuaGVpZ2h0fXB4YDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBpZiAodGhpcy5fcGFnZUVsZW1lbnQpIHtcbiAgICAgIHRoaXMuX3BhZ2VFbGVtZW50LnN0eWxlLm1hcmdpblRvcCA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge051bWJlcn0gc2Nyb2xsXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKi9cbiAgX3RyYW5zbGF0ZVRvKHNjcm9sbCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRUcmFuc2xhdGlvbiA9PSAwICYmIHNjcm9sbCA9PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY3VycmVudFRyYW5zbGF0aW9uID0gc2Nyb2xsO1xuICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMuYW5pbWF0ZSA/IHsgZHVyYXRpb246IC4zLCB0aW1pbmc6ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknIH0gOiB7fTtcbiAgICB0aGlzLl9vblB1bGwgJiYgdGhpcy5fb25QdWxsKChzY3JvbGwgLyB0aGlzLmhlaWdodCkudG9GaXhlZCgyKSwgb3B0KTtcbiAgICBjb25zdCBzY3JvbGxFbGVtZW50ID0gIHRoaXMuaGFzQXR0cmlidXRlKCdmaXhlZC1jb250ZW50JykgPyB0aGlzIDogdGhpcy5fcGFnZUVsZW1lbnQ7XG5cbiAgICBhbmltaXQoc2Nyb2xsRWxlbWVudClcbiAgICAgIC5xdWV1ZSh7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKDBweCwgJHtzY3JvbGx9cHgsIDBweClgIH0sIG9wdClcbiAgICAgIC5wbGF5KCgpID0+IHtcbiAgICAgICAgc2Nyb2xsID09PSAwICYmIHN0eWxlci5jbGVhcihzY3JvbGxFbGVtZW50LCAndHJhbnNpdGlvbiB0cmFuc2Zvcm0nKTtcbiAgICAgICAgb3B0aW9ucy5jYWxsYmFjayBpbnN0YW5jZW9mIEZ1bmN0aW9uICYmIG9wdGlvbnMuY2FsbGJhY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9kaXNhYmxlRHJhZ0xvY2soKSB7IC8vIGUyZSB0ZXN0cyBuZWVkIGl0XG4gICAgdGhpcy5fZHJhZ0xvY2tEaXNhYmxlZCA9IHRydWU7XG4gICAgdGhpcy5fc2V0dXBMaXN0ZW5lcnModHJ1ZSk7XG4gIH1cblxuICBfc2V0dXBMaXN0ZW5lcnMoYWRkKSB7XG4gICAgY29uc3Qgc2Nyb2xsVG9nZ2xlID0gYWN0aW9uID0+IHRoaXMuX3BhZ2VFbGVtZW50W2Ake2FjdGlvbn1FdmVudExpc3RlbmVyYF0oJ3Njcm9sbCcsIHRoaXMuX29uU2Nyb2xsLCBmYWxzZSk7XG4gICAgY29uc3QgZ2RUb2dnbGUgPSBhY3Rpb24gPT4ge1xuICAgICAgY29uc3QgcGFzc2l2ZSA9IHsgcGFzc2l2ZTogdHJ1ZSB9O1xuICAgICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yW2FjdGlvbl0oJ2RyYWcnLCB0aGlzLl9vbkRyYWcsIHBhc3NpdmUpO1xuICAgICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yW2FjdGlvbl0oJ2RyYWdzdGFydCcsIHRoaXMuX29uRHJhZ1N0YXJ0LCBwYXNzaXZlKTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvclthY3Rpb25dKCdkcmFnZW5kJywgdGhpcy5fb25EcmFnRW5kLCBwYXNzaXZlKTtcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuX2dlc3R1cmVEZXRlY3Rvcikge1xuICAgICAgZ2RUb2dnbGUoJ29mZicpO1xuICAgICAgdGhpcy5fZ2VzdHVyZURldGVjdG9yLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciA9IG51bGw7XG4gICAgfVxuICAgIHNjcm9sbFRvZ2dsZSgncmVtb3ZlJyk7XG5cbiAgICBpZiAoYWRkKSB7XG4gICAgICB0aGlzLl9nZXN0dXJlRGV0ZWN0b3IgPSBuZXcgR2VzdHVyZURldGVjdG9yKHRoaXMuX3BhZ2VFbGVtZW50LCB7XG4gICAgICAgIGRyYWdNaW5EaXN0YW5jZTogMSxcbiAgICAgICAgZHJhZ0Rpc3RhbmNlQ29ycmVjdGlvbjogZmFsc2UsXG4gICAgICAgIGRyYWdMb2NrVG9BeGlzOiAhdGhpcy5fZHJhZ0xvY2tEaXNhYmxlZCxcbiAgICAgICAgcGFzc2l2ZTogIXRoaXMuX3Nob3VsZEZpeFNjcm9sbFxuICAgICAgfSk7XG5cbiAgICAgIGdkVG9nZ2xlKCdvbicpO1xuICAgICAgc2Nyb2xsVG9nZ2xlKCdhZGQnKTtcbiAgICB9XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9jdXJyZW50VHJhbnNsYXRpb24gPSAwO1xuICAgIHRoaXMuX3BhZ2VFbGVtZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuXG4gICAgdGhpcy5fc2V0dXBMaXN0ZW5lcnModHJ1ZSk7XG4gICAgdGhpcy5fc2V0U3R5bGUoKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX2hpZGUoKTtcbiAgICB0aGlzLl9zZXR1cExpc3RlbmVycyhmYWxzZSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydoZWlnaHQnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdoZWlnaHQnICYmIHRoaXMuX3BhZ2VFbGVtZW50KSB7XG4gICAgICB0aGlzLl9zZXRTdHlsZSgpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ2NoYW5nZXN0YXRlJ11cbiAgfVxufVxuXG5vbnNFbGVtZW50cy5QdWxsSG9vayA9IFB1bGxIb29rRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXB1bGwtaG9vaycsIFB1bGxIb29rRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgQmFzZUlucHV0RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1pbnB1dCc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdyYW5nZS0tKicsXG4gICcucmFuZ2VfX2lucHV0JzogJ3JhbmdlLS0qX19pbnB1dCcsXG4gICcucmFuZ2VfX2ZvY3VzLXJpbmcnOiAncmFuZ2UtLSpfX2ZvY3VzLXJpbmcnXG59O1xuXG5jb25zdCBhY3RpdmVDbGFzc1Rva2VuID0gJ3JhbmdlX19pbnB1dC0tYWN0aXZlJztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtcmFuZ2VcbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBzbGlkZXJbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgUmFuZ2UgaW5wdXQgY29tcG9uZW50LiBVc2VkIHRvIGRpc3BsYXkgYSBkcmFnZ2FibGUgc2xpZGVyLlxuICpcbiAqICAgICBXb3JrcyB2ZXJ5IHNpbWlsYXIgdG8gdGhlIGA8aW5wdXQgdHlwZT1cInJhbmdlXCI+YCBlbGVtZW50LlxuICogICBbL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBjb2RlcGVuIHhaUW9tTVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3JhbmdlXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1pbnB1dFxuICogICBbZW5dVGhlIGA8b25zLWlucHV0PmAgY29tcG9uZW50IGlzIHVzZWQgdG8gZGlzcGxheSB0ZXh0IGlucHV0cywgcmFkaW8gYnV0dG9ucyBhbmQgY2hlY2tib3hlcy5bL2VuXVxuICogICBbamFdWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXJhbmdlIHZhbHVlPVwiMjBcIj48L29ucy1yYW5nZT5cbiAqIDxvbnMtcmFuZ2UgbW9kaWZpZXI9XCJtYXRlcmlhbFwiIHZhbHVlPVwiMTBcIj48L3JhbmdlPlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJhbmdlRWxlbWVudCBleHRlbmRzIEJhc2VJbnB1dEVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9vbk1vdXNlRG93biA9IHRoaXMuX29uTW91c2VEb3duLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25Nb3VzZVVwID0gdGhpcy5fb25Nb3VzZVVwLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25Ub3VjaFN0YXJ0ID0gdGhpcy5fb25Ub3VjaFN0YXJ0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25Ub3VjaEVuZCA9IHRoaXMuX29uVG91Y2hFbmQuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vbklucHV0ID0gdGhpcy5fdXBkYXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5fb25EcmFnc3RhcnQgPSB0aGlzLl9vbkRyYWdzdGFydC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uRHJhZ2VuZCA9IHRoaXMuX29uRHJhZ2VuZC5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgc3VwZXIuX2NvbXBpbGUoKTtcbiAgICB0aGlzLl91cGRhdGVEaXNhYmxlZCh0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSk7XG4gIH1cblxuICAvKiBJbmhlcml0ZWQgcHJvcHMgKi9cblxuICBfdXBkYXRlKCkge1xuICAgIGNvbnN0IGlucHV0ID0gdGhpcy5faW5wdXQ7XG4gICAgY29uc3QgZm9jdXNSaW5nID0gdGhpcy5fZm9jdXNSaW5nO1xuXG4gICAgaW5wdXQuc3R5bGUuYmFja2dyb3VuZFNpemUgPSBgJHsxMDAgKiB0aGlzLl9yYXRpb30lIDJweGA7XG4gICAgZm9jdXNSaW5nLnZhbHVlID0gdGhpcy52YWx1ZTtcblxuICAgIC8vIE5PVEU6IFwiX3plcm9cIiBhdHRyaWJ1dGUgaXMgdXNlZCBmb3IgQ1NTIHN0eWxpbmcuXG4gICAgaWYgKChpbnB1dC5taW4gPT09ICcnICYmIGlucHV0LnZhbHVlID09PSAnMCcpIHx8IGlucHV0Lm1pbiA9PT0gaW5wdXQudmFsdWUpIHtcbiAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgnX3plcm8nLCAnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlucHV0LnJlbW92ZUF0dHJpYnV0ZSgnX3plcm8nKTtcbiAgICB9XG5cbiAgICBbJ21pbicsICdtYXgnXS5mb3JFYWNoKGF0dHIgPT4gZm9jdXNSaW5nW2F0dHJdID0gaW5wdXRbYXR0cl0pO1xuICB9XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfdGVtcGxhdGUoKSB7XG4gICAgcmV0dXJuIGBcbiAgICAgIDxpbnB1dCB0eXBlPVwiJHt0aGlzLnR5cGV9XCIgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X19pbnB1dFwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJyYW5nZVwiIGNsYXNzPVwicmFuZ2VfX2ZvY3VzLXJpbmdcIiB0YWJJbmRleD1cIi0xXCI+XG4gICAgYDtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ3JhbmdlJztcbiAgfVxuXG4gIGdldCB0eXBlKCkge1xuICAgIHJldHVybiAncmFuZ2UnO1xuICB9XG5cbiAgLyogT3duIHByb3BzICovXG5cbiAgX29uTW91c2VEb3duKGUpIHtcbiAgICB0aGlzLl9pbnB1dC5jbGFzc0xpc3QuYWRkKGFjdGl2ZUNsYXNzVG9rZW4pO1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9pbnB1dC5mb2N1cygpKTtcbiAgfVxuXG4gIF9vblRvdWNoU3RhcnQoZSkge1xuICAgIHRoaXMuX29uTW91c2VEb3duKCk7XG4gIH1cblxuICBfb25Nb3VzZVVwKGUpIHtcbiAgICB0aGlzLl9pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKGFjdGl2ZUNsYXNzVG9rZW4pO1xuICB9XG5cbiAgX29uVG91Y2hFbmQoZSkge1xuICAgIHRoaXMuX29uTW91c2VVcChlKTtcbiAgfVxuXG4gIF9vbkRyYWdzdGFydChlKSB7XG4gICAgZS5jb25zdW1lZCA9IHRydWU7XG4gICAgZS5nZXN0dXJlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuX2lucHV0LmNsYXNzTGlzdC5hZGQoYWN0aXZlQ2xhc3NUb2tlbik7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdkcmFnJywgdGhpcy5fb25EcmFnKTtcbiAgfVxuXG4gIF9vbkRyYWcoZSkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBfb25EcmFnZW5kKGUpIHtcbiAgICB0aGlzLl9pbnB1dC5jbGFzc0xpc3QucmVtb3ZlKGFjdGl2ZUNsYXNzVG9rZW4pO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZycsIHRoaXMuX29uRHJhZyk7XG4gIH1cblxuICBnZXQgX2ZvY3VzUmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5jaGlsZHJlblsxXTtcbiAgfVxuXG4gIGdldCBfcmF0aW8oKSB7XG4gICAgLy8gUmV0dXJucyB0aGUgY3VycmVudCByYXRpby5cbiAgICBjb25zdCBtaW4gPSB0aGlzLl9pbnB1dC5taW4gPT09ICcnID8gMCA6IHBhcnNlSW50KHRoaXMuX2lucHV0Lm1pbik7XG4gICAgY29uc3QgbWF4ID0gdGhpcy5faW5wdXQubWF4ID09PSAnJyA/IDEwMCA6IHBhcnNlSW50KHRoaXMuX2lucHV0Lm1heCk7XG5cbiAgICByZXR1cm4gKHRoaXMudmFsdWUgLSBtaW4pIC8gKG1heCAtIG1pbik7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydkaXNhYmxlZCcsIC4uLkJhc2VJbnB1dEVsZW1lbnQub2JzZXJ2ZWRBdHRyaWJ1dGVzXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdkaXNhYmxlZCcpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURpc2FibGVkKGN1cnJlbnQpO1xuICAgIH1cbiAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtib29sZWFufSBkaXNhYmxlZFxuICAgKi9cbiAgX3VwZGF0ZURpc2FibGVkKGRpc2FibGVkKSB7XG4gICAgaWYgKGRpc2FibGVkKSB7XG4gICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ3JhbmdlLS1kaXNhYmxlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsYXNzTGlzdC5yZW1vdmUoJ3JhbmdlLS1kaXNhYmxlZCcpO1xuICAgIH1cbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX3NldHVwTGlzdGVuZXJzKHRydWUpO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5fc2V0dXBMaXN0ZW5lcnMoZmFsc2UpO1xuICB9XG5cbiAgX3NldHVwTGlzdGVuZXJzKGFkZCkge1xuICAgIGNvbnN0IGFjdGlvbiA9IChhZGQgPyAnYWRkJyA6ICdyZW1vdmUnKSArICdFdmVudExpc3RlbmVyJztcbiAgICB1dGlsW2FjdGlvbl0odGhpcywgJ3RvdWNoc3RhcnQnLCB0aGlzLl9vblRvdWNoU3RhcnQsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICB0aGlzW2FjdGlvbl0oJ21vdXNlZG93bicsIHRoaXMuX29uTW91c2VEb3duKTtcbiAgICB0aGlzW2FjdGlvbl0oJ21vdXNldXAnLCB0aGlzLl9vbk1vdXNlVXApO1xuICAgIHRoaXNbYWN0aW9uXSgndG91Y2hlbmQnLCB0aGlzLl9vblRvdWNoRW5kKTtcbiAgICB0aGlzW2FjdGlvbl0oJ2RyYWdzdGFydCcsIHRoaXMuX29uRHJhZ3N0YXJ0KTtcbiAgICB0aGlzW2FjdGlvbl0oJ2RyYWdlbmQnLCB0aGlzLl9vbkRyYWdlbmQpO1xuICAgIHRoaXNbYWN0aW9uXSgnaW5wdXQnLCB0aGlzLl9vbklucHV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBlbGVtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2YWx1ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCB2YWx1ZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbn1cblxub25zRWxlbWVudHMuUmFuZ2UgPSBSYW5nZUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1yYW5nZScsIFJhbmdlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNiBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsJztcblxuLyoqXG4gKiBAY2xhc3MgQW5pbWF0b3JDU1MgLSBpbXBsZW1lbnRhdGlvbiBvZiBBbmltYXRvciBjbGFzcyB1c2luZyBjc3MgdHJhbnNpdGlvbnNcbiAqL1xuY2xhc3MgQW5pbWF0b3JDU1Mge1xuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGFuaW1hdGVcbiAgICogQGRlc2MgbWFpbiBhbmltYXRpb24gZnVuY3Rpb25cbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBmaW5hbENTU1xuICAgKiBAcGFyYW0ge251bWJlcn0gW2R1cmF0aW9uPTIwMF0gLSBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAgICogQHJldHVybiB7T2JqZWN0fSByZXN1bHRcbiAgICogQHJldHVybiB7RnVuY3Rpb259IHJlc3VsdC50aGVuKGNhbGxiYWNrKSAtIHNldHMgYSBjYWxsYmFjayB0byBiZSBleGVjdXRlZCBhZnRlciB0aGUgYW5pbWF0aW9uIGhhcyBzdG9wcGVkXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufSByZXN1bHQuc3RvcChvcHRpb25zKSAtIHN0b3BzIHRoZSBhbmltYXRpb247IGlmIG9wdGlvbnMuc3RvcE5leHQgaXMgdHJ1ZSB0aGVuIGl0IGRvZXNuJ3QgY2FsbCB0aGUgY2FsbGJhY2tcbiAgICogQHJldHVybiB7RnVuY3Rpb259IHJlc3VsdC5maW5pc2gobXMpIC0gZmluaXNoZXMgdGhlIGFuaW1hdGlvbiBpbiB0aGUgc3BlY2lmaWVkIHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufSByZXN1bHQuc3BlZWQobXMpIC0gc2V0cyB0aGUgYW5pbWF0aW9uIHNwZWVkIHNvIHRoYXQgaXQgZmluaXNoZXMgYXMgaWYgdGhlIG9yaWdpbmFsIGR1cmF0aW9uIHdhcyB0aGUgb25lIHNwZWNpZmllZCBoZXJlXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYGBcbiAgICogIHZhciByZXN1bHQgPSBhbmltYXRvci5hbmltYXRlKGVsLCB7b3BhY2l0eTogMC41fSwgMTAwMCk7XG4gICAqXG4gICAqICBlbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGUpe1xuICAgKiAgICByZXN1bHQuc3BlZWQoMjAwKS50aGVuKGZ1bmN0aW9uKCl7XG4gICAqICAgICAgY29uc29sZS5sb2coJ2RvbmUnKTtcbiAgICogICAgfSk7XG4gICAqICB9LCAzMDApO1xuICAgKiBgYGBgXG4gICAqL1xuICBhbmltYXRlKGVsLCBmaW5hbCwgZHVyYXRpb24gPSAyMDApIHtcbiAgICB2YXIgc3RhcnQgPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpLFxuICAgICAgICBpbml0aWFsID0ge30sXG4gICAgICAgIHN0b3BwZWQgPSBmYWxzZSxcbiAgICAgICAgbmV4dCA9IGZhbHNlLFxuICAgICAgICB0aW1lb3V0ID0gZmFsc2UsXG4gICAgICAgIHByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhmaW5hbCk7XG5cbiAgICB2YXIgdXBkYXRlU3R5bGVzID0gKCkgPT4ge1xuICAgICAgbGV0IHMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XG4gICAgICBwcm9wZXJ0aWVzLmZvckVhY2gocy5nZXRQcm9wZXJ0eVZhbHVlLmJpbmQocykpO1xuICAgICAgcyA9IGVsLm9mZnNldEhlaWdodDtcbiAgICB9O1xuXG4gICAgdmFyIHJlc3VsdCA9IHtcbiAgICAgIHN0b3A6IChvcHRpb25zID0ge30pID0+IHtcbiAgICAgICAgdGltZW91dCAmJiBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHZhciBrID0gTWF0aC5taW4oMSwgKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCkgLSBzdGFydCkgLyBkdXJhdGlvbik7XG4gICAgICAgIHByb3BlcnRpZXMuZm9yRWFjaChpID0+IHtcbiAgICAgICAgICBlbC5zdHlsZVtpXSA9ICgxIC0gaykgKiBpbml0aWFsW2ldICsgayAqIGZpbmFsW2ldICsgKGkgPT0gJ29wYWNpdHknID8gJycgOiAncHgnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVsLnN0eWxlLnRyYW5zaXRpb25EdXJhdGlvbiA9ICcwcyc7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuc3RvcE5leHQpIHtcbiAgICAgICAgICBuZXh0ID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSBpZiAoIXN0b3BwZWQpIHtcbiAgICAgICAgICBzdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICBuZXh0ICYmIG5leHQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSxcbiAgICAgIHRoZW46IChjYikgPT4ge1xuICAgICAgICBuZXh0ID0gY2I7XG4gICAgICAgIGlmIChzdG9wcGVkKSB7XG4gICAgICAgICAgbmV4dCAmJiBuZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICBzcGVlZDogKG5ld0R1cmF0aW9uKSA9PiB7XG4gICAgICAgIGlmIChpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgICAgICAgbmV3RHVyYXRpb24gPSAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc3RvcHBlZCkge1xuICAgICAgICAgIHRpbWVvdXQgJiYgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgICAgY29uc3QgcGFzc2VkID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAtIHN0YXJ0O1xuICAgICAgICAgIGNvbnN0ICBrID0gcGFzc2VkIC8gZHVyYXRpb247XG4gICAgICAgICAgY29uc3QgcmVtYWluaW5nID0gbmV3RHVyYXRpb24gKiAoMSAtIGspO1xuXG4gICAgICAgICAgcHJvcGVydGllcy5mb3JFYWNoKGkgPT4ge1xuICAgICAgICAgICAgZWwuc3R5bGVbaV0gPSAoMSAtIGspICogaW5pdGlhbFtpXSArIGsgKiBmaW5hbFtpXSArIChpID09ICdvcGFjaXR5JyA/ICcnIDogJ3B4Jyk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB1cGRhdGVTdHlsZXMoKTtcblxuICAgICAgICAgIHN0YXJ0ID0gZWwuc3BlZWRVcFRpbWU7XG4gICAgICAgICAgZHVyYXRpb24gPSByZW1haW5pbmc7XG5cbiAgICAgICAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBkdXJhdGlvbiAvIDEwMDAgKyAncyc7XG5cbiAgICAgICAgICBwcm9wZXJ0aWVzLmZvckVhY2goaSA9PiB7XG4gICAgICAgICAgICBlbC5zdHlsZVtpXSA9IGZpbmFsW2ldICsgKGkgPT0gJ29wYWNpdHknID8gJycgOiAncHgnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KHJlc3VsdC5zdG9wLCByZW1haW5pbmcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgICAgZmluaXNoOiAobWlsbGlzZWNvbmRzID0gNTApID0+IHtcbiAgICAgICAgdmFyIGsgPSAoKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAtIHN0YXJ0KSAvIGR1cmF0aW9uO1xuXG4gICAgICAgIHJlc3VsdC5zcGVlZChtaWxsaXNlY29uZHMgLyAoMSAtIGspKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKGVsLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSB8fCBzdG9wcGVkIHx8IGludGVybmFsLmNvbmZpZy5hbmltYXRpb25zRGlzYWJsZWQpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICAgIHByb3BlcnRpZXMuZm9yRWFjaChlID0+IHtcbiAgICAgIGNvbnN0IHYgPSBwYXJzZUZsb2F0KHN0eWxlLmdldFByb3BlcnR5VmFsdWUoZSkpO1xuICAgICAgaW5pdGlhbFtlXSA9IGlzTmFOKHYpID8gMCA6IHY7XG4gICAgfSk7XG5cblxuICAgIGlmICghc3RvcHBlZCkge1xuICAgICAgZWwuc3R5bGUudHJhbnNpdGlvblByb3BlcnR5ID0gcHJvcGVydGllcy5qb2luKCcsJyk7XG4gICAgICBlbC5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSBkdXJhdGlvbiAvIDEwMDAgKyAncyc7XG5cbiAgICAgIHByb3BlcnRpZXMuZm9yRWFjaChlID0+IHtcbiAgICAgICAgZWwuc3R5bGVbZV0gPSBmaW5hbFtlXSArIChlID09ICdvcGFjaXR5JyA/ICcnIDogJ3B4Jyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dChyZXN1bHQuc3RvcCwgZHVyYXRpb24pO1xuICAgIHRoaXMuX29uU3RvcEFuaW1hdGlvbnMoZWwsIHJlc3VsdC5zdG9wKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLl9xdWV1ZSA9IFtdO1xuICAgIHRoaXMuX2luZGV4ID0gMDtcbiAgfVxuXG4gIF9vblN0b3BBbmltYXRpb25zKGVsLCBsaXN0ZW5lcikge1xuICAgIHZhciBxdWV1ZSA9IHRoaXMuX3F1ZXVlO1xuICAgIHZhciBpID0gdGhpcy5faW5kZXgrKztcbiAgICBxdWV1ZVtlbF0gPSBxdWV1ZVtlbF0gfHwgW107XG4gICAgcXVldWVbZWxdW2ldID0gKG9wdGlvbnMpID0+IHtcbiAgICAgIGRlbGV0ZSBxdWV1ZVtlbF1baV07XG4gICAgICBpZiAocXVldWVbZWxdICYmIHF1ZXVlW2VsXS5sZW5ndGggPT0gMCkge1xuICAgICAgICBkZWxldGUgcXVldWVbZWxdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxpc3RlbmVyKG9wdGlvbnMpO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgKiBAbWV0aG9kIHN0b3BBbmltYXRpb25zXG4gICogQGRlc2Mgc3RvcHMgYWN0aXZlIGFuaW1hdGlvbnMgb24gYSBzcGVjaWZpZWQgZWxlbWVudFxuICAqIEBwYXJhbSB7RWxlbWVudHxBcnJheX0gZWxlbWVudCAtIGVsZW1lbnQgb3IgYXJyYXkgb2YgZWxlbWVudHNcbiAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dXG4gICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5zdG9wTmV4dF0gLSB0aGUgY2FsbGJhY2tzIGFmdGVyIHRoZSBhbmltYXRpb25zIHdvbid0IGJlIGNhbGxlZCBpZiB0aGlzIG9wdGlvbiBpcyB0cnVlXG4gICovXG4gIHN0b3BBbmltYXRpb25zKGVsLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbCkpIHtcbiAgICAgIHJldHVybiBlbC5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgdGhpcy5zdG9wQW5pbWF0aW9ucyhlbCwgb3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAodGhpcy5fcXVldWVbZWxdIHx8IFtdKS5mb3JFYWNoKGUgPT4geyBlKG9wdGlvbnMgfHwge30pOyB9KTtcbiAgfVxuXG4gIC8qKlxuICAqIEBtZXRob2Qgc3RvcEFsbFxuICAqIEBkZXNjIHN0b3BzIGFsbCBhY3RpdmUgYW5pbWF0aW9uc1xuICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV1cbiAgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnN0b3BOZXh0XSAtIHRoZSBjYWxsYmFja3MgYWZ0ZXIgdGhlIGFuaW1hdGlvbnMgd29uJ3QgYmUgY2FsbGVkIGlmIHRoaXMgb3B0aW9uIGlzIHRydWVcbiAgKi9cbiAgc3RvcEFsbChvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLnN0b3BBbmltYXRpb25zKE9iamVjdC5rZXlzKHRoaXMuX3F1ZXVlKSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgKiBAbWV0aG9kIGZhZGVcbiAgKiBAZGVzYyBmYWRlcyB0aGUgZWxlbWVudCAoc2hvcnQgdmVyc2lvbiBmb3IgYW5pbWF0ZShlbCwge29wYWNpdHk6IDB9KSlcbiAgKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAgKiBAcGFyYW0ge251bWJlcn0gW2R1cmF0aW9uPTIwMF1cbiAgKi9cbiAgZmFkZShlbCwgZHVyYXRpb24gPSAyMDApIHtcbiAgICByZXR1cm4gdGhpcy5hbmltYXRlKGVsLCB7b3BhY2l0eTogMH0sIGR1cmF0aW9uKTtcbiAgfVxuXG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuaW1hdG9yQ1NTO1xuXG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBpbnRlcm5hbCBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBBbmltYXRvciBmcm9tICcuL2FuaW1hdG9yLWNzcyc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uLy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ3JpcHBsZSc7XG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAncmlwcGxlLS0qJyxcbiAgJy5yaXBwbGVfX3dhdmUnOiAncmlwcGxlLS0qX193YXZlJyxcbiAgJy5yaXBwbGVfX2JhY2tncm91bmQnOiAncmlwcGxlLS0qX19iYWNrZ3JvdW5kJyxcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXJpcHBsZVxuICogQGNhdGVnb3J5IHZpc3VhbFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBBZGRzIGEgTWF0ZXJpYWwgRGVzaWduIFwicmlwcGxlXCIgZWZmZWN0IHRvIGFuIGVsZW1lbnQuIFRoZSByaXBwbGUgZWZmZWN0IHdpbGwgc3ByZWFkIGZyb20gdGhlIHBvc2l0aW9uIHdoZXJlIHRoZSB1c2VyIHRhcHMuXG4gKlxuICogICAgIFNvbWUgZWxlbWVudHMgc3VjaCBhcyBgPG9ucy1idXR0b24+YCBhbmQgYDxvbnMtZmFiPmAgIHN1cHBvcnQgYSBgcmlwcGxlYCBhdHRyaWJ1dGUuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV3jg57jg4bjg6rjgqLjg6vjg4fjgrbjgqTjg7Pjga7jg6rjg4Pjg5fjg6vlirnmnpzjgpJET03opoHntKDjgavov73liqDjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gd0tRV2RaXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvcmlwcGxlXG4gKiBAbW9kaWZpZXIgbGlnaHQtZ3JheVxuICogICBbZW5dQ2hhbmdlIHRoZSBjb2xvciBvZiBlZmZlY3RzIHRvIGxpZ2h0IGdyYXkuWy9lbl1cbiAqICAgW2phXeOCqOODleOCp+OCr+ODiOOBruiJsuOBjOaYjuOCi+OBhOeBsOiJsuOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI2Nyb3NzLXBsYXRmb3JtLXN0eWxpbmctYXV0b3N0eWxpbmdcbiAqICBbZW5dQ3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svZW5dXG4gKiAgW2phXUNyb3NzIHBsYXRmb3JtIHN0eWxpbmdbL2phXVxuICogQGV4YW1wbGVcbiAqIDxkaXYgY2xhc3M9XCJteS1kaXZcIj5cbiAqICA8b25zLXJpcHBsZT48L29ucy1yaXBwbGU+XG4gKiA8L2Rpdj5cbiAqXG4gKiBAZXhhbXBsZVxuICogPG9ucy1idXR0b24gcmlwcGxlPkNsaWNrIG1lITwvb25zLWJ1dHRvbj5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmlwcGxlRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjb2xvclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ29sb3Igb2YgdGhlIHJpcHBsZSBlZmZlY3QuWy9lbl1cbiAgICogICBbamFd44Oq44OD44OX44Or44Ko44OV44Kn44Kv44OI44Gu6Imy44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBhcHBlYXJhbmNlIG9mIHRoZSByaXBwbGUgZWZmZWN0LlsvZW5dXG4gICAqICAgW2phXeOCqOODleOCp+OCr+ODiOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGJhY2tncm91bmRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUNvbG9yIG9mIHRoZSBiYWNrZ3JvdW5kLlsvZW5dXG4gICAqICAgW2phXeiDjOaZr+OBruiJsuOCkuioreWumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHNpemVcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNpemluZyBvZiB0aGUgd2F2ZSBvbiByaXBwbGUgZWZmZWN0LiBTZXQgXCJjb3ZlclwiIG9yIFwiY29udGFpblwiLiBEZWZhdWx0IGlzIFwiY292ZXJcIi5bL2VuXVxuICAgKiAgIFtqYV3jgqjjg5Xjgqfjgq/jg4jjga7jgrXjgqTjgrrjgpLmjIflrprjgZfjgb7jgZnjgIJcImNvdmVyXCLjgoLjgZfjgY/jga9cImNvbnRhaW5cIuOCkuaMh+WumuOBl+OBvuOBmeOAguODh+ODleOCqeODq+ODiOOBr1wiY292ZXJcIuOBp+OBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGNlbnRlclxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIHByZXNlbnRzLCBjaGFuZ2UgdGhlIHBvc2l0aW9uIG9mIHdhdmUgZWZmZWN0IHRvIGNlbnRlciBvZiB0aGUgdGFyZ2V0IGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFd44GT44Gu6KaB57Sg44KS6Kit5a6a44GZ44KL44Go44CB44Ko44OV44Kn44Kv44OI44Gu5L2N572u44GM6KaB57Sg44Gu55yf44KT5Lit44GL44KJ5aeL44G+44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCwgdGhlIHJpcHBsZSBlZmZlY3Qgd2lsbCBiZSBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzoqK3lrprjgZXjgozjgZ/loLTlkIjjgIHjg6rjg4Pjg5fjg6vjgqjjg5Xjgqfjgq/jg4jjga/nhKHlirnjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fb25UYXAgPSB0aGlzLl9vblRhcC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uSG9sZCA9IHRoaXMuX29uSG9sZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uRHJhZ1N0YXJ0ID0gdGhpcy5fb25EcmFnU3RhcnQuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9vblJlbGVhc2UgPSB0aGlzLl9vblJlbGVhc2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuXG4gICAgdGhpcy5fYW5pbWF0b3IgPSBuZXcgQW5pbWF0b3IoKTtcblxuICAgIFsnY29sb3InLCAnY2VudGVyJywgJ3N0YXJ0LXJhZGl1cycsICdiYWNrZ3JvdW5kJywgJ21vZGlmaWVyJ10uZm9yRWFjaChlID0+IHtcbiAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKGUsIG51bGwsIHRoaXMuZ2V0QXR0cmlidXRlKGUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIHRoaXMuY2xhc3NMaXN0LmFkZChkZWZhdWx0Q2xhc3NOYW1lKTtcblxuICAgIHRoaXMuX3dhdmUgPSB0aGlzLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3JpcHBsZV9fd2F2ZScpWzBdO1xuICAgIHRoaXMuX2JhY2tncm91bmQgPSB0aGlzLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3JpcHBsZV9fYmFja2dyb3VuZCcpWzBdO1xuXG4gICAgaWYgKCEodGhpcy5fYmFja2dyb3VuZCAmJiB0aGlzLl93YXZlKSkge1xuICAgICAgdGhpcy5fd2F2ZSA9IHV0aWwuY3JlYXRlKCcucmlwcGxlX193YXZlJyk7XG4gICAgICB0aGlzLl9iYWNrZ3JvdW5kID0gdXRpbC5jcmVhdGUoJy5yaXBwbGVfX2JhY2tncm91bmQnKTtcblxuICAgICAgdGhpcy5hcHBlbmRDaGlsZCh0aGlzLl93YXZlKTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQodGhpcy5fYmFja2dyb3VuZCk7XG4gICAgfVxuXG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICB9XG5cbiAgX2dldEVmZmVjdFNpemUoKSB7XG4gICAgY29uc3Qgc2l6ZXMgPSBbJ2NvdmVyJywgJ2NvbnRhaW4nXTtcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ3NpemUnKSkge1xuICAgICAgY29uc3Qgc2l6ZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCdzaXplJyk7XG4gICAgICBpZiAoc2l6ZXMuaW5kZXhPZihzaXplKSAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIHNpemU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICdjb3Zlcic7XG4gIH1cblxuICBfY2FsY3VsYXRlQ29vcmRzKGUpIHtcbiAgICBsZXQgeCwgeSwgaCwgdywgcjtcbiAgICBjb25zdCBiID0gdGhpcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5fZ2V0RWZmZWN0U2l6ZSgpO1xuICAgIGNvbnN0IGVycm9yID0gKCkgPT4gdXRpbC50aHJvdygnUmlwcGxlIGludmFsaWQgc3RhdGUnKTtcblxuICAgIGlmICh0aGlzLl9jZW50ZXIpIHtcbiAgICAgIHggPSBiLndpZHRoIC8gMjtcbiAgICAgIHkgPSBiLmhlaWdodCAvIDI7XG5cbiAgICAgIGlmIChzaXplID09PSAnY292ZXInKSB7XG4gICAgICAgIHIgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7XG4gICAgICB9IGVsc2UgaWYgKHNpemUgPT09ICdjb250YWluJykge1xuICAgICAgICByID0gTWF0aC5taW4oeCwgeSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcigpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0gKHR5cGVvZiBlLmNsaWVudFggPT09ICdudW1iZXInID8gZS5jbGllbnRYIDogZS5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYKSAtIGIubGVmdDtcbiAgICAgIHkgPSAodHlwZW9mIGUuY2xpZW50WSA9PT0gJ251bWJlcicgPyBlLmNsaWVudFkgOiBlLmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFkpIC0gYi50b3A7XG4gICAgICBoID0gTWF0aC5tYXgoeSwgYi5oZWlnaHQgLSB5KTtcbiAgICAgIHcgPSBNYXRoLm1heCh4LCBiLndpZHRoIC0geCk7XG5cbiAgICAgIGlmIChzaXplID09PSAnY292ZXInKSB7XG4gICAgICAgIHIgPSBNYXRoLnNxcnQoaCAqIGggKyB3ICogdyk7XG4gICAgICB9IGVsc2UgaWYgKHNpemUgPT09ICdjb250YWluJykge1xuICAgICAgICByID0gTWF0aC5taW4oTWF0aC5yb3VuZChoIC8gMiksIE1hdGgucm91bmQodyAvIDIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt4LCB5LCByfTtcbiAgfVxuXG4gIF9yaXBwbGVBbmltYXRpb24oZSwgZHVyYXRpb24gPSAzMDApIHtcbiAgICBjb25zdCB7X2FuaW1hdG9yLCBfd2F2ZSwgX2JhY2tncm91bmQsIF9taW5SfSA9IHRoaXM7XG4gICAgY29uc3Qge3gsIHksIHJ9ID0gdGhpcy5fY2FsY3VsYXRlQ29vcmRzKGUpO1xuXG4gICAgX2FuaW1hdG9yLnN0b3BBbGwoe3N0b3BOZXh0OiAxfSk7XG4gICAgX2FuaW1hdG9yLmFuaW1hdGUoX2JhY2tncm91bmQsIHtvcGFjaXR5OiAxfSwgZHVyYXRpb24pO1xuXG4gICAgdXRpbC5leHRlbmQoX3dhdmUuc3R5bGUsIHtcbiAgICAgIG9wYWNpdHk6IDEsXG4gICAgICB0b3A6IHkgLSBfbWluUiArICdweCcsXG4gICAgICBsZWZ0OiB4IC0gX21pblIgKyAncHgnLFxuICAgICAgd2lkdGg6IDIgKiBfbWluUiArICdweCcsXG4gICAgICBoZWlnaHQ6IDIgKiBfbWluUiArICdweCdcbiAgICB9KTtcblxuICAgIHJldHVybiBfYW5pbWF0b3IuYW5pbWF0ZShfd2F2ZSwge1xuICAgICAgdG9wOiB5IC0gcixcbiAgICAgIGxlZnQ6IHggLSByLFxuICAgICAgaGVpZ2h0OiAyICogcixcbiAgICAgIHdpZHRoOiAyICogclxuICAgIH0sIGR1cmF0aW9uKTtcbiAgfVxuXG4gIF91cGRhdGVQYXJlbnQoKSB7XG4gICAgaWYgKCF0aGlzLl9wYXJlbnRVcGRhdGVkICYmIHRoaXMucGFyZW50Tm9kZSkge1xuICAgICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMucGFyZW50Tm9kZSk7XG4gICAgICBpZiAoY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCdwb3NpdGlvbicpID09PSAnc3RhdGljJykge1xuICAgICAgICB0aGlzLnBhcmVudE5vZGUuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgfVxuICAgICAgdGhpcy5fcGFyZW50VXBkYXRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgX29uVGFwKGUpIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQgJiYgIWUucmlwcGxlKSB7XG4gICAgICBlLnJpcHBsZSA9IHRydWU7XG4gICAgICB0aGlzLl91cGRhdGVQYXJlbnQoKTtcbiAgICAgIHRoaXMuX3JpcHBsZUFuaW1hdGlvbihlLmdlc3R1cmUuc3JjRXZlbnQpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLl9hbmltYXRvci5mYWRlKHRoaXMuX3dhdmUpO1xuICAgICAgICB0aGlzLl9hbmltYXRvci5mYWRlKHRoaXMuX2JhY2tncm91bmQpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX29uSG9sZChlKSB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkICYmICFlLnJpcHBsZSkge1xuICAgICAgZS5yaXBwbGUgPSB0cnVlO1xuICAgICAgdGhpcy5fdXBkYXRlUGFyZW50KCk7XG4gICAgICB0aGlzLl9ob2xkaW5nID0gdGhpcy5fcmlwcGxlQW5pbWF0aW9uKGUuZ2VzdHVyZS5zcmNFdmVudCwgMjAwMCk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWxlYXNlJywgdGhpcy5fb25SZWxlYXNlKTtcbiAgICB9XG4gIH1cblxuICBfb25SZWxlYXNlKGUpIHtcbiAgICBpZiAodGhpcy5faG9sZGluZyAmJiAhZS5yaXBwbGUpIHtcbiAgICAgIGUucmlwcGxlID0gdHJ1ZTtcbiAgICAgIHRoaXMuX2hvbGRpbmcuc3BlZWQoMzAwKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fYW5pbWF0b3Iuc3RvcEFsbCh7c3RvcE5leHQ6IHRydWV9KTtcbiAgICAgICAgdGhpcy5fYW5pbWF0b3IuZmFkZSh0aGlzLl93YXZlKTtcbiAgICAgICAgdGhpcy5fYW5pbWF0b3IuZmFkZSh0aGlzLl9iYWNrZ3JvdW5kKTtcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLl9ob2xkaW5nID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVsZWFzZScsIHRoaXMuX29uUmVsZWFzZSk7XG4gIH1cblxuICBfb25EcmFnU3RhcnQoZSkge1xuICAgIGlmICh0aGlzLl9ob2xkaW5nKSB7XG4gICAgICByZXR1cm4gdGhpcy5fb25SZWxlYXNlKGUpO1xuICAgIH1cbiAgICBpZiAoWydsZWZ0JywgJ3JpZ2h0J10uaW5kZXhPZihlLmdlc3R1cmUuZGlyZWN0aW9uKSAhPSAtMSkge1xuICAgICAgdGhpcy5fb25UYXAoZSk7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5fcGFyZW50Tm9kZSA9IHRoaXMucGFyZW50Tm9kZTtcblxuICAgIGlmIChpbnRlcm5hbC5jb25maWcuYW5pbWF0aW9uc0Rpc2FibGVkKSB7XG4gICAgICB0aGlzLmRpc2FibGVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcGFyZW50Tm9kZS5hZGRFdmVudExpc3RlbmVyKCd0YXAnLCB0aGlzLl9vblRhcCk7XG4gICAgICB0aGlzLl9wYXJlbnROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2hvbGQnLCB0aGlzLl9vbkhvbGQpO1xuICAgICAgdGhpcy5fcGFyZW50Tm9kZS5hZGRFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCB0aGlzLl9vbkRyYWdTdGFydCk7XG4gICAgfVxuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgY29uc3QgcG4gPSB0aGlzLl9wYXJlbnROb2RlIHx8IHRoaXMucGFyZW50Tm9kZTtcbiAgICBwbi5yZW1vdmVFdmVudExpc3RlbmVyKCd0YXAnLCB0aGlzLl9vblRhcCk7XG4gICAgcG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignaG9sZCcsIHRoaXMuX29uSG9sZCk7XG4gICAgcG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZ3N0YXJ0JywgdGhpcy5fb25EcmFnU3RhcnQpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnc3RhcnQtcmFkaXVzJywgJ2NvbG9yJywgJ2JhY2tncm91bmQnLCAnY2VudGVyJywgJ2NsYXNzJywgJ21vZGlmaWVyJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuXG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc3RhcnQtcmFkaXVzJzpcbiAgICAgICAgdGhpcy5fbWluUiA9IE1hdGgubWF4KDAsIHBhcnNlRmxvYXQoY3VycmVudCkgfHwgMCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdjb2xvcic6XG4gICAgICAgIGlmIChjdXJyZW50KSB7XG4gICAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3dhdmUuc3R5bGUuYmFja2dyb3VuZCA9IGN1cnJlbnQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFzQXR0cmlidXRlKCdiYWNrZ3JvdW5kJykpIHtcbiAgICAgICAgICAgICAgdGhpcy5fYmFja2dyb3VuZC5zdHlsZS5iYWNrZ3JvdW5kID0gY3VycmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYmFja2dyb3VuZCc6XG4gICAgICAgIGlmIChjdXJyZW50IHx8IGxhc3QpIHtcbiAgICAgICAgICBpZiAoY3VycmVudCA9PT0gJ25vbmUnKSB7XG4gICAgICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZSgnZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgdGhpcy5fYmFja2dyb3VuZC5zdHlsZS5iYWNrZ3JvdW5kID0gJ3RyYW5zcGFyZW50JztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAodGhpcy5fYmFja2dyb3VuZC5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kLnJlbW92ZUF0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLl9iYWNrZ3JvdW5kLnN0eWxlLmJhY2tncm91bmQgPSBjdXJyZW50O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICBpZiAobmFtZSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgICB0aGlzLl9jZW50ZXIgPSBjdXJyZW50ICE9IG51bGwgJiYgY3VycmVudCAhPSAnZmFsc2UnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZGlzYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBleOCjOOBpuOBhOOCi+WgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuICBzZXQgZGlzYWJsZWQodmFsdWUpIHtcbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5SaXBwbGUgPSBSaXBwbGVFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtcmlwcGxlJywgUmlwcGxlRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCBCYXNlRWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1lbGVtZW50JztcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtcm93XG4gKiBAY2F0ZWdvcnkgZ3JpZFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1SZXByZXNlbnRzIGEgcm93IGluIHRoZSBncmlkIHN5c3RlbS4gVXNlIHdpdGggYDxvbnMtY29sPmAgdG8gbGF5b3V0IGNvbXBvbmVudHMuWy9lbl1cbiAqICAgW2phXeOCsOODquODg+ODieOCt+OCueODhuODoOOBq+OBpuihjOOCkuWumue+qeOBl+OBvuOBmeOAgm9ucy1jb2zjgajjgajjgoLjgavkvb/nlKjjgZfjgIHjgrPjg7Pjg53jg7zjg43jg7Pjg4jjga7phY3nva7jgavkvb/nlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gR2d1akMge3dpZGV9XG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sXG4gKiAgIFtlbl1MYXlvdXRpbmcgZ3VpZGVbL2VuXVxuICogICBbamFd44Os44Kk44Ki44Km44OI6Kq/5pW0Wy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1jb2xcbiAqICAgW2VuXVRoZSBgPG9ucy1jb2w+YCBjb21wb25lbnQgaXMgdXNlZCBhcyBjaGlsZHJlbiBvZiBgPG9ucy1yb3c+YC5bL2VuXVxuICogICBbamFdb25zLWNvbOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAbm90ZVxuICogICBbZW5dRm9yIEFuZHJvaWQgNC4zIGFuZCBlYXJsaWVyLCBhbmQgaU9TNiBhbmQgZWFybGllciwgd2hlbiB1c2luZyBtaXhlZCBhbGlnbm1lbnQgd2l0aCBvbnMtcm93IGFuZCBvbnMtY29sLCB0aGV5IG1heSBub3QgYmUgZGlzcGxheWVkIGNvcnJlY3RseS4gWW91IGNhbiB1c2Ugb25seSBvbmUgdmVydGljYWwtYWxpZ24uWy9lbl1cbiAqICAgW2phXUFuZHJvaWQgNC4z5Lul5YmN44CB44KC44GX44GP44GvaU9TIDbku6XliY3jga5PU+OBruWgtOWQiOOAgW9ucy1yb3fjgahvbnMtY29s44KS57WE44G/5ZCI44KP44Gb44Gm44Gd44KM44Ge44KM44Gub25zLWNvbOimgee0oOOBrnZlcnRpY2FsLWFsaWdu5bGe5oCn44Gu5YCk44Gr5Yil44CF44Gu5YCk44KS5oyH5a6a44GZ44KL44Go44CB5o+P55S744GM5bSp44KM44KL5aC05ZCI44GM44GC44KK44G+44GZ44CCdmVydGljYWwtYWxpZ27lsZ7mgKfjga7lgKTjgavjga/kuIDjgaTjga7lgKTjgaDjgZHjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtcm93PlxuICogICA8b25zLWNvbCB3aWR0aD1cIjUwcHhcIj48b25zLWljb24gaWNvbj1cImZhLXR3aXR0ZXJcIj48L29ucy1pY29uPjwvb25zLWNvbD5cbiAqICAgPG9ucy1jb2w+VGV4dDwvb25zLWNvbD5cbiAqIDwvb25zLXJvdz5cbiAqL1xuXG4vKipcbiAqIEBhdHRyaWJ1dGUgdmVydGljYWwtYWxpZ25cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVNob3J0IGhhbmQgYXR0cmlidXRlIGZvciBhbGlnbmluZyB2ZXJ0aWNhbGx5LiBWYWxpZCB2YWx1ZXMgYXJlIHRvcCwgYm90dG9tLCBhbmQgY2VudGVyLlsvZW5dXG4gKiAgIFtqYV3nuKbjgavmlbTliJfjgZnjgovjgZ/jgoHjgavmjIflrprjgZfjgb7jgZnjgIJ0b3DjgIFib3R0b23jgIFjZW50ZXLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJvd0VsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG59XG5cbm9uc0VsZW1lbnRzLlJvdyA9IFJvd0VsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1yb3cnLCBSb3dFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnc2VnbWVudCc7XG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnc2VnbWVudC0tKicsXG4gICcuc2VnbWVudF9faXRlbSc6ICdzZWdtZW50LS0qX19pdGVtJyxcbiAgJy5zZWdtZW50X19pbnB1dCc6ICdzZWdtZW50LS0qX19pbnB1dCcsXG4gICcuc2VnbWVudF9fYnV0dG9uJzogJ3NlZ21lbnQtLSpfX2J1dHRvbidcbn07XG5cbmNvbnN0IGdlbmVyYXRlSWQgPSAoKCkgPT4ge1xuICBsZXQgaSA9IDA7XG4gIHJldHVybiAoKSA9PiAnb25zLXNlZ21lbnQtZ2VuLScgKyAoaSsrKTtcbn0pKCk7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXNlZ21lbnRcbiAqIEBjYXRlZ29yeSBjb250cm9sXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICAgW2VuXU1hdGVyaWFsIERlc2lnbiBzZWdtZW50Wy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXVxuICogICAgIFNlZ21lbnQgY29tcG9uZW50LiBVc2UgdGhpcyBjb21wb25lbnQgdG8gaGF2ZSBhIGJ1dHRvbiBiYXIgd2l0aCBhdXRvbWF0aWMgc3R5bGVzIHRoYXQgc3dpdGNoIG9uIGNsaWNrIG9mIGFub3RoZXIgYnV0dG9uLlxuICpcbiAqICAgICBXaWxsIGF1dG9tYXRpY2FsbHkgZGlzcGxheSBhcyBhIE1hdGVyaWFsIERlc2lnbiBzZWdtZW50IG9uIEFuZHJvaWQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4gaExheXhcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zZWdtZW50XG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjY3Jvc3MtcGxhdGZvcm0tc3R5bGluZy1hdXRvc3R5bGluZyBbZW5dSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svZW5dW2phXUluZm9ybWF0aW9uIGFib3V0IGNyb3NzIHBsYXRmb3JtIHN0eWxpbmdbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtc2VnbWVudD5cbiAqICAgPG9ucy1idXR0b24+TGFiZWwgMTwvb25zLWJ1dHRvbj5cbiAqICAgPG9ucy1idXR0b24+TGFiZWwgMjwvb25zLWJ1dHRvbj5cbiAqICAgPG9ucy1idXR0b24+TGFiZWwgMzwvb25zLWJ1dHRvbj5cbiAqIDwvb25zLXNlZ21lbnQ+XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VnbWVudEVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0Y2hhbmdlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlcyBhZnRlciB0aGUgYWN0aXZlIGJ1dHRvbiBpcyBjaGFuZ2VkLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgKiAgIFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV2ZW50LmluZGV4XG4gICAqICAgW2VuXVRhcHBlZCBidXR0b24gaW5kZXguWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50LnNlZ21lbnRJdGVtXG4gICAqICAgW2VuXVNlZ21lbnQgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kaWZpZXJcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHNlZ21lbnQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSB0YWJiYXItaWRcbiAgICogQGluaXRvbmx5XG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUlEIG9mIHRoZSB0YWJiYXIgZWxlbWVudCB0byBcImNvbm5lY3RcIiB0byB0aGUgc2VnbWVudC4gTXVzdCBiZSBpbnNpZGUgdGhlIHNhbWUgcGFnZS5bL2VuXVxuICAgKiAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFjdGl2ZS1pbmRleFxuICAgKiBAaW5pdG9ubHlcbiAgICogQGRlZmF1bHQgMFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JbmRleCBvZiB0aGUgZmlyc3QgYWN0aXZlIGJ1dHRvbiwgb25seSB3b3JrcyBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgdGFiYmFyIChpbiB3aGljaCBjYXNlIHRoZSBhY3RpdmUgdGFiIHNldHMgdGhlIGFjdGl2ZSBidXR0b24pLlsvZW5dXG4gICAqICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgaWYgc2VnbWVudCBzaG91bGQgYmUgZGlzYWJsZWQuWy9lbl1cbiAgICogICBbamFd44Oc44K/44Oz44KS54Sh5Yq55YyW44GZ44KL5aC05ZCI44Gv5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fc2VnbWVudElkID0gZ2VuZXJhdGVJZCgpO1xuICAgIHRoaXMuX3RhYmJhciA9IG51bGw7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uVGFiYmFyUHJlQ2hhbmdlID0gdGhpcy5fb25UYWJiYXJQcmVDaGFuZ2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb21waWxlKClcbiAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9sYXN0QWN0aXZlSW5kZXggPSB0aGlzLl90YWJiYXIgPyB0aGlzLl90YWJiYXIuZ2V0QWN0aXZlVGFiSW5kZXgoKSA6IHRoaXMuZ2V0QWN0aXZlQnV0dG9uSW5kZXgoKSk7XG4gICAgfSk7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaW5kZXggPj0gMDsgaW5kZXgtLSkge1xuICAgICAgY29uc3QgaXRlbSA9IHRoaXMuY2hpbGRyZW5baW5kZXhdO1xuICAgICAgaXRlbS5jbGFzc0xpc3QuYWRkKCdzZWdtZW50X19pdGVtJyk7XG5cbiAgICAgIGNvbnN0IGlucHV0ID0gdXRpbC5maW5kQ2hpbGQoaXRlbSwgJy5zZWdtZW50X19pbnB1dCcpIHx8IHV0aWwuY3JlYXRlKCdpbnB1dC5zZWdtZW50X19pbnB1dCcpO1xuICAgICAgaW5wdXQudHlwZSA9ICdyYWRpbyc7XG4gICAgICBpbnB1dC52YWx1ZSA9IGluZGV4O1xuICAgICAgaW5wdXQubmFtZSA9IGlucHV0Lm5hbWUgfHwgdGhpcy5fc2VnbWVudElkO1xuICAgICAgaW5wdXQuY2hlY2tlZCA9ICF0aGlzLmhhc0F0dHJpYnV0ZSgndGFiYmFyLWlkJykgJiYgaW5kZXggPT09IChwYXJzZUludCh0aGlzLmdldEF0dHJpYnV0ZSgnYWN0aXZlLWluZGV4JykpIHx8IDApO1xuXG4gICAgICBjb25zdCBidXR0b24gPSB1dGlsLmZpbmRDaGlsZChpdGVtLCAnLnNlZ21lbnRfX2J1dHRvbicpIHx8IHV0aWwuY3JlYXRlKCcuc2VnbWVudF9fYnV0dG9uJyk7XG4gICAgICBpZiAoYnV0dG9uLnBhcmVudEVsZW1lbnQgIT09IGl0ZW0pIHtcbiAgICAgICAgd2hpbGUgKGl0ZW0uZmlyc3RDaGlsZCkge1xuICAgICAgICAgIGJ1dHRvbi5hcHBlbmRDaGlsZChpdGVtLmZpcnN0Q2hpbGQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGl0ZW0uYXBwZW5kQ2hpbGQoaW5wdXQpO1xuICAgICAgaXRlbS5hcHBlbmRDaGlsZChidXR0b24pO1xuICAgIH1cblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ3RhYmJhci1pZCcpKSB7XG4gICAgICAgIGNvbnN0IHBhZ2UgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1wYWdlJyk7XG4gICAgICAgIHRoaXMuX3RhYmJhciA9IHBhZ2UgJiYgcGFnZS5xdWVyeVNlbGVjdG9yKCcjJyArIHRoaXMuZ2V0QXR0cmlidXRlKCd0YWJiYXItaWQnKSk7XG4gICAgICAgIGlmICghdGhpcy5fdGFiYmFyIHx8IHRoaXMuX3RhYmJhci50YWdOYW1lICE9PSAnT05TLVRBQkJBUicpIHtcbiAgICAgICAgICB1dGlsLnRocm93KGBObyB0YWJiYXIgd2l0aCBpZCAke3RoaXMuZ2V0QXR0cmlidXRlKCd0YWJiYXItaWQnKX0gd2FzIGZvdW5kLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdGFiYmFyLnNldEF0dHJpYnV0ZSgnaGlkZS10YWJzJywgJycpO1xuICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4gdGhpcy5fc2V0Q2hlY2tlZCh0aGlzLl90YWJiYXIuZ2V0QWN0aXZlVGFiSW5kZXgoKSkpO1xuXG4gICAgICAgIHRoaXMuX3RhYmJhci5hZGRFdmVudExpc3RlbmVyKCdwcmVjaGFuZ2UnLCB0aGlzLl9vblRhYmJhclByZUNoYW5nZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHRoaXMuX29uQ2hhbmdlKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fdGFiYmFyKSB7XG4gICAgICAgIHRoaXMuX3RhYmJhci5yZW1vdmVFdmVudExpc3RlbmVyKCdwcmVjaGFuZ2UnLCB0aGlzLl9vblRhYmJhclByZUNoYW5nZSk7XG4gICAgICAgIHRoaXMuX3RhYmJhciA9IG51bGw7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9vbkNoYW5nZSk7XG4gIH1cblxuICBfc2V0Q2hlY2tlZChpbmRleCkge1xuICAgIHRoaXMuY2hpbGRyZW5baW5kZXhdLmZpcnN0RWxlbWVudENoaWxkLmNoZWNrZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2Qgc2V0QWN0aXZlQnV0dG9uXG4gICAqIEBzaWduYXR1cmUgc2V0QWN0aXZlQnV0dG9uKGluZGV4LCBbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiAgIFtlbl1CdXR0b24gaW5kZXguWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LCB3b3JrcyBvbmx5IGlmIHRoZXJlIGlzIGEgY29ubmVjdGVkIHRhYmJhci4gU3VwcG9ydHMgdGhlIHNhbWUgb3B0aW9ucyBhcyBgb25zLXRhYmJhcmAncyBgc2V0QWN0aXZlVGFiYCBtZXRob2QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU1ha2UgYnV0dG9uIHdpdGggdGhlIHNwZWNpZmllZCBpbmRleCBhY3RpdmUuIElmIHRoZXJlIGlzIGEgY29ubmVjdGVkIHRhYmJhciBpdCBzaG93cyB0aGUgY29ycmVzcG9uZGluZyB0YWIgcGFnZS4gSW4gdGhpcyBjYXNlIGFuaW1hdGlvbnMgYW5kIHRoZWlyIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgc2Vjb25kIHBhcmFtZXRlci5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgc2VsZWN0ZWQgaW5kZXggb3IgdG8gdGhlIG5ldyBwYWdlIGVsZW1lbnQgaWYgdGhlcmUgaXMgYSBjb25uZWN0ZWQgdGFiYmFyLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBzZXRBY3RpdmVCdXR0b24oaW5kZXgsIG9wdGlvbnMpIHtcbiAgICBpZiAodGhpcy5fdGFiYmFyKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdGFiYmFyLnNldEFjdGl2ZVRhYihpbmRleCwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0Q2hlY2tlZChpbmRleCk7XG4gICAgdGhpcy5fcG9zdENoYW5nZShpbmRleCk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBnZXRBY3RpdmVCdXR0b25JbmRleFxuICAgKiBAc2lnbmF0dXJlIGdldEFjdGl2ZUJ1dHRvbkluZGV4KClcbiAgICogQHJldHVybiB7TnVtYmVyfVxuICAgKiAgIFtlbl1UaGUgaW5kZXggb2YgdGhlIGN1cnJlbnRseSBhY3RpdmUgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIGJ1dHRvbiBpbmRleCBvZiBjdXJyZW50IGFjdGl2ZSBidXR0b24uIElmIGFjdGl2ZSBidXR0b24gaXMgbm90IGZvdW5kLCByZXR1cm5zIC0xLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXRBY3RpdmVCdXR0b25JbmRleCgpIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgeyAvLyBBcnJheS5maW5kSW5kZXhcbiAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldLmZpcnN0RWxlbWVudENoaWxkLmNoZWNrZWQpIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIF9vbkNoYW5nZShldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuX3RhYmJhclxuICAgICAgPyB0aGlzLl90YWJiYXIuc2V0QWN0aXZlVGFiKHRoaXMuZ2V0QWN0aXZlQnV0dG9uSW5kZXgoKSwgeyByZWplY3Q6IGZhbHNlIH0pXG4gICAgICA6IHRoaXMuX3Bvc3RDaGFuZ2UodGhpcy5nZXRBY3RpdmVCdXR0b25JbmRleCgpKTtcbiAgfVxuXG4gIF9vblRhYmJhclByZUNoYW5nZShldmVudCkge1xuICAgIHNldEltbWVkaWF0ZSgoKSA9PiB7XG4gICAgICBpZiAoIWV2ZW50LmRldGFpbC5jYW5jZWxlZCkge1xuICAgICAgICB0aGlzLl9zZXRDaGVja2VkKGV2ZW50LmluZGV4KTtcbiAgICAgICAgdGhpcy5fcG9zdENoYW5nZShldmVudC5pbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBfcG9zdENoYW5nZShpbmRleCkge1xuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncG9zdGNoYW5nZScsIHtcbiAgICAgIGluZGV4LFxuICAgICAgYWN0aXZlSW5kZXg6IGluZGV4LFxuICAgICAgbGFzdEFjdGl2ZUluZGV4OiB0aGlzLl9sYXN0QWN0aXZlSW5kZXgsXG4gICAgICBzZWdtZW50SXRlbTogdGhpcy5jaGlsZHJlbltpbmRleF1cbiAgICB9KTtcbiAgICB0aGlzLl9sYXN0QWN0aXZlSW5kZXggPSBpbmRleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgZGlzYWJsZWRcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBzZWdtZW50IGlzIGRpc2FibGVkIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3nhKHlirnljJbjgZXjgozjgabjgYTjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgc2V0IGRpc2FibGVkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdkaXNhYmxlZCcsIHZhbHVlKTtcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2Rpc2FibGVkJyk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydjbGFzcycsICdtb2RpZmllciddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IGV2ZW50cygpIHtcbiAgICByZXR1cm4gWydwb3N0Y2hhbmdlJ107XG4gIH1cbn1cblxub25zRWxlbWVudHMuU2VnbWVudCA9IFNlZ21lbnRFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc2VnbWVudCcsIFNlZ21lbnRFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdzZWxlY3QtKiBzZWxlY3QtLSonLFxuICAnLnNlbGVjdC1pbnB1dCc6ICdzZWxlY3QtaW5wdXQtLSonXG59O1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ3NlbGVjdCc7XG5cbmNvbnN0IElOUFVUX0FUVFJJQlVURVMgPSBbXG4gICdhdXRvZm9jdXMnLFxuICAnZGlzYWJsZWQnLFxuICAnZm9ybScsXG4gICdtdWx0aXBsZScsXG4gICduYW1lJyxcbiAgJ3JlcXVpcmVkJyxcbiAgJ3NpemUnXG5dO1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1zZWxlY3RcbiAqIEBjYXRlZ29yeSBmb3JtXG4gKiBAbW9kaWZpZXIgbWF0ZXJpYWxcbiAqICBbZW5dRGlzcGxheXMgYSBNYXRlcmlhbCBEZXNpZ24gc2VsZWN0IGlucHV0LlsvZW5dXG4gKiAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgdW5kZXJiYXJcbiAqICBbZW5dRGlzcGxheXMgYSBob3Jpem9udGFsIGxpbmUgdW5kZXJuZWF0aCBhIHNlbGVjdCBpbnB1dC5bL2VuXVxuICogIFtqYV1bL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBTZWxlY3QgY29tcG9uZW50LiBJZiB5b3Ugd2FudCB0byBwbGFjZSBhIHNlbGVjdCB3aXRoIGFuIElEIG9mIGBteS1pZGAgb24gYSBwYWdlLCB1c2UgYDxvbnMtc2VsZWN0IHNlbGVjdC1pZD1cIm15LWlkXCI+YC5cbiAqXG4gKiAgICAgVGhlIGNvbXBvbmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgZGlzcGxheSBhcyBhIE1hdGVyaWFsIERlc2lnbiBzZWxlY3Qgb24gQW5kcm9pZC5cbiAqXG4gKiAgICAgTW9zdCBhdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGEgbm9ybWFsIGA8c2VsZWN0PmAgZWxlbWVudCBjYW4gYWxzbyBiZSB1c2VkIG9uIHRoZSBgPG9ucy1zZWxlY3Q+YCBlbGVtZW50LlxuICogICBbL2VuXVxuICogICBbamFd44K744Os44Kv44OI44Oc44OD44Kv44K544KS6KGo56S644GZ44KL44Kz44Oz44Od44O844ON44Oz44OI44Gn44GZ44CCYHNlbGVjdGAg6KaB57Sg44Gr5L2/55So44Gn44GN44KL5bGe5oCn44Gu5aSa44GP44GMIGBvbnMtc2VsZWN0YCDopoHntKDjgafjgoLliKnnlKjjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gaExheXhcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zZWxlY3RcbiAqIEBndWlkZSB0aGVtaW5nLmh0bWwjbW9kaWZpZXJzIFtlbl1Nb3JlIGRldGFpbHMgYWJvdXQgdGhlIGBtb2RpZmllcmAgYXR0cmlidXRlWy9lbl1bamFdbW9kaWZpZXLlsZ7mgKfjga7kvb/jgYTmlrlbL2phXVxuICogQGd1aWRlIHRoZW1pbmcuaHRtbCNjcm9zcy1wbGF0Zm9ybS1zdHlsaW5nLWF1dG9zdHlsaW5nIFtlbl1JbmZvcm1hdGlvbiBhYm91dCBjcm9zcyBwbGF0Zm9ybSBzdHlsaW5nWy9lbl1bamFdSW5mb3JtYXRpb24gYWJvdXQgY3Jvc3MgcGxhdGZvcm0gc3R5bGluZ1svamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1zZWxlY3Q+XG4gKiAgIDxvcHRpb24gdmFsdWU9XCIxXCI+MTwvb3B0aW9uPlxuICogICA8b3B0aW9uIHZhbHVlPVwiMlwiPjJuZDwvb3B0aW9uPlxuICogICA8b3B0aW9uIHZhbHVlPVwiM1wiPjNyZCBvcHRpb248L29wdGlvbj5cbiAqIDwvb25zLXNlbGVjdD5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTZWxlY3RFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGF1dG9mb2N1c1xuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dRWxlbWVudCBhdXRvbWF0aWNhbGx5IGdhaW5zIGZvY3VzIG9uIHBhZ2UgbG9hZC5bL2VuXVxuICAgKiAgW2phXeODmuODvOOCuOODreODvOODieaZguOBq+OBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOBq+ODleOCqeODvOOCq+OCueOBjOenu+OCi+OCiOOBhuOBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBzZWxlY3QgaW5wdXQgc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOCkueEoeWKueWMluOBmeOCi+WgtOWQiOOBq+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGZvcm1cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUFzc29jaWF0ZSBhIHNlbGVjdCBlbGVtZW50IHRvIGFuIGV4aXN0aW5nIGZvcm0gb24gdGhlIHBhZ2UsIGV2ZW4gaWYgbm90IG5lc3RlZC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jgrvjg6zjgq/jg4jjg5zjg4Pjgq/jgrnjgpLjgIHmjIflrprjgZfjgZ8gYGZvcm1gIOimgee0oOOBq+e0kOS7mOOBkeOBvuOBmeOAguOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOCkiBgZm9ybWAg6KaB57Sg44Gu5aSW5YG044Gr6YWN572u44GZ44KL6Zqb44Gr5L2/55So44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbXVsdGlwbGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIGRlZmluZWQsIG11bHRpcGxlIG9wdGlvbnMgY2FuIGJlIHNlbGVjdGVkIGF0IG9uY2UuWy9lbl1cbiAgICogIFtqYV3pgbjmip7ogqLjga7opIfmlbDpgbjmip7jgpLmnInlirnjgavjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBuYW1lXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1OYW1lIHRoZSBzZWxlY3QgZWxlbWVudCwgdXNlZnVsIGZvciBpbnN0YW5jZSBpZiBpdCBpcyBwYXJ0IG9mIGEgZm9ybS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7jgrvjg6zjgq/jg4jjg5zjg4Pjgq/jgrnjga7lkI3liY3jgpLmjIflrprjgZfjgb7jgZnjgILpgJrluLggYGZvcm1gIOimgee0oOOBqOWFseOBq+S9v+eUqOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJlcXVpcmVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dTWFrZSB0aGUgc2VsZWN0IGlucHV0IHJlcXVpcmVkIGZvciBzdWJtaXR0aW5nIHRoZSBmb3JtIGl0IGlzIHBhcnQgb2YuWy9lbl1cbiAgICogICBbamFd44GT44Gu44K744Os44Kv44OI44Oc44OD44Kv44K544KS5YWl5Yqb5b+F6aCI44Gr44GZ44KL5aC05ZCI44Gr5oyH5a6a44GX44G+44GZ44CC6YCa5bi4IGBmb3JtYCDopoHntKDjgajlhbHjgavkvb/nlKjjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzZWxlY3QtaWRcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlEIGdpdmVuIHRvIHRoZSBpbm5lciBzZWxlY3QsIHVzZWZ1bCBmb3IgZHluYW1pYyBtYW5pcHVsYXRpb24uWy9lbl1cbiAgICogICBbamFd44GT44Gu44K744Os44Kv44OI44Oc44OD44Kv44K544GM5YaF6YOo44Gr5oyB44GkIHNlbGVjdCDopoHntKDjgavkuI7jgYjjgosgSUQg44KS5oyH5a6a44GX44G+44GZ44CC44K744Os44Kv44OI44Oc44OD44Kv44K544Gu5YaF5a6544KS5YuV55qE44Gr5aSJ5pu044GZ44KL5b+F6KaB44GM44GC44KL5aC05ZCI44Gr5L2/55So44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc2l6ZVxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVmYXVsdCAxXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Ib3cgbWFueSBvcHRpb25zIGFyZSBkaXNwbGF5ZWQ7IGlmIHRoZXJlIGFyZSBtb3JlIHRoYW4gdGhlIHNpemUgdGhlbiBhIHNjcm9sbCBhcHBlYXJzIHRvIG5hdmlnYXRlIHRoZW0uWy9lbl1cbiAgICogICBbamFd5LiA5bqm44Gr6KGo56S644GZ44KL6YG45oqe6IKi44Gu5YCL5pWw44KS5oyH5a6a44GX44G+44GZ44CC6YG45oqe6IKi44GM44GT44Gu5bGe5oCn44Gn5oyH5a6a44GX44Gf5YCL5pWw44KI44KK44KC5aSa44GE5aC05ZCI44CB44K544Kv44Ot44O844Or44GM5pyJ5Yq544Gr44Gq44KK44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl9jb21waWxlKCkpO1xuXG4gICAgdGhpcy5fZGVyaXZlR2V0dGVycygpO1xuICB9XG5cbiAgc3RhdGljIGdldCBvYnNlcnZlZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnbW9kaWZpZXInLCAnY2xhc3MnLCAuLi5JTlBVVF9BVFRSSUJVVEVTXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKElOUFVUX0FUVFJJQlVURVMuaW5kZXhPZihuYW1lKSA+PSAwKSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlQm91bmRBdHRyaWJ1dGVzKCkpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBfc2VsZWN0KCkge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3IoJ3NlbGVjdCcpO1xuICB9XG5cbiAgX3VwZGF0ZUJvdW5kQXR0cmlidXRlcygpIHtcbiAgICBJTlBVVF9BVFRSSUJVVEVTLmZvckVhY2goKGF0dHIpID0+IHtcbiAgICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZShhdHRyKSkge1xuICAgICAgICB0aGlzLl9zZWxlY3Quc2V0QXR0cmlidXRlKGF0dHIsIHRoaXMuZ2V0QXR0cmlidXRlKGF0dHIpKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLl9zZWxlY3QucmVtb3ZlQXR0cmlidXRlKGF0dHIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBsZW5ndGhcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU51bWJlciBvZiBvcHRpb25zIGluIHRoZSBzZWxlY3QgYm94LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOBq+WQq+OBvuOCjOOCi+mBuOaKnuiCouOBruWAi+aVsOOCkui/lOOBl+OBvuOBmeOAgiBgc2VsZWN0YCDopoHntKBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9wdGlvbnNcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNldmVyYWwgb3B0aW9ucyBmb3IgaGFuZGxpbmcgdGhlIHNlbGVjdCBET00gb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCu+ODrOOCr+ODiOODnOODg+OCr+OCueOBq+WQq+OBvuOCjOOCiyBgb3B0aW9uYCDopoHntKDjga7phY3liJfjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHNlbGVjdGVkSW5kZXhcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUluZGV4IG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOmBuOaKnuOBleOCjOOBpuOBhOOCi+mBuOaKnuiCouOBruOCpOODs+ODh+ODg+OCr+OCueOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmFsdWVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVZhbHVlIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgb3B0aW9uLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOmBuOaKnuOBleOCjOOBpuOBhOOCi+mBuOaKnuiCouOBruWApOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuY2xhc3NMaXN0LmFkZChkZWZhdWx0Q2xhc3NOYW1lKTtcbiAgICBjb25zdCBzZWwgPSB0aGlzLl9zZWxlY3QgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2VsZWN0Jyk7XG4gICAgaWYgKCFzZWwuaWQgJiYgdGhpcy5oYXNBdHRyaWJ1dGUoJ3NlbGVjdC1pZCcpKSB7XG4gICAgICBzZWwuaWQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnc2VsZWN0LWlkJyk7XG4gICAgfVxuICAgIHNlbC5jbGFzc0xpc3QuYWRkKCdzZWxlY3QtaW5wdXQnKTtcbiAgICBpZiAoIXRoaXMuX3NlbGVjdCkge1xuICAgICAgdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZE5vZGVzKS5mb3JFYWNoKGVsZW1lbnQgPT4gc2VsLmFwcGVuZENoaWxkKGVsZW1lbnQpKTtcbiAgICAgIHRoaXMuYXBwZW5kQ2hpbGQoc2VsKTtcbiAgICB9XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG4gIH1cblxuICBfZGVyaXZlR2V0dGVycygpIHtcbiAgICBbJ2Rpc2FibGVkJywgJ2xlbmd0aCcsICdtdWx0aXBsZScsICduYW1lJywgJ29wdGlvbnMnLCAnc2VsZWN0ZWRJbmRleCcsICdzaXplJywgJ3ZhbHVlJywgJ2Zvcm0nLCAndHlwZSddXG4gICAgICAuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgZ2V0OiAoKSA9PiB0aGlzLl9zZWxlY3Rba2V5XSxcbiAgICAgICAgICBzZXQ6IFsnZm9ybScsICd0eXBlJ10uaW5kZXhPZihrZXkpID09PSAtMVxuICAgICAgICAgICAgPyB2YWx1ZSA9PiBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fc2VsZWN0W2tleV0gPSB2YWx1ZSlcbiAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBhZGQob3B0aW9uLCBpbmRleCA9IG51bGwpIHtcbiAgICB0aGlzLl9zZWxlY3QuYWRkKG9wdGlvbiwgaW5kZXgpO1xuICB9XG5cbiAgcmVtb3ZlKGluZGV4KSB7XG4gICAgdGhpcy5fc2VsZWN0LnJlbW92ZShpbmRleCk7XG4gIH1cbn1cblxub25zRWxlbWVudHMuU2VsZWN0ID0gU2VsZWN0RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXNlbGVjdCcsIFNlbGVjdEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGF1dG9TdHlsZSBmcm9tICcuLi9vbnMvYXV0b3N0eWxlJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ2ZhYiBmYWItLW1pbmkgc3BlZWQtZGlhbF9faXRlbSc7XG5cbmNvbnN0IHNjaGVtZSA9IHtcbiAgJyc6ICdmYWItLSogc3BlZWQtZGlhbF9faXRlbS0tKidcbn07XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXNwZWVkLWRpYWwtaXRlbVxuICogQGNhdGVnb3J5IGNvbnRyb2xcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhpcyBjb21wb25lbnQgZGlzcGxheXMgdGhlIGNoaWxkIGVsZW1lbnRzIG9mIHRoZSBNYXRlcmlhbCBEZXNpZ24gU3BlZWQgZGlhbCBjb21wb25lbnQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1cbiAqICAgICBNYXRlcmlhbCBEZXNpZ27jga5TcGVlZCBkaWFs44Gu5a2Q6KaB57Sg44KS6KGo54++44GZ44KL6KaB57Sg44Gn44GZ44CCXG4gKiAgIFsvamFdXG4gKiBAY29kZXBlbiBkWVFZTGdcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zcGVlZC1kaWFsXG4gKiBAc2VlYWxzbyBvbnMtc3BlZWQtZGlhbFxuICogICBbZW5dVGhlIGA8b25zLXNwZWVkLWRpYWw+YCBjb21wb25lbnQuWy9lbl1cbiAqICAgW2phXW9ucy1zcGVlZC1kaWFs44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1mYWJcbiAqICAgW2VuXW9ucy1mYWIgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1mYWLjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtc3BlZWQtZGlhbCBwb3NpdGlvbj1cImxlZnQgYm90dG9tXCI+XG4gKiAgIDxvbnMtZmFiPlxuICogICAgIDxvbnMtaWNvbiBpY29uPVwiZmEtdHdpdHRlclwiPjwvb25zLWljb24+XG4gKiAgIDwvb25zLWZhYj5cbiAqICAgPG9ucy1zcGVlZC1kaWFsLWl0ZW0+QTwvb25zLXNwZWVkLWRpYWwtaXRlbT5cbiAqICAgPG9ucy1zcGVlZC1kaWFsLWl0ZW0+Qjwvb25zLXNwZWVkLWRpYWwtaXRlbT5cbiAqICAgPG9ucy1zcGVlZC1kaWFsLWl0ZW0+Qzwvb25zLXNwZWVkLWRpYWwtaXRlbT5cbiAqIDwvb25zLXNwZWVkLWRpYWw+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwZWVkRGlhbEl0ZW1FbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgY29tcG9uZW50LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCs+ODs+ODneODvOODjeODs+ODiOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJpcHBsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBkZWZpbmVkLCB0aGUgYnV0dG9uIHdpbGwgaGF2ZSBhIHJpcHBsZSBlZmZlY3Qgd2hlbiB0YXBwZWQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIHRoaXMuX2JvdW5kT25DbGljayA9IHRoaXMuX29uQ2xpY2suYmluZCh0aGlzKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ21vZGlmaWVyJywgJ3JpcHBsZScsICdjbGFzcyddO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHtcbiAgICBzd2l0Y2ggKG5hbWUpIHtcbiAgICAgIGNhc2UgJ2NsYXNzJzpcbiAgICAgICAgdXRpbC5yZXN0b3JlQ2xhc3ModGhpcywgZGVmYXVsdENsYXNzTmFtZSwgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdtb2RpZmllcic6XG4gICAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgICB1dGlsLmFkZE1vZGlmaWVyKHRoaXMsICdtaW5pJyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlwcGxlJzpcbiAgICAgICAgdGhpcy5fdXBkYXRlUmlwcGxlKCk7XG4gICAgfVxuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2JvdW5kT25DbGljaywgZmFsc2UpO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2JvdW5kT25DbGljaywgZmFsc2UpO1xuICB9XG5cbiAgX3VwZGF0ZVJpcHBsZSgpIHtcbiAgICB1dGlsLnVwZGF0ZVJpcHBsZSh0aGlzKTtcbiAgfVxuXG4gIF9vbkNsaWNrKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgYXV0b1N0eWxlLnByZXBhcmUodGhpcyk7XG5cbiAgICBkZWZhdWx0Q2xhc3NOYW1lLnNwbGl0KC9cXHMrLykuZm9yRWFjaCh0b2tlbiA9PiB0aGlzLmNsYXNzTGlzdC5hZGQodG9rZW4pKTtcblxuICAgIHV0aWwuYWRkTW9kaWZpZXIodGhpcywgJ21pbmknKTtcbiAgICB0aGlzLl91cGRhdGVSaXBwbGUoKTtcblxuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5TcGVlZERpYWxJdGVtID0gU3BlZWREaWFsSXRlbUVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zcGVlZC1kaWFsLWl0ZW0nLCBTcGVlZERpYWxJdGVtRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBzdHlsZXIgZnJvbSAnLi4vb25zL3N0eWxlcic7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAnc3BlZWQtZGlhbCc7XG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnc3BlZWQtZGlhbC0tKicsXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1zcGVlZC1kaWFsXG4gKiBAY2F0ZWdvcnkgY29udHJvbFxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBFbGVtZW50IHRoYXQgZGlzcGxheXMgYSBNYXRlcmlhbCBEZXNpZ24gU3BlZWQgRGlhbG9nIGNvbXBvbmVudC4gSXQgaXMgdXNlZnVsIHdoZW4gdGhlcmUgYXJlIG1vcmUgdGhhbiBvbmUgcHJpbWFyeSBhY3Rpb24gdGhhdCBjYW4gYmUgcGVyZm9ybWVkIGluIGEgcGFnZS5cbiAqXG4gKiAgICAgVGhlIFNwZWVkIGRpYWwgbG9va3MgbGlrZSBhIGA8b25zLWZhYj5gIGVsZW1lbnQgYnV0IHdpbGwgZXhwYW5kIGEgbWVudSB3aGVuIHRhcHBlZC5cbiAqICAgWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAY29kZXBlbiBkWVFZTGdcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS9zcGVlZC1kaWFsXG4gKiBAc2VlYWxzbyBvbnMtc3BlZWQtZGlhbC1pdGVtXG4gKiAgIFtlbl1UaGUgYDxvbnMtc3BlZWQtZGlhbC1pdGVtPmAgcmVwcmVzZW50cyBhIG1lbnUgaXRlbS5bL2VuXVxuICogICBbamFdb25zLXNwZWVkLWRpYWwtaXRlbeOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtZmFiXG4gKiAgIFtlbl1vbnMtZmFiIGNvbXBvbmVudFsvZW5dXG4gKiAgIFtqYV1vbnMtZmFi44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNwZWVkLWRpYWwgcG9zaXRpb249XCJsZWZ0IGJvdHRvbVwiPlxuICogICA8b25zLWZhYj5cbiAqICAgICA8b25zLWljb24gaWNvbj1cImZhLXR3aXR0ZXJcIj48L29ucy1pY29uPlxuICogICA8L29ucy1mYWI+XG4gKiAgIDxvbnMtc3BlZWQtZGlhbC1pdGVtPkE8L29ucy1zcGVlZC1kaWFsLWl0ZW0+XG4gKiAgIDxvbnMtc3BlZWQtZGlhbC1pdGVtPkI8L29ucy1zcGVlZC1kaWFsLWl0ZW0+XG4gKiAgIDxvbnMtc3BlZWQtZGlhbC1pdGVtPkM8L29ucy1zcGVlZC1kaWFsLWl0ZW0+XG4gKiA8L29ucy1zcGVlZC1kaWFsPlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTcGVlZERpYWxFbGVtZW50IGV4dGVuZHMgQmFzZUVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgb3BlblxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgbWVudSBpdGVtcyBhcmUgc2hvd24uWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBjbG9zZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgbWVudSBpdGVtcyBhcmUgaGlkZGVuLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgY29tcG9uZW50LlsvZW5dXG4gICAqICAgW2phXeOBk+OBruOCs+ODs+ODneODvOODjeODs+ODiOOBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHJpcHBsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBkZWZpbmVkLCB0aGUgYnV0dG9uIHdpbGwgaGF2ZSBhIHJpcHBsZSBlZmZlY3Qgd2hlbiB0YXBwZWQuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwb3NpdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBTcGVjaWZ5IHRoZSB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBwb3NpdGlvbiBvZiB0aGUgY29tcG9uZW50LlxuICAgKiAgICAgSS5lLiB0byBkaXNwbGF5IGl0IGluIHRoZSB0b3AgcmlnaHQgY29ybmVyIHNwZWNpZnkgXCJyaWdodCB0b3BcIi5cbiAgICogICAgIENob29zZSBmcm9tIFwicmlnaHRcIiwgXCJsZWZ0XCIsIFwidG9wXCIgYW5kIFwiYm90dG9tXCIuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdXG4gICAqICAgICDjgZPjga7opoHntKDjgpLooajnpLrjgZnjgovlt6blj7PjgajkuIrkuIvjga7kvY3nva7jgpLmjIflrprjgZfjgb7jgZnjgIJcbiAgICogICAgIOS+i+OBiOOBsOOAgeWPs+S4iuOBq+ihqOekuuOBmeOCi+WgtOWQiOOBq+OBr1wicmlnaHQgdG9wXCLjgpLmjIflrprjgZfjgb7jgZnjgIJcbiAgICogICAgIOW3puWPs+OBqOS4iuS4i+OBruS9jee9ruOBruaMh+WumuOBq+OBr+OAgXJpZ2h044GobGVmdOOAgXRvcOOBqGJvdHRvbeOBjOOBneOCjOOBnuOCjOaMh+WumuOBp+OBjeOBvuOBmeOAglxuICAgKiAgIFsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpcmVjdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgZGlyZWN0aW9uIHRoZSBpdGVtcyBhcmUgZGlzcGxheWVkLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIFwidXBcIiwgXCJkb3duXCIsIFwibGVmdFwiIGFuZCBcInJpZ2h0XCIuWy9lbl1cbiAgICogICBbamFdXG4gICAqICAgICDopoHntKDjgYzooajnpLrjgZnjgovmlrnlkJHjgpLmjIflrprjgZfjgb7jgZnjgIJ1cCwgZG93biwgbGVmdCwgcmlnaHTjgYzmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBkaXNhYmxlZFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU3BlY2lmeSBpZiBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkLlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBmeOCi+WgtOWQiOOBq+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5faXRlbVNob3duID0gZmFsc2U7XG4gICAgdGhpcy5fYm91bmRPbkNsaWNrID0gdGhpcy5fb25DbGljay5iaW5kKHRoaXMpO1xuICB9XG5cbiAgX2NvbXBpbGUoKSB7XG4gICAgdGhpcy5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuICAgIHRoaXMuX3VwZGF0ZVJpcHBsZSgpO1xuICAgIE1vZGlmaWVyVXRpbC5pbml0TW9kaWZpZXIodGhpcywgc2NoZW1lKTtcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnZGlyZWN0aW9uJykpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURpcmVjdGlvbih0aGlzLmdldEF0dHJpYnV0ZSgnZGlyZWN0aW9uJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91cGRhdGVEaXJlY3Rpb24oJ3VwJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXBkYXRlUG9zaXRpb24oKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2NsYXNzJywgJ21vZGlmaWVyJywgJ3JpcHBsZScsICdkaXJlY3Rpb24nLCAncG9zaXRpb24nXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdjbGFzcyc6XG4gICAgICAgIHV0aWwucmVzdG9yZUNsYXNzKHRoaXMsIGRlZmF1bHRDbGFzc05hbWUsIHNjaGVtZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbW9kaWZpZXInOlxuICAgICAgICBNb2RpZmllclV0aWwub25Nb2RpZmllckNoYW5nZWQobGFzdCwgY3VycmVudCwgdGhpcywgc2NoZW1lKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlUmlwcGxlKCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2RpcmVjdGlvbic6XG4gICAgICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB0aGlzLl91cGRhdGVEaXJlY3Rpb24oY3VycmVudCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3Bvc2l0aW9uJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHRoaXMuX3VwZGF0ZVBvc2l0aW9uKCkpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrLCBmYWxzZSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrLCBmYWxzZSk7XG4gIH1cblxuICBnZXQgaXRlbXMoKSB7XG4gICAgcmV0dXJuIHV0aWwuYXJyYXlGcm9tKHRoaXMucXVlcnlTZWxlY3RvckFsbCgnb25zLXNwZWVkLWRpYWwtaXRlbScpKTtcbiAgfVxuXG4gIGdldCBfZmFiKCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLWZhYicpO1xuICB9XG5cbiAgX29uQ2xpY2soZSkge1xuICAgIGlmICh0aGlzLm9uQ2xpY2spIHtcbiAgICAgIHRoaXMub25DbGljay5hcHBseSh0aGlzKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9IGVsc2UgaWYgKCF0aGlzLmRpc2FibGVkICYmIHRoaXMudmlzaWJsZSkge1xuICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlSXRlbXMoKTtcbiAgICB9XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICBpZiAoIXRoaXMuaW5saW5lKSB7XG4gICAgICByZXR1cm4gdGhpcy5zaG93KCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGlmICghdGhpcy5pbmxpbmUpIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHRoaXMuaGlkZSgpLnRoZW4ocmVzb2x2ZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBfdXBkYXRlUmlwcGxlKCkge1xuICAgIGlmICh0aGlzLl9mYWIpIHtcbiAgICAgIHRoaXMuaGFzQXR0cmlidXRlKCdyaXBwbGUnKSA/IHRoaXMuX2ZhYi5zZXRBdHRyaWJ1dGUoJ3JpcHBsZScsICcnKSA6IHRoaXMuX2ZhYi5yZW1vdmVBdHRyaWJ1dGUoJ3JpcHBsZScpO1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVEaXJlY3Rpb24oZGlyZWN0aW9uKSB7XG4gICAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLml0ZW1zO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHN0eWxlcihjaGlsZHJlbltpXSwge1xuICAgICAgICB0cmFuc2l0aW9uRGVsYXk6IDI1ICogaSArICdtcycsXG4gICAgICAgIGJvdHRvbTogJ2F1dG8nLFxuICAgICAgICByaWdodDogJ2F1dG8nLFxuICAgICAgICB0b3A6ICdhdXRvJyxcbiAgICAgICAgbGVmdDogJ2F1dG8nXG4gICAgICB9KTtcbiAgICB9XG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgJ3VwJzpcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNoaWxkcmVuW2ldLnN0eWxlLmJvdHRvbSA9IDcyICsgNTYgKiBpICsgJ3B4JztcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS5yaWdodCA9ICc4cHgnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZG93bic6XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS50b3AgPSA3MiArIDU2ICogaSArICdweCc7XG4gICAgICAgICAgY2hpbGRyZW5baV0uc3R5bGUubGVmdCA9ICc4cHgnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS50b3AgPSAnOHB4JztcbiAgICAgICAgICBjaGlsZHJlbltpXS5zdHlsZS5yaWdodCA9IDcyICsgNTYgKiBpICsgJ3B4JztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNoaWxkcmVuW2ldLnN0eWxlLnRvcCA9ICc4cHgnO1xuICAgICAgICAgIGNoaWxkcmVuW2ldLnN0eWxlLmxlZnQgPSA3MiArIDU2ICogaSArICdweCc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnRocm93KCdBcmd1bWVudCBtdXN0IGJlIG9uZSBvZiB1cCwgZG93biwgbGVmdCBvciByaWdodC4nKTtcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlUG9zaXRpb24oKSB7XG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5yZW1vdmUoXG4gICAgICAnZmFiLS10b3BfX2xlZnQnLFxuICAgICAgJ2ZhYi0tYm90dG9tX19yaWdodCcsXG4gICAgICAnZmFiLS1ib3R0b21fX2xlZnQnLFxuICAgICAgJ2ZhYi0tdG9wX19yaWdodCcsXG4gICAgICAnZmFiLS10b3BfX2NlbnRlcicsXG4gICAgICAnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgIHN3aXRjaCAocG9zaXRpb24pIHtcbiAgICAgIGNhc2UgJ3RvcCByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCB0b3AnOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tdG9wX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3RvcCBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgdG9wJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLXRvcF9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSByaWdodCc6XG4gICAgICBjYXNlICdyaWdodCBib3R0b20nOlxuICAgICAgICB0aGlzLmNsYXNzTGlzdC5hZGQoJ2ZhYi0tYm90dG9tX19yaWdodCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSBsZWZ0JzpcbiAgICAgIGNhc2UgJ2xlZnQgYm90dG9tJzpcbiAgICAgICAgdGhpcy5jbGFzc0xpc3QuYWRkKCdmYWItLWJvdHRvbV9fbGVmdCcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciB0b3AnOlxuICAgICAgY2FzZSAndG9wIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS10b3BfX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NlbnRlciBib3R0b20nOlxuICAgICAgY2FzZSAnYm90dG9tIGNlbnRlcic6XG4gICAgICAgIHRoaXMuY2xhc3NMaXN0LmFkZCgnZmFiLS1ib3R0b21fX2NlbnRlcicpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIF9nZXRUcmFuc2xhdGUoKSB7XG4gICAgY29uc3QgaXNCb3R0b20gPSAodGhpcy5nZXRBdHRyaWJ1dGUoJ3Bvc2l0aW9uJykgfHwgJycpLmluZGV4T2YoJ2JvdHRvbScpID49IDA7XG4gICAgY29uc3QgdHJhbnNsYXRlID0gaXNCb3R0b20gPyBgdHJhbnNsYXRlM2QoMHB4LCAtJHt1dGlsLmdsb2JhbHMuZmFiT2Zmc2V0IHx8IDB9cHgsIDBweCkgYCA6ICcnO1xuICAgIHJldHVybiB0cmFuc2xhdGU7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSBzcGVlZCBkaWFsLlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgc2hvdygpIHtcbiAgICB0aGlzLl9mYWIuc2hvdygpO1xuICAgIHN0eWxlcih0aGlzLCB7IHRyYW5zZm9ybTogdGhpcy5fZ2V0VHJhbnNsYXRlIH0pO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhpZGVcbiAgICogQHNpZ25hdHVyZSBoaWRlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhpZGUgdGhlIHNwZWVkIGRpYWwuWy9lbl1cbiAgICogICBbamFdU3BlZWQgZGlhbOOCkumdnuihqOekuuOBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBoaWRlKCkge1xuICAgIHJldHVybiB0aGlzLmhpZGVJdGVtcygpLnRoZW4oKCk9PiB0aGlzLl9mYWIuaGlkZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNob3dJdGVtc1xuICAgKiBAc2lnbmF0dXJlIHNob3dJdGVtcygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSBzcGVlZCBkaWFsIGl0ZW1zLlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7lrZDopoHntKDjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgc2hvd0l0ZW1zKCkge1xuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnZGlyZWN0aW9uJykpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZURpcmVjdGlvbih0aGlzLmdldEF0dHJpYnV0ZSgnZGlyZWN0aW9uJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl91cGRhdGVEaXJlY3Rpb24oJ3VwJyk7XG4gICAgfVxuXG4gICAgbGV0IHRvdGFsRGVsYXkgPSAwO1xuICAgIGlmICghdGhpcy5faXRlbVNob3duKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuaXRlbXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5ID0gMjUgKiBpO1xuICAgICAgICB0b3RhbERlbGF5ICs9IGRlbGF5O1xuICAgICAgICBzdHlsZXIoY2hpbGRyZW5baV0sIHtcbiAgICAgICAgICB0cmFuc2Zvcm06ICdzY2FsZSgxKScsXG4gICAgICAgICAgdHJhbnNpdGlvbkRlbGF5OiBkZWxheSArICdtcydcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0b3RhbERlbGF5ICs9IDUwO1xuXG4gICAgICB0aGlzLl9pdGVtU2hvd24gPSB0cnVlO1xuICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdvcGVuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmZXJyZWQgPSB1dGlsLmRlZmVyKCk7XG4gICAgc2V0VGltZW91dChkZWZlcnJlZC5yZXNvbHZlLCB0b3RhbERlbGF5KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGhpZGVJdGVtc1xuICAgKiBAc2lnbmF0dXJlIGhpZGVJdGVtcygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRoZSBzcGVlZCBkaWFsIGl0ZW1zLlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7lrZDopoHntKDjgpLpnZ7ooajnpLrjgavjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgaGlkZUl0ZW1zKCkge1xuICAgIGxldCB0b3RhbERlbGF5ID0gMDtcbiAgICBpZiAodGhpcy5faXRlbVNob3duKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuaXRlbXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlbGF5ID0gMjUgKiAoY2hpbGRyZW4ubGVuZ3RoIC0gaSk7XG4gICAgICAgIHRvdGFsRGVsYXkgKz0gZGVsYXk7XG4gICAgICAgIHN0eWxlcihjaGlsZHJlbltpXSwge1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3NjYWxlKDApJyxcbiAgICAgICAgICB0cmFuc2l0aW9uRGVsYXk6IGRlbGF5ICsgJ21zJ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHRvdGFsRGVsYXkgKz0gNTA7XG5cbiAgICAgIHRoaXMuX2l0ZW1TaG93biA9IGZhbHNlO1xuICAgICAgdXRpbC50cmlnZ2VyRWxlbWVudEV2ZW50KHRoaXMsICdjbG9zZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmVycmVkID0gdXRpbC5kZWZlcigpO1xuICAgIHNldFRpbWVvdXQoZGVmZXJyZWQucmVzb2x2ZSwgdG90YWxEZWxheSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIHNldCBkaXNhYmxlZCh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5oaWRlSXRlbXMoKTtcbiAgICB9XG4gICAgdXRpbC5hcnJheUZyb20odGhpcy5jaGlsZHJlbikuZm9yRWFjaChlID0+IHtcbiAgICAgIHV0aWwubWF0Y2goZSwgJy5mYWInKSAmJiB1dGlsLnRvZ2dsZUF0dHJpYnV0ZShlLCAnZGlzYWJsZWQnLCB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2Rpc2FibGVkJywgdmFsdWUpO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgaW5saW5lXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgaW5saW5lIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg7Pjg6njgqTjg7PopoHntKDjga7loLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgZ2V0IGlubGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYXNBdHRyaWJ1dGUoJ2lubGluZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBvciBub3QuWy9lbl1cbiAgICogICBbamFd6KaB57Sg44GM6KaL44GI44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG4gIGdldCB2aXNpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLl9mYWIudmlzaWJsZSAmJiB0aGlzLnN0eWxlLmRpc3BsYXkgIT09ICdub25lJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGlzT3BlblxuICAgKiBAc2lnbmF0dXJlIGlzT3BlbigpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SZXR1cm5zIHdoZXRoZXIgdGhlIG1lbnUgaXMgb3BlbiBvciBub3QuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGlzT3BlbigpIHtcbiAgICByZXR1cm4gdGhpcy5faXRlbVNob3duO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKClcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRvZ2dsZSB2aXNpYmlsaXR5LlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7ooajnpLrpnZ7ooajnpLrjgpLliIfjgormm7/jgYjjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgdG9nZ2xlKCkge1xuICAgIHJldHVybiB0aGlzLnZpc2libGUgPyB0aGlzLmhpZGUoKSA6IHRoaXMuc2hvdygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlSXRlbXNcbiAgICogQHNpZ25hdHVyZSB0b2dnbGVJdGVtcygpXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1Ub2dnbGUgaXRlbSB2aXNpYmlsaXR5LlsvZW5dXG4gICAqICAgW2phXVNwZWVkIGRpYWzjga7lrZDopoHntKDjga7ooajnpLrpnZ7ooajnpLrjgpLliIfjgormm7/jgYjjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgdG9nZ2xlSXRlbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNPcGVuKCkgPyB0aGlzLmhpZGVJdGVtcygpIDogdGhpcy5zaG93SXRlbXMoKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ29wZW4nLCAnY2xvc2UnXTtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5TcGVlZERpYWwgPSBTcGVlZERpYWxFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc3BlZWQtZGlhbCcsIFNwZWVkRGlhbEVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vb25zL2ludGVybmFsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IHtQYWdlTG9hZGVyLCBkZWZhdWx0UGFnZUxvYWRlcn0gZnJvbSAnLi4vb25zL3BhZ2UtbG9hZGVyJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCByZXdyaXRhYmxlcyA9IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcmVhZHkoZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICBzZXRJbW1lZGlhdGUoY2FsbGJhY2spO1xuICB9XG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy1zcGxpdHRlci1jb250ZW50XG4gKiBAY2F0ZWdvcnkgbWVudVxuICogQGRlc2NyaXB0aW9uXG4gKiAgW2VuXVxuICogICAgVGhlIGA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+YCBlbGVtZW50IGlzIHVzZWQgYXMgYSBjaGlsZCBlbGVtZW50IG9mIGA8b25zLXNwbGl0dGVyPmAuXG4gKlxuICogICAgSXQgY29udGFpbnMgdGhlIG1haW4gY29udGVudCBvZiB0aGUgcGFnZSB3aGlsZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgY29udGFpbnMgdGhlIGxpc3QuXG4gKiAgWy9lbl1cbiAqICBbamFdb25zLXNwbGl0dGVyLWNvbnRlbnTopoHntKDjga/jgIFvbnMtc3BsaXR0ZXLopoHntKDjga7lrZDopoHntKDjgajjgZfjgabliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gck9RT01MXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3BsaXR0ZXJcbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogIFtlbl1NYW5hZ2luZyBtdWx0aXBsZSBwYWdlcy5bL2VuXVxuICogIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyXG4gKiAgW2VuXVRoZSBgPG9ucy1zcGxpdHRlcj5gIGNvbXBvbmVudCBpcyB0aGUgcGFyZW50IGVsZW1lbnQuWy9lbl1cbiAqICBbamFdb25zLXNwbGl0dGVy44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1zcGxpdHRlci1zaWRlXG4gKiAgW2VuXVRoZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgY29tcG9uZW50IGNvbnRhaW5zIHRoZSBtZW51LlsvZW5dXG4gKiAgW2phXW9ucy1zcGxpdHRlci1zaWRl44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNwbGl0dGVyPlxuICogICA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKiAgICAgLi4uXG4gKiAgIDwvb25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKlxuICogICA8b25zLXNwbGl0dGVyLXNpZGUgc2lkZT1cImxlZnRcIiB3aWR0aD1cIjgwJVwiIGNvbGxhcHNlPlxuICogICAgIC4uLlxuICogICA8L29ucy1zcGxpdHRlci1zaWRlPlxuICogPC9vbnMtc3BsaXR0ZXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyQ29udGVudEVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgcGFnZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBUaGUgdXJsIG9mIHRoZSBjb250ZW50IHBhZ2UuIElmIHRoaXMgYXR0cmlidXRlIGlzIHVzZWQgdGhlIGNvbnRlbnQgd2lsbCBiZSBsb2FkZWQgZnJvbSBhIGA8dGVtcGxhdGU+YCB0YWcgb3IgYSByZW1vdGUgZmlsZS5cbiAgICpcbiAgICogICAgIEl0IGlzIGFsc28gcG9zc2libGUgdG8gcHV0IGA8b25zLXBhZ2U+YCBlbGVtZW50IGFzIGEgY2hpbGQgb2YgdGhlIGVsZW1lbnQuXG4gICAqICAgWy9lbl1cbiAgICogICBbamFdb25zLXNwbGl0dGVyLWNvbnRlbnTopoHntKDjgavooajnpLrjgZnjgovjg5rjg7zjgrjjga5VUkzjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fcGFnZSA9IG51bGw7XG4gICAgdGhpcy5fcGFnZUxvYWRlciA9IGRlZmF1bHRQYWdlTG9hZGVyO1xuXG4gICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgIHJld3JpdGFibGVzLnJlYWR5KHRoaXMsICgpID0+IHtcbiAgICAgICAgY29uc3QgcGFnZSA9IHRoaXMuX2dldFBhZ2VUYXJnZXQoKTtcblxuICAgICAgICBpZiAocGFnZSkge1xuICAgICAgICAgIHRoaXMubG9hZChwYWdlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAoIXV0aWwubWF0Y2godGhpcy5wYXJlbnROb2RlLCAnb25zLXNwbGl0dGVyJykpIHtcbiAgICAgIHV0aWwudGhyb3coJ1wib25zLXNwbGl0dGVyLWNvbnRlbnRcIiBtdXN0IGhhdmUgXCJvbnMtc3BsaXR0ZXJcIiBhcyBwYXJlbnQnKTtcbiAgICB9XG4gIH1cblxuICBfZ2V0UGFnZVRhcmdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZSB8fCB0aGlzLmdldEF0dHJpYnV0ZSgncGFnZScpO1xuICB9XG5cbiAgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7fVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHBhZ2UgdG8gbG9hZCBpbiB0aGUgc3BsaXR0ZXIgY29udGVudC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7opoHntKDlhoXjgavooajnpLrjgZnjgovjg5rjg7zjgrjjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsqfSBwYWdlXG4gICAqL1xuICBzZXQgcGFnZShwYWdlKSB7XG4gICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gIH1cblxuICBnZXQgX2NvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF07XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VMb2FkZXJcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUGFnZSBlbGVtZW50IGxvYWRlZCBpbiB0aGUgc3BsaXR0ZXIgY29udGVudC5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7opoHntKDlhoXjgavooajnpLrjgZnjgovjg5rjg7zjgrjjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2VMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VMb2FkZXI7XG4gIH1cblxuICBzZXQgcGFnZUxvYWRlcihsb2FkZXIpIHtcbiAgICBpZiAoIShsb2FkZXIgaW5zdGFuY2VvZiBQYWdlTG9hZGVyKSkge1xuICAgICAgdXRpbC50aHJvd1BhZ2VMb2FkZXIoKTtcbiAgICB9XG4gICAgdGhpcy5fcGFnZUxvYWRlciA9IGxvYWRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGxvYWRcbiAgICogQHNpZ25hdHVyZSBsb2FkKHBhZ2UsIFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhZ2UsIFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGRvY3VtZW50IG9yIGFuIGA8dGVtcGxhdGU+YCBpZC5bL2VuXVxuICAgKiAgIFtqYV1wYWdl44GuVVJM44GL44CBYDx0ZW1wbGF0ZT5g44Gn5a6j6KiA44GX44Gf44OG44Oz44OX44Os44O844OI44GuaWTlsZ7mgKfjga7lgKTjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLmNhbGxiYWNrXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyB0aGUgcGFnZSBzcGVjaWZpZWQgaW4gYHBhZ2VgIGluIHRoZSBjb250ZW50LlsvZW5dXG4gICAqICAgW2phXeaMh+WumuOBl+OBn1VSTOOCkuODoeOCpOODs+ODmuODvOOCuOOCkuiqreOBv+i+vOOBv+OBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBuZXcgYDxvbnMtcGFnZT5gIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1gPG9ucy1wYWdlPmDopoHntKDjgpLop6PmsbrjgZnjgotQcm9taXNl44Kq44OW44K444Kn44Kv44OI44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICovXG4gIGxvYWQocGFnZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gICAgY29uc3QgY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrIHx8IGZ1bmN0aW9uKCkge307XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBsZXQgb2xkQ29udGVudCA9IHRoaXMuX2NvbnRlbnQgfHwgbnVsbDtcblxuICAgICAgdGhpcy5fcGFnZUxvYWRlci5sb2FkKHtwYWdlLCBwYXJlbnQ6IHRoaXN9LCBwYWdlRWxlbWVudCA9PiB7XG4gICAgICAgIGlmIChvbGRDb250ZW50KSB7XG4gICAgICAgICAgdGhpcy5fcGFnZUxvYWRlci51bmxvYWQob2xkQ29udGVudCk7XG4gICAgICAgICAgb2xkQ29udGVudCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRJbW1lZGlhdGUoKCkgPT4gdGhpcy5fc2hvdygpKTtcblxuICAgICAgICBjYWxsYmFjayhwYWdlRWxlbWVudCk7XG4gICAgICAgIHJlc29sdmUocGFnZUVsZW1lbnQpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBfc2hvdygpIHtcbiAgICBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgdGhpcy5fY29udGVudC5fc2hvdygpO1xuICAgIH1cbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICB0aGlzLl9jb250ZW50Ll9oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgX2Rlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuX2NvbnRlbnQpIHtcbiAgICAgIHRoaXMuX3BhZ2VMb2FkZXIudW5sb2FkKHRoaXMuX2NvbnRlbnQpO1xuICAgIH1cbiAgICB0aGlzLnJlbW92ZSgpO1xuICB9XG5cbiAgc3RhdGljIGdldCByZXdyaXRhYmxlcygpIHtcbiAgICByZXR1cm4gcmV3cml0YWJsZXM7XG4gIH1cbn1cblxub25zRWxlbWVudHMuU3BsaXR0ZXJDb250ZW50ID0gU3BsaXR0ZXJDb250ZW50RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXNwbGl0dGVyLWNvbnRlbnQnLCBTcGxpdHRlckNvbnRlbnRFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vb25zL3V0aWwnO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyTWFza0VsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuX2JvdW5kT25DbGljayA9IHRoaXMuX29uQ2xpY2suYmluZCh0aGlzKTtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMucGFyZW50Tm9kZS5fc2lkZXMuZXZlcnkoc2lkZSA9PiBzaWRlLm1vZGUgPT09ICdzcGxpdCcpKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzdHlsZScsICdkaXNwbGF5OiBub25lICFpbXBvcnRhbnQnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9vbkNsaWNrKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMub25DbGljayBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICB0aGlzLm9uQ2xpY2soKTtcbiAgICB9IGVsc2UgaWYgKHV0aWwubWF0Y2godGhpcy5wYXJlbnROb2RlLCAnb25zLXNwbGl0dGVyJykpIHtcbiAgICAgIHRoaXMucGFyZW50Tm9kZS5fc2lkZXMuZm9yRWFjaChzaWRlID0+IHNpZGUuY2xvc2UoJ2xlZnQnKS5jYXRjaCgoKSA9PiB7fSkpO1xuICAgIH1cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrKTtcbiAgICB1dGlsLmlvc01hc2tTY3JvbGxGaXgodGhpcywgdHJ1ZSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fYm91bmRPbkNsaWNrKTtcbiAgICB1dGlsLmlvc01hc2tTY3JvbGxGaXgodGhpcywgZmFsc2UpO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLlNwbGl0dGVyTWFzayA9IFNwbGl0dGVyTWFza0VsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zcGxpdHRlci1tYXNrJywgU3BsaXR0ZXJNYXNrRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgdXRpbCBmcm9tICcuLi8uLi9vbnMvdXRpbCc7XG5pbXBvcnQgc3R5bGVyIGZyb20gJy4uLy4uL29ucy9zdHlsZXInO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgQmFzZUFuaW1hdG9yIGZyb20gJy4uLy4uL29ucy9iYXNlLWFuaW1hdG9yJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3BsaXR0ZXJBbmltYXRvciBleHRlbmRzIEJhc2VBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdjdWJpYy1iZXppZXIoLjEsIC43LCAuMSwgMSknLCBkdXJhdGlvbiA9IDAuMywgZGVsYXkgPSAwfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGR1cmF0aW9uLCBkZWxheSB9KTtcbiAgfVxuXG4gIHVwZGF0ZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgdXRpbC5leHRlbmQodGhpcywge1xuICAgICAgdGltaW5nOiB0aGlzLnRpbWluZywgZHVyYXRpb246IHRoaXMuZHVyYXRpb24sIGRlbGF5OiB0aGlzLmRlbGF5XG4gICAgfSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBzaWRlRWxlbWVudFxuICAgKi9cbiAgYWN0aXZhdGUoc2lkZUVsZW1lbnQpIHtcbiAgICBjb25zdCBzcGxpdHRlciA9IHNpZGVFbGVtZW50LnBhcmVudE5vZGU7XG5cbiAgICBjb250ZW50UmVhZHkoc3BsaXR0ZXIsICgpID0+IHtcbiAgICAgIHRoaXMuX3NpZGUgPSBzaWRlRWxlbWVudDtcbiAgICAgIHRoaXMuX29wcG9zaXRlU2lkZSA9IHNwbGl0dGVyLnJpZ2h0ICE9PSBzaWRlRWxlbWVudCAmJiBzcGxpdHRlci5yaWdodCB8fCBzcGxpdHRlci5sZWZ0ICE9PSBzaWRlRWxlbWVudCAmJiBzcGxpdHRlci5sZWZ0O1xuICAgICAgdGhpcy5fY29udGVudCA9IHNwbGl0dGVyLmNvbnRlbnQ7XG4gICAgICB0aGlzLl9tYXNrID0gc3BsaXR0ZXIubWFzaztcbiAgICB9KTtcbiAgfVxuXG4gIGRlYWN0aXZhdGUoKSB7XG4gICAgdGhpcy5jbGVhclRyYW5zaXRpb24oKTtcbiAgICB0aGlzLl9tYXNrICYmIHRoaXMuY2xlYXJNYXNrKCk7XG4gICAgdGhpcy5fY29udGVudCA9IHRoaXMuX3NpZGUgPSB0aGlzLl9vcHBvc2l0ZVNpZGUgPSB0aGlzLl9tYXNrID0gbnVsbDtcbiAgfVxuXG4gIGdldCBtaW51cygpIHtcbiAgICByZXR1cm4gdGhpcy5fc2lkZS5zaWRlID09PSAncmlnaHQnID8gJy0nIDogJyc7XG4gIH1cblxuICBjbGVhclRyYW5zaXRpb24oKSB7XG4gICAgJ3NpZGUgbWFzayBjb250ZW50Jy5zcGxpdCgvXFxzKy8pXG4gICAgICAuZm9yRWFjaChlID0+IHRoaXNbJ18nICsgZV0gJiYgc3R5bGVyLmNsZWFyKHRoaXNbJ18nICsgZV0sICd0cmFuc2Zvcm0gdHJhbnNpdGlvbicpKVxuICB9XG5cbiAgY2xlYXJNYXNrKCkge1xuICAgIC8vIENoZWNrIGlmIHRoZSBvdGhlciBzaWRlIG5lZWRzIHRoZSBtYXNrIGJlZm9yZSBjbGVhcmluZ1xuICAgIGlmICghdGhpcy5fb3Bwb3NpdGVTaWRlIHx8IHRoaXMuX29wcG9zaXRlU2lkZS5tb2RlID09PSAnc3BsaXQnIHx8ICF0aGlzLl9vcHBvc2l0ZVNpZGUuaXNPcGVuKSB7XG4gICAgICB0aGlzLl9tYXNrLnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgICAgIHRoaXMuX21hc2suc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRpc3RhbmNlXG4gICAqL1xuICB0cmFuc2xhdGUoZGlzdGFuY2UpIHtcblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIG9wZW4oZG9uZSkge1xuICAgIGRvbmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBjbG9zZShkb25lKSB7XG4gICAgZG9uZSgpO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IFNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvci5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE92ZXJsYXlTcGxpdHRlckFuaW1hdG9yIGV4dGVuZHMgU3BsaXR0ZXJBbmltYXRvciB7XG5cbiAgdHJhbnNsYXRlKGRpc3RhbmNlKSB7XG4gICAgdGhpcy5fbWFzay5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsgLy8gQXZvaWQgY29udGVudCBjbGlja3NcblxuICAgIGFuaW1pdCh0aGlzLl9zaWRlKVxuICAgICAgLnF1ZXVlKHtcbiAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoJHt0aGlzLm1pbnVzICsgZGlzdGFuY2V9cHgsIDAsIDApYFxuICAgICAgfSlcbiAgICAgIC5wbGF5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZG9uZVxuICAgKi9cbiAgb3Blbihkb25lKSB7XG4gICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgIGFuaW1pdCh0aGlzLl9zaWRlKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5taW51c30xMDAlLCAwLCAwKWBcbiAgICAgICAgfSwgdGhpcy5kZWYpXG4gICAgICAgIC5xdWV1ZShjYWxsYmFjayA9PiB7XG4gICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lICYmIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdCh0aGlzLl9tYXNrKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIGRpc3BsYXk6ICdibG9jaydcbiAgICAgICAgfSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICBvcGFjaXR5OiAnMSdcbiAgICAgICAgfSwge1xuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uLFxuICAgICAgICAgIHRpbWluZzogJ2xpbmVhcicsXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBjbG9zZShkb25lKSB7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRoaXMuX3NpZGUpXG4gICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknXG4gICAgICAgIH0sIHRoaXMuZGVmKVxuICAgICAgICAucXVldWUoY2FsbGJhY2sgPT4ge1xuICAgICAgICAgIGRvbmUgJiYgZG9uZSgpO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQodGhpcy5fbWFzaylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICBvcGFjaXR5OiAnMCdcbiAgICAgICAgfSwge1xuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uLFxuICAgICAgICAgIHRpbWluZzogJ2xpbmVhcicsXG4gICAgICAgIH0pXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBTcGxpdHRlckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3IuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQdXNoU3BsaXR0ZXJBbmltYXRvciBleHRlbmRzIFNwbGl0dGVyQW5pbWF0b3Ige1xuXG4gIF9nZXRTbGlkaW5nRWxlbWVudHMoKSB7XG4gICAgY29uc3Qgc2xpZGluZ0VsZW1lbnRzID0gW3RoaXMuX3NpZGUsIHRoaXMuX2NvbnRlbnRdO1xuICAgIGlmICh0aGlzLl9vcHBvc2l0ZVNpZGUgJiYgdGhpcy5fb3Bwb3NpdGVTaWRlLm1vZGUgPT09ICdzcGxpdCcpIHtcbiAgICAgIHNsaWRpbmdFbGVtZW50cy5wdXNoKHRoaXMuX29wcG9zaXRlU2lkZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNsaWRpbmdFbGVtZW50cztcbiAgfVxuXG4gIHRyYW5zbGF0ZShkaXN0YW5jZSkge1xuICAgIGlmICghdGhpcy5fc2xpZGluZ0VsZW1lbnRzKSB7XG4gICAgICB0aGlzLl9zbGlkaW5nRWxlbWVudHMgPSB0aGlzLl9nZXRTbGlkaW5nRWxlbWVudHMoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9tYXNrLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snOyAvLyBBdm9pZCBjb250ZW50IGNsaWNrc1xuXG4gICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgIC5xdWV1ZSh7XG4gICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5taW51cyArIGRpc3RhbmNlfXB4LCAwLCAwKWBcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIG9wZW4oZG9uZSkge1xuICAgIGNvbnN0IG1heCA9IHRoaXMuX3NpZGUub2Zmc2V0V2lkdGg7XG4gICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gdGhpcy5fZ2V0U2xpZGluZ0VsZW1lbnRzKCk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMubWludXMgKyBtYXh9cHgsIDAsIDApYFxuICAgICAgICB9LCB0aGlzLmRlZilcbiAgICAgICAgLnF1ZXVlKGNhbGxiYWNrID0+IHtcbiAgICAgICAgICB0aGlzLl9zbGlkaW5nRWxlbWVudHMgPSBudWxsO1xuICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSAmJiBkb25lKCk7XG4gICAgICAgIH0pLFxuXG4gICAgICBhbmltaXQodGhpcy5fbWFzaylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICBkaXNwbGF5OiAnYmxvY2snXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkb25lXG4gICAqL1xuICBjbG9zZShkb25lKSB7XG4gICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gdGhpcy5fZ2V0U2xpZGluZ0VsZW1lbnRzKCk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHtcbiAgICAgICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUzZCgwLCAwLCAwKSdcbiAgICAgICAgfSwgdGhpcy5kZWYpXG4gICAgICAgIC5xdWV1ZShjYWxsYmFjayA9PiB7XG4gICAgICAgICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gbnVsbDtcbiAgICAgICAgICBzdXBlci5jbGVhclRyYW5zaXRpb24oKTtcbiAgICAgICAgICBkb25lICYmIGRvbmUoKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KHRoaXMuX21hc2spXG4gICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgc3R5bGVyIGZyb20gJy4uLy4uL29ucy9zdHlsZXInO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBTcGxpdHRlckFuaW1hdG9yIGZyb20gJy4vYW5pbWF0b3IuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXZlYWxTcGxpdHRlckFuaW1hdG9yIGV4dGVuZHMgU3BsaXR0ZXJBbmltYXRvciB7XG5cbiAgX2dldFNsaWRpbmdFbGVtZW50cygpIHtcbiAgICBjb25zdCBzbGlkaW5nRWxlbWVudHMgPSBbdGhpcy5fY29udGVudCwgdGhpcy5fbWFza107XG4gICAgaWYgKHRoaXMuX29wcG9zaXRlU2lkZSAmJiB0aGlzLl9vcHBvc2l0ZVNpZGUubW9kZSA9PT0gJ3NwbGl0Jykge1xuICAgICAgc2xpZGluZ0VsZW1lbnRzLnB1c2godGhpcy5fb3Bwb3NpdGVTaWRlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2xpZGluZ0VsZW1lbnRzO1xuICB9XG5cbiAgYWN0aXZhdGUoc2lkZUVsZW1lbnQpIHtcbiAgICBzdXBlci5hY3RpdmF0ZShzaWRlRWxlbWVudCk7XG4gICAgaWYgKHNpZGVFbGVtZW50Lm1vZGUgPT09ICdjb2xsYXBzZScpIHtcbiAgICAgIHRoaXMuX3NldFN0eWxlcyhzaWRlRWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgZGVhY3RpdmF0ZSgpIHtcbiAgICB0aGlzLl9zaWRlICYmIHRoaXMuX3Vuc2V0U3R5bGVzKHRoaXMuX3NpZGUpO1xuICAgIHN1cGVyLmRlYWN0aXZhdGUoKTtcbiAgfVxuXG4gIF9zZXRTdHlsZXMoc2lkZUVsZW1lbnQpIHtcbiAgICBzdHlsZXIoc2lkZUVsZW1lbnQsIHtcbiAgICAgIGxlZnQ6IHNpZGVFbGVtZW50LnNpZGUgPT09ICdyaWdodCcgPyAnYXV0bycgOiAwLFxuICAgICAgcmlnaHQ6IHNpZGVFbGVtZW50LnNpZGUgPT09ICdyaWdodCcgID8gMCA6ICdhdXRvJyxcbiAgICAgIHpJbmRleDogMCxcbiAgICAgIGJhY2tncm91bmRDb2xvcjogJ2JsYWNrJyxcbiAgICAgIHRyYW5zZm9ybTogdGhpcy5fZ2VuZXJhdGVCZWhpbmRQYWdlU3R5bGUoMCkuY29udGFpbmVyLnRyYW5zZm9ybSxcbiAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3BsaXR0ZXIgPSBzaWRlRWxlbWVudC5wYXJlbnRFbGVtZW50O1xuICAgIGNvbnRlbnRSZWFkeShzcGxpdHRlciwgKCkgPT4gc3BsaXR0ZXIuY29udGVudCAmJiBzdHlsZXIoc3BsaXR0ZXIuY29udGVudCwgeyBib3hTaGFkb3c6ICcwIDAgMTJweCAwIHJnYmEoMCwgMCwgMCwgMC4yKScgfSkpO1xuICB9XG5cbiAgX3Vuc2V0U3R5bGVzKHNpZGVFbGVtZW50KSB7XG4gICAgc3R5bGVyLmNsZWFyKHNpZGVFbGVtZW50LCAnbGVmdCByaWdodCB6SW5kZXggYmFja2dyb3VuZENvbG9yIGRpc3BsYXknKTtcbiAgICBpZiAoc2lkZUVsZW1lbnQuX2NvbnRlbnQpIHtcbiAgICAgIHNpZGVFbGVtZW50Ll9jb250ZW50LnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgb3RoZXIgc2lkZSBuZWVkcyB0aGUgY29tbW9uIHN0eWxlc1xuICAgIGlmICghdGhpcy5fb3Bwb3NpdGVTaWRlIHx8IHRoaXMuX29wcG9zaXRlU2lkZS5tb2RlID09PSAnc3BsaXQnKSB7XG4gICAgICBzaWRlRWxlbWVudC5wYXJlbnRFbGVtZW50LmNvbnRlbnQgJiYgc3R5bGVyLmNsZWFyKHNpZGVFbGVtZW50LnBhcmVudEVsZW1lbnQuY29udGVudCwgJ2JveFNoYWRvdycpO1xuICAgIH1cbiAgfVxuXG4gIF9nZW5lcmF0ZUJlaGluZFBhZ2VTdHlsZShkaXN0YW5jZSkge1xuICAgIGNvbnN0IG1heCA9IHRoaXMubWF4V2lkdGg7XG5cbiAgICBsZXQgYmVoaW5kRGlzdGFuY2UgPSAoZGlzdGFuY2UgLSBtYXgpIC8gbWF4ICogMTA7XG4gICAgYmVoaW5kRGlzdGFuY2UgPSBpc05hTihiZWhpbmREaXN0YW5jZSkgPyAwIDogTWF0aC5tYXgoTWF0aC5taW4oYmVoaW5kRGlzdGFuY2UsIDApLCAtMTApO1xuXG4gICAgY29uc3QgYmVoaW5kVHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7KHRoaXMubWludXMgPyAtMSA6IDEpICogYmVoaW5kRGlzdGFuY2V9JSwgMCwgMClgO1xuICAgIGNvbnN0IG9wYWNpdHkgPSAxICsgYmVoaW5kRGlzdGFuY2UgLyAxMDA7XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29udGVudDoge1xuICAgICAgICBvcGFjaXR5XG4gICAgICB9LFxuICAgICAgY29udGFpbmVyOiB7XG4gICAgICAgIHRyYW5zZm9ybTogYmVoaW5kVHJhbnNmb3JtXG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHRyYW5zbGF0ZShkaXN0YW5jZSkge1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuekluZGV4ID0gMTtcbiAgICB0aGlzLm1heFdpZHRoID0gdGhpcy5tYXhXaWR0aCB8fCB0aGlzLl9nZXRNYXhXaWR0aCgpO1xuICAgIGNvbnN0IG1lbnVTdHlsZSA9IHRoaXMuX2dlbmVyYXRlQmVoaW5kUGFnZVN0eWxlKE1hdGgubWluKGRpc3RhbmNlLCB0aGlzLm1heFdpZHRoKSk7XG5cbiAgICBpZiAoIXRoaXMuX3NsaWRpbmdFbGVtZW50cykge1xuICAgICAgdGhpcy5fc2xpZGluZ0VsZW1lbnRzID0gdGhpcy5fZ2V0U2xpZGluZ0VsZW1lbnRzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fbWFzay5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJzsgLy8gQXZvaWQgY29udGVudCBjbGlja3NcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodGhpcy5fc2xpZGluZ0VsZW1lbnRzKVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogYHRyYW5zbGF0ZTNkKCR7dGhpcy5taW51cyArIGRpc3RhbmNlfXB4LCAwLCAwKWBcbiAgICAgICAgfSksXG4gICAgICBhbmltaXQodGhpcy5fc2lkZS5fY29udGVudClcbiAgICAgICAgLnF1ZXVlKG1lbnVTdHlsZS5jb250ZW50KSxcbiAgICAgIGFuaW1pdCh0aGlzLl9zaWRlKVxuICAgICAgICAucXVldWUobWVudVN0eWxlLmNvbnRhaW5lcilcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIG9wZW4oZG9uZSkge1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgIHRoaXMuX3NpZGUuc3R5bGUuekluZGV4ID0gMTtcbiAgICB0aGlzLm1heFdpZHRoID0gdGhpcy5tYXhXaWR0aCB8fCB0aGlzLl9nZXRNYXhXaWR0aCgpO1xuICAgIGNvbnN0IG1lbnVTdHlsZSA9IHRoaXMuX2dlbmVyYXRlQmVoaW5kUGFnZVN0eWxlKHRoaXMubWF4V2lkdGgpO1xuICAgIHRoaXMuX3NsaWRpbmdFbGVtZW50cyA9IHRoaXMuX2dldFNsaWRpbmdFbGVtZW50cygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7IC8vIEZpeDogVGltZSB0byB1cGRhdGUgcHJldmlvdXMgdHJhbnNsYXRlM2QgYWZ0ZXIgY2hhbmdpbmcgc3R5bGUuZGlzcGxheVxuICAgICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgICAgYW5pbWl0KHRoaXMuX3NsaWRpbmdFbGVtZW50cylcbiAgICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAgIC5xdWV1ZSh7XG4gICAgICAgICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke3RoaXMubWludXMgKyB0aGlzLm1heFdpZHRofXB4LCAwLCAwKWBcbiAgICAgICAgICB9LCB0aGlzLmRlZiksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuX21hc2spXG4gICAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgICAucXVldWUoe1xuICAgICAgICAgICAgZGlzcGxheTogJ2Jsb2NrJ1xuICAgICAgICAgIH0pLFxuXG4gICAgICAgIGFuaW1pdCh0aGlzLl9zaWRlLl9jb250ZW50KVxuICAgICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgICAgLnF1ZXVlKG1lbnVTdHlsZS5jb250ZW50LCB0aGlzLmRlZiksXG5cbiAgICAgICAgYW5pbWl0KHRoaXMuX3NpZGUpXG4gICAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgICAucXVldWUobWVudVN0eWxlLmNvbnRhaW5lciwgdGhpcy5kZWYpXG4gICAgICAgICAgLnF1ZXVlKGNhbGxiYWNrID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3NsaWRpbmdFbGVtZW50cyA9IG51bGw7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgZG9uZSAmJiBkb25lKCk7XG4gICAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0sIDEwMDAvNjApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGRvbmVcbiAgICovXG4gIGNsb3NlKGRvbmUpIHtcbiAgICBjb25zdCBtZW51U3R5bGUgPSB0aGlzLl9nZW5lcmF0ZUJlaGluZFBhZ2VTdHlsZSgwKTtcbiAgICB0aGlzLl9zbGlkaW5nRWxlbWVudHMgPSB0aGlzLl9nZXRTbGlkaW5nRWxlbWVudHMoKTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodGhpcy5fc2xpZGluZ0VsZW1lbnRzKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJ1xuICAgICAgICB9LCB0aGlzLmRlZiksXG5cbiAgICAgIGFuaW1pdCh0aGlzLl9tYXNrKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoe1xuICAgICAgICAgIGRpc3BsYXk6ICdub25lJ1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KHRoaXMuX3NpZGUuX2NvbnRlbnQpXG4gICAgICAgIC53YWl0KHRoaXMuZGVsYXkpXG4gICAgICAgIC5xdWV1ZShtZW51U3R5bGUuY29udGVudCwgdGhpcy5kZWYpLFxuXG4gICAgICBhbmltaXQodGhpcy5fc2lkZSlcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKG1lbnVTdHlsZS5jb250YWluZXIsIHRoaXMuZGVmKVxuICAgICAgICAucXVldWUoY2FsbGJhY2sgPT4ge1xuICAgICAgICAgIHRoaXMuX3NsaWRpbmdFbGVtZW50cyA9IG51bGw7XG4gICAgICAgICAgdGhpcy5fc2lkZS5zdHlsZS56SW5kZXggPSAwO1xuICAgICAgICAgIHRoaXMuX3NpZGUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICB0aGlzLl9zaWRlLl9jb250ZW50LnN0eWxlLm9wYWNpdHkgPSAnJztcbiAgICAgICAgICBkb25lICYmIGRvbmUoKTtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgX2dldE1heFdpZHRoKCkge1xuICAgIHJldHVybiB0aGlzLl9zaWRlLm9mZnNldFdpZHRoO1xuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEFuaW1hdG9yRmFjdG9yeSBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvYW5pbWF0b3ItZmFjdG9yeSc7XG5pbXBvcnQgT3ZlcmxheVNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9vdmVybGF5LWFuaW1hdG9yJztcbmltcG9ydCBQdXNoU3BsaXR0ZXJBbmltYXRvciBmcm9tICcuL3B1c2gtYW5pbWF0b3InO1xuaW1wb3J0IFJldmVhbFNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9yZXZlYWwtYW5pbWF0b3InO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlciBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvZGV2aWNlLWJhY2stYnV0dG9uLWRpc3BhdGNoZXInO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi8uLi9vbnMvY29udGVudC1yZWFkeSc7XG5cbmNvbnN0IF9hbmltYXRvckRpY3QgPSB7XG4gIGRlZmF1bHQ6IE92ZXJsYXlTcGxpdHRlckFuaW1hdG9yLFxuICBvdmVybGF5OiBPdmVybGF5U3BsaXR0ZXJBbmltYXRvcixcbiAgcHVzaDogUHVzaFNwbGl0dGVyQW5pbWF0b3IsXG4gIHJldmVhbDogUmV2ZWFsU3BsaXR0ZXJBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc3BsaXR0ZXJcbiAqIEBjYXRlZ29yeSBtZW51XG4gKiBAZGVzY3JpcHRpb25cbiAqICBbZW5dXG4gKiAgICBBIGNvbXBvbmVudCB0aGF0IGVuYWJsZXMgcmVzcG9uc2l2ZSBsYXlvdXQgYnkgaW1wbGVtZW50aW5nIGJvdGggYSB0d28tY29sdW1uIGxheW91dCBhbmQgYSBzbGlkaW5nIG1lbnUgbGF5b3V0LlxuICpcbiAqICAgIEl0IGNhbiBiZSBjb25maWd1cmVkIHRvIGF1dG9tYXRpY2FsbHkgZXhwYW5kIGludG8gYSBjb2x1bW4gbGF5b3V0IG9uIGxhcmdlIHNjcmVlbnMgYW5kIGNvbGxhcHNlIHRoZSBtZW51IG9uIHNtYWxsZXIgc2NyZWVucy4gV2hlbiB0aGUgbWVudSBpcyBjb2xsYXBzZWQgdGhlIHVzZXIgY2FuIG9wZW4gaXQgYnkgc3dpcGluZy5cbiAqICBbL2VuXVxuICogIFtqYV1bL2phXVxuICogQGNvZGVwZW4gck9RT01MXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3BsaXR0ZXJcbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogIFtlbl1NYW5hZ2luZyBtdWx0aXBsZSBwYWdlcy5bL2VuXVxuICogIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyLWNvbnRlbnRcbiAqICBbZW5dVGhlIGA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+YCBjb21wb25lbnQgY29udGFpbnMgdGhlIG1haW4gY29udGVudCBvZiB0aGUgcGFnZS5bL2VuXVxuICogIFtqYV1vbnMtc3BsaXR0ZXItY29udGVudOOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtc3BsaXR0ZXItc2lkZVxuICogIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXItc2lkZT5gIGNvbXBvbmVudCBjb250YWlucyB0aGUgbWVudS5bL2VuXVxuICogIFtqYV1vbnMtc3BsaXR0ZXItc2lkZeOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAZXhhbXBsZVxuICogPG9ucy1zcGxpdHRlciBpZD1cInNwbGl0dGVyXCI+XG4gKiAgIDxvbnMtc3BsaXR0ZXItY29udGVudD5cbiAqICAgICAuLi5cbiAqICAgPC9vbnMtc3BsaXR0ZXItY29udGVudD5cbiAqXG4gKiAgIDxvbnMtc3BsaXR0ZXItc2lkZSBzaWRlPVwibGVmdFwiIHdpZHRoPVwiODAlXCIgY29sbGFwc2Ugc3dpcGVhYmxlPlxuICogICAgIC4uLlxuICogICA8L29ucy1zcGxpdHRlci1zaWRlPlxuICogPC9vbnMtc3BsaXR0ZXI+XG4gKlxuICogPHNjcmlwdD5cbiAqICAgdmFyIHNwbGl0dGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NwbGl0dGVyJyk7XG4gKiAgIHNwbGl0dGVyLmxlZnQub3BlbigpO1xuICogPC9zY3JpcHQ+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICBfZ2V0U2lkZShzaWRlKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHV0aWwuZmluZENoaWxkKHRoaXMsIGUgPT4ge1xuICAgICAgcmV0dXJuIHV0aWwubWF0Y2goZSwgJ29ucy1zcGxpdHRlci1zaWRlJykgJiYgZS5nZXRBdHRyaWJ1dGUoJ3NpZGUnKSA9PT0gc2lkZTtcbiAgICB9KTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgbGVmdFxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dTGVmdCBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IGxlZnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldFNpZGUoJ2xlZnQnKTtcbiAgfVxuICAvKipcbiAgICogQHByb3BlcnR5IHJpZ2h0XG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1SaWdodCBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IHJpZ2h0KCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRTaWRlKCdyaWdodCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzaWRlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJzdCBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudCByZWdhcmRsZXNzIHRoZSBhY3R1YWwgc2lkZS5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgZ2V0IHNpZGUoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICdvbnMtc3BsaXR0ZXItc2lkZScpO1xuICB9XG5cbiAgZ2V0IF9zaWRlcygpIHtcbiAgICByZXR1cm4gW3RoaXMubGVmdCwgdGhpcy5yaWdodF0uZmlsdGVyKGUgPT4gZSk7XG4gIH1cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjb250ZW50XG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXItY29udGVudD5gIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBjb250ZW50KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCAnb25zLXNwbGl0dGVyLWNvbnRlbnQnKTtcbiAgfVxuXG4gIGdldCB0b3BQYWdlKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnQuX2NvbnRlbnQ7XG4gIH1cblxuICBnZXQgbWFzaygpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJ29ucy1zcGxpdHRlci1tYXNrJyk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cbiAgZ2V0IG9uRGV2aWNlQmFja0J1dHRvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fYmFja0J1dHRvbkhhbmRsZXI7XG4gIH1cblxuICBzZXQgb25EZXZpY2VCYWNrQnV0dG9uKGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX2JhY2tCdXR0b25IYW5kbGVyKSB7XG4gICAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBkZXZpY2VCYWNrQnV0dG9uRGlzcGF0Y2hlci5jcmVhdGVIYW5kbGVyKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIF9vbkRldmljZUJhY2tCdXR0b24oZXZlbnQpIHtcbiAgICB0aGlzLl9zaWRlcy5zb21lKHMgPT4gcy5pc09wZW4gPyBzLmNsb3NlKCkgOiBmYWxzZSkgfHwgZXZlbnQuY2FsbFBhcmVudEhhbmRsZXIoKTtcbiAgfVxuXG4gIF9vbk1vZGVDaGFuZ2UoZSkge1xuICAgIGlmIChlLnRhcmdldC5wYXJlbnROb2RlKSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICB0aGlzLl9sYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIF9sYXlvdXQoKSB7XG4gICAgdGhpcy5fc2lkZXMuZm9yRWFjaChzaWRlID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbnRlbnQpIHtcbiAgICAgICAgdGhpcy5jb250ZW50LnN0eWxlW3NpZGUuc2lkZV0gPSBzaWRlLm1vZGUgPT09ICdzcGxpdCcgPyBzaWRlLnN0eWxlLndpZHRoIDogMDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9vbk1vZGVDaGFuZ2UgPSB0aGlzLl9vbk1vZGVDaGFuZ2UuYmluZCh0aGlzKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICAhdGhpcy5tYXNrICYmIHRoaXMuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnb25zLXNwbGl0dGVyLW1hc2snKSk7XG4gICAgICB0aGlzLl9sYXlvdXQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMub25EZXZpY2VCYWNrQnV0dG9uID0gdGhpcy5fb25EZXZpY2VCYWNrQnV0dG9uLmJpbmQodGhpcyk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdtb2RlY2hhbmdlJywgdGhpcy5fb25Nb2RlQ2hhbmdlLCBmYWxzZSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9iYWNrQnV0dG9uSGFuZGxlci5kZXN0cm95KCk7XG4gICAgdGhpcy5fYmFja0J1dHRvbkhhbmRsZXIgPSBudWxsO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW9kZWNoYW5nZScsIHRoaXMuX29uTW9kZUNoYW5nZSwgZmFsc2UpO1xuICB9XG5cbiAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKG5hbWUsIGxhc3QsIGN1cnJlbnQpIHt9XG5cbiAgX3Nob3coKSB7XG4gICAgdXRpbC5wcm9wYWdhdGVBY3Rpb24odGhpcywgJ19zaG93Jyk7XG4gIH1cblxuICBfaGlkZSgpIHtcbiAgICB1dGlsLnByb3BhZ2F0ZUFjdGlvbih0aGlzLCAnX2hpZGUnKTtcbiAgfVxuXG4gIF9kZXN0cm95KCkge1xuICAgIHV0aWwucHJvcGFnYXRlQWN0aW9uKHRoaXMsICdfZGVzdHJveScpO1xuICAgIHRoaXMucmVtb3ZlKCk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXJBbmltYXRvcihuYW1lLCBBbmltYXRvcikge1xuICAgIGlmICghKEFuaW1hdG9yIGluc3RhbmNlb2YgU3BsaXR0ZXJBbmltYXRvcikpIHtcbiAgICAgIHV0aWwudGhyb3dBbmltYXRvcignU3BsaXR0ZXInKTtcbiAgICB9XG4gICAgX2FuaW1hdG9yRGljdFtuYW1lXSA9IEFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBTcGxpdHRlckFuaW1hdG9yKCkge1xuICAgIHJldHVybiBTcGxpdHRlckFuaW1hdG9yO1xuICB9XG5cbiAgc3RhdGljIGdldCBhbmltYXRvcnMoKSB7XG4gICAgcmV0dXJuIF9hbmltYXRvckRpY3Q7XG4gIH1cbn1cblxub25zRWxlbWVudHMuU3BsaXR0ZXIgPSBTcGxpdHRlckVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zcGxpdHRlcicsIFNwbGl0dGVyRWxlbWVudCk7XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uL29ucy91dGlsJztcbmltcG9ydCBBbmltYXRvckZhY3RvcnkgZnJvbSAnLi4vb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnknO1xuaW1wb3J0IG9yaWVudGF0aW9uIGZyb20gJy4uL29ucy9vcmllbnRhdGlvbic7XG5pbXBvcnQgaW50ZXJuYWwgZnJvbSAnLi4vb25zL2ludGVybmFsJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWVsZW1lbnQnO1xuaW1wb3J0IFNwbGl0dGVyQW5pbWF0b3IgZnJvbSAnLi9vbnMtc3BsaXR0ZXIvYW5pbWF0b3InO1xuaW1wb3J0IFN3aXBlUmV2ZWFsIGZyb20gJy4uL29ucy9pbnRlcm5hbC9zd2lwZS1yZXZlYWwnO1xuaW1wb3J0IERvb3JMb2NrIGZyb20gJy4uL29ucy9kb29ybG9jayc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCB7IFBhZ2VMb2FkZXIsIGRlZmF1bHRQYWdlTG9hZGVyfSBmcm9tICcuLi9vbnMvcGFnZS1sb2FkZXInO1xuaW1wb3J0IFNwbGl0dGVyRWxlbWVudCBmcm9tICcuL29ucy1zcGxpdHRlcic7XG5cbmNvbnN0IFNQTElUX01PREUgPSAnc3BsaXQnO1xuY29uc3QgQ09MTEFQU0VfTU9ERSA9ICdjb2xsYXBzZSc7XG5jb25zdCBDTE9TRURfU1RBVEUgPSAnY2xvc2VkJztcbmNvbnN0IE9QRU5fU1RBVEUgPSAnb3Blbic7XG5jb25zdCBDSEFOR0lOR19TVEFURSA9ICdjaGFuZ2luZyc7XG5cbmNvbnN0IHJld3JpdGFibGVzID0ge1xuICAvKipcbiAgICogQHBhcmFtIHtFbGVtZW50fSBzcGxpdHRlclNpZGVFbGVtZW50XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICByZWFkeShzcGxpdHRlclNpZGVFbGVtZW50LCBjYWxsYmFjaykge1xuICAgIHNldEltbWVkaWF0ZShjYWxsYmFjayk7XG4gIH1cbn07XG5cbmNsYXNzIENvbGxhcHNlRGV0ZWN0aW9uIHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgdGFyZ2V0KSB7XG4gICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRhcmdldCAmJiB0aGlzLmNoYW5nZVRhcmdldCh0YXJnZXQpO1xuICB9XG5cbiAgY2hhbmdlVGFyZ2V0KHRhcmdldCkge1xuICAgIHRoaXMuZGlzYWJsZSgpO1xuICAgIHRoaXMuX3RhcmdldCA9IHRhcmdldDtcbiAgICBpZiAodGFyZ2V0KSB7XG4gICAgICB0aGlzLl9vcmllbnRhdGlvbiA9IFsncG9ydHJhaXQnLCAnbGFuZHNjYXBlJ10uaW5kZXhPZih0YXJnZXQpICE9PSAtMTtcbiAgICAgIHRoaXMuYWN0aXZhdGUoKTtcbiAgICB9XG4gIH1cblxuICBfbWF0Y2godmFsdWUpIHtcbiAgICBpZiAodGhpcy5fb3JpZW50YXRpb24pIHtcbiAgICAgIHJldHVybiB0aGlzLl90YXJnZXQgPT09ICh2YWx1ZS5pc1BvcnRyYWl0ID8gJ3BvcnRyYWl0JyA6ICdsYW5kc2NhcGUnKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlLm1hdGNoZXM7XG4gIH1cblxuICBfb25DaGFuZ2UodmFsdWUpIHtcbiAgICB0aGlzLl9lbGVtZW50Ll91cGRhdGVNb2RlKHRoaXMuX21hdGNoKHZhbHVlKSA/IENPTExBUFNFX01PREUgOiBTUExJVF9NT0RFKTtcbiAgfVxuXG4gIGFjdGl2YXRlKCkge1xuICAgIGlmICh0aGlzLl9vcmllbnRhdGlvbikge1xuICAgICAgb3JpZW50YXRpb24ub24oJ2NoYW5nZScsIHRoaXMuX29uQ2hhbmdlKTtcbiAgICAgIHRoaXMuX29uQ2hhbmdlKHtpc1BvcnRyYWl0OiBvcmllbnRhdGlvbi5pc1BvcnRyYWl0KCl9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcXVlcnlSZXN1bHQgPSB3aW5kb3cubWF0Y2hNZWRpYSh0aGlzLl90YXJnZXQpO1xuICAgICAgdGhpcy5fcXVlcnlSZXN1bHQuYWRkTGlzdGVuZXIodGhpcy5fb25DaGFuZ2UpO1xuICAgICAgdGhpcy5fb25DaGFuZ2UodGhpcy5fcXVlcnlSZXN1bHQpO1xuICAgIH1cbiAgfVxuXG4gIGRpc2FibGUoKSB7XG4gICAgaWYgKHRoaXMuX29yaWVudGF0aW9uKSB7XG4gICAgICBvcmllbnRhdGlvbi5vZmYoJ2NoYW5nZScsIHRoaXMuX29uQ2hhbmdlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3F1ZXJ5UmVzdWx0KSB7XG4gICAgICB0aGlzLl9xdWVyeVJlc3VsdC5yZW1vdmVMaXN0ZW5lcih0aGlzLl9vbkNoYW5nZSk7XG4gICAgICB0aGlzLl9xdWVyeVJlc3VsdCA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHdpZHRoVG9QeCA9ICh3aWR0aCwgcGFyZW50KSA9PiB7XG4gIGNvbnN0IFt2YWx1ZSwgcHhdID0gW3BhcnNlSW50KHdpZHRoLCAxMCksIC9weC8udGVzdCh3aWR0aCldO1xuICByZXR1cm4gcHggPyB2YWx1ZSA6IE1hdGgucm91bmQocGFyZW50Lm9mZnNldFdpZHRoICogdmFsdWUgLyAxMDApO1xufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc3BsaXR0ZXItc2lkZVxuICogQGNhdGVnb3J5IG1lbnVcbiAqIEBkZXNjcmlwdGlvblxuICogIFtlbl1cbiAqICAgIFRoZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudCBpcyB1c2VkIGFzIGEgY2hpbGQgZWxlbWVudCBvZiBgPG9ucy1zcGxpdHRlcj5gLlxuICpcbiAqICAgIEl0IHdpbGwgYmUgZGlzcGxheWVkIG9uIGVpdGhlciB0aGUgbGVmdCBvciByaWdodCBzaWRlIG9mIHRoZSBgPG9ucy1zcGxpdHRlci1jb250ZW50PmAgZWxlbWVudC5cbiAqXG4gKiAgICBJdCBzdXBwb3J0cyB0d28gbW9kZXM6IGNvbGxhcHNlZCBhbmQgc3BsaXQuIFdoZW4gaXQncyBpbiBjb2xsYXBzZWQgbW9kZSBpdCB3aWxsIGJlIGhpZGRlbiBmcm9tIHZpZXcgYW5kIGNhbiBiZSBkaXNwbGF5ZWQgd2hlbiB0aGUgdXNlciBzd2lwZXMgdGhlIHNjcmVlbiBvciB0YXBzIGEgYnV0dG9uLiBJbiBzcGxpdCBtb2RlIHRoZSBlbGVtZW50IGlzIGFsd2F5cyBzaG93bi4gSXQgY2FuIGJlIGNvbmZpZ3VyZWQgdG8gYXV0b21hdGljYWxseSBzd2l0Y2ggYmV0d2VlbiB0aGUgdHdvIG1vZGVzIGRlcGVuZGluZyBvbiB0aGUgc2NyZWVuIHNpemUuXG4gKiAgWy9lbl1cbiAqICBbamFdb25zLXNwbGl0dGVyLXNpZGXopoHntKDjga/jgIFvbnMtc3BsaXR0ZXLopoHntKDjga7lrZDopoHntKDjgajjgZfjgabliKnnlKjjgZfjgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gck9RT01MXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3BsaXR0ZXJcbiAqIEBndWlkZSBmdW5kYW1lbnRhbHMuaHRtbCNtYW5hZ2luZy1wYWdlc1xuICogIFtlbl1NYW5hZ2luZyBtdWx0aXBsZSBwYWdlcy5bL2VuXVxuICogIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXVxuICogQHNlZWFsc28gb25zLXNwbGl0dGVyXG4gKiAgW2VuXVRoZSBgPG9ucy1zcGxpdHRlcj5gIGlzIHRoZSBwYXJlbnQgY29tcG9uZW50LlsvZW5dXG4gKiAgW2phXW9ucy1zcGxpdHRlcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtc3BsaXR0ZXItY29udGVudFxuICogIFtlbl1UaGUgYDxvbnMtc3BsaXR0ZXItY29udGVudD5gIGNvbXBvbmVudCBjb250YWlucyB0aGUgbWFpbiBjb250ZW50IG9mIHRoZSBwYWdlLlsvZW5dXG4gKiAgW2phXW9ucy1zcGxpdHRlci1jb250ZW5044Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXNwbGl0dGVyPlxuICogICA8b25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKiAgICAgLi4uXG4gKiAgIDwvb25zLXNwbGl0dGVyLWNvbnRlbnQ+XG4gKlxuICogICA8b25zLXNwbGl0dGVyLXNpZGUgc2lkZT1cImxlZnRcIiB3aWR0aD1cIjgwJVwiIGNvbGxhcHNlPlxuICogICAgIC4uLlxuICogICA8L29ucy1zcGxpdHRlci1zaWRlPlxuICogPC9vbnMtc3BsaXR0ZXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNwbGl0dGVyU2lkZUVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBtb2RlY2hhbmdlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlZCBqdXN0IGFmdGVyIHRoZSBjb21wb25lbnQncyBtb2RlIGNoYW5nZXMuWy9lbl1cbiAgICogICBbamFd44GT44Gu6KaB57Sg44Gu44Oi44O844OJ44GM5aSJ5YyW44GX44Gf6Zqb44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuc2lkZVxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudC5tb2RlXG4gICAqICAgW2VuXVJldHVybnMgdGhlIGN1cnJlbnQgbW9kZS4gQ2FuIGJlIGVpdGhlciBgXCJjb2xsYXBzZVwiYCBvciBgXCJzcGxpdFwiYC5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjga7jg6Ljg7zjg4njgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHByZW9wZW5cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVkIGp1c3QgYmVmb3JlIHRoZSBzbGlkaW5nIG1lbnUgaXMgb3BlbmVkLlsvZW5dXG4gICAqICAgW2phXeOCueODqeOCpOODh+OCo+ODs+OCsOODoeODi+ODpeODvOOBjOmWi+OBj+WJjeOBq+eZuueBq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICAgKiAgIFtlbl1FdmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44Kq44OW44K444Kn44Kv44OI44Gn44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXZlbnQuY2FuY2VsXG4gICAqICAgW2VuXUNhbGwgdG8gY2FuY2VsIG9wZW5pbmcgc2xpZGluZyBtZW51LlsvZW5dXG4gICAqICAgW2phXeOCueODqeOCpOODh+OCo+ODs+OCsOODoeODi+ODpeODvOOBjOmWi+OBj+OBruOCkuOCreODo+ODs+OCu+ODq+OBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5zaWRlXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0b3BlblxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgc2xpZGluZyBtZW51IGlzIG9wZW5lZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjg6njgqTjg4fjgqPjg7PjgrDjg6Hjg4vjg6Xjg7zjgYzplovjgYTjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5zaWRlXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVjbG9zZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBiZWZvcmUgdGhlIHNsaWRpbmcgbWVudSBpcyBjbG9zZWQuWy9lbl1cbiAgICogICBbamFd44K544Op44Kk44OH44Kj44Oz44Kw44Oh44OL44Ol44O844GM6ZaJ44GY44KL5YmN44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgafjgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuc2lkZVxuICAgKiAgIFtlbl1Db21wb25lbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCs+ODs+ODneODvOODjeODs+ODiOOBruOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1DYWxsIHRvIGNhbmNlbCBvcGVuaW5nIHNsaWRpbmctbWVudS5bL2VuXVxuICAgKiAgIFtqYV3jgrnjg6njgqTjg4fjgqPjg7PjgrDjg6Hjg4vjg6Xjg7zjgYzplonjgZjjgovjga7jgpLjgq3jg6Pjg7Pjgrvjg6vjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGV2ZW50IHBvc3RjbG9zZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQganVzdCBhZnRlciB0aGUgc2xpZGluZyBtZW51IGlzIGNsb3NlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjg6njgqTjg4fjgqPjg7PjgrDjg6Hjg4vjg6Xjg7zjgYzplonjgZjjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOBp+OBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5zaWRlXG4gICAqICAgW2VuXUNvbXBvbmVudCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kz44Oz44Od44O844ON44Oz44OI44Gu44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0ICBkZWZhdWx0XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbi4gVXNlIG9uZSBvZiBgb3ZlcmxheWAsIGBwdXNoYCwgYHJldmVhbGAgb3IgIGBkZWZhdWx0YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+OCkuaMh+WumuOBl+OBvuOBmeOAglwib3ZlcmxheVwiLCBcInB1c2hcIiwgXCJyZXZlYWxcIiwgXCJkZWZhdWx0XCLjga7jgYTjgZrjgozjgYvjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb24tb3B0aW9uc1xuICAgKiBAdHlwZSB7RXhwcmVzc2lvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIHRpbWluZyBhbmQgZGVsYXkgd2l0aCBhbiBvYmplY3QgbGl0ZXJhbC4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAxLCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgb3Blbi10aHJlc2hvbGRcbiAgICogQHR5cGUge051bWJlcn1cbiAgICogQGRlZmF1bHQgIDAuM1xuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1TcGVjaWZ5IGhvdyBtdWNoIHRoZSBtZW51IG5lZWRzIHRvIGJlIHN3aXBlZCBiZWZvcmUgb3BlbmluZy4gQSB2YWx1ZSBiZXR3ZWVuIGAwYCBhbmQgYDFgLlsvZW5dXG4gICAqICBbamFd44Gp44Gu44GP44KJ44GE44K544Ov44Kk44OX44GZ44KM44Gw44K544Op44Kk44OH44Kj44Oz44Kw44Oh44OL44Ol44O844KS6ZaL44GP44GL44Gp44GG44GL44Gu5Ymy5ZCI44KS5oyH5a6a44GX44G+44GZ44CCMOOBi+OCiTHjga7plpPjga7mlbDlgKTjgpLmjIflrprjgZfjgb7jgZnjgILjgrnjg6/jgqTjg5fjga7ot53pm6LjgYzjgZPjgZPjgafmjIflrprjgZfjgZ/mlbDlgKTmjpvjgZHjgovjgZPjga7opoHntKDjga7luYXjgojjgorjgoLlpKfjgY3jgZHjgozjgbDjgIHjgrnjg6/jgqTjg5fjgYzntYLjgo/jgaPjgZ/mmYLjgavjgZPjga7opoHntKDjgpLplovjgY3jgb7jgZnjgILjg4fjg5Xjgqnjg6vjg4jjga8wLjPjgafjgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjb2xsYXBzZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBTcGVjaWZ5IHRoZSBjb2xsYXBzZSBiZWhhdmlvci4gVmFsaWQgdmFsdWVzIGFyZSBgXCJwb3J0cmFpdFwiYCwgYFwibGFuZHNjYXBlXCJgIG9yIGEgbWVkaWEgcXVlcnkuXG4gICAqICAgICBUaGUgc3RyaW5ncyBgXCJwb3J0cmFpdFwiYCBhbmQgYFwibGFuZHNjYXBlXCJgIG1lYW5zIHRoZSB2aWV3IHdpbGwgY29sbGFwc2Ugd2hlbiBkZXZpY2UgaXMgaW4gbGFuZHNjYXBlIG9yIHBvcnRyYWl0IG9yaWVudGF0aW9uLlxuICAgKiAgICAgSWYgdGhlIHZhbHVlIGlzIGEgbWVkaWEgcXVlcnksIHRoZSB2aWV3IHdpbGwgY29sbGFwc2Ugd2hlbiB0aGUgbWVkaWEgcXVlcnkgcmVzb2x2ZXMgdG8gYHRydWVgLlxuICAgKiAgICAgSWYgdGhlIHZhbHVlIGlzIG5vdCBkZWZpbmVkLCB0aGUgdmlldyBhbHdheXMgYmUgaW4gYFwiY29sbGFwc2VcImAgbW9kZS5cbiAgICogICBbL2VuXVxuICAgKiAgIFtqYV1cbiAgICogICAgIOW3puWBtOOBruODmuODvOOCuOOCkumdnuihqOekuuOBq+OBmeOCi+adoeS7tuOCkuaMh+WumuOBl+OBvuOBmeOAgnBvcnRyYWl0LCBsYW5kc2NhcGXjgIF3aWR0aCAjcHjjgoLjgZfjgY/jga/jg6Hjg4fjgqPjgqLjgq/jgqjjg6rjga7mjIflrprjgYzlj6/og73jgafjgZnjgIJcbiAgICogICAgIHBvcnRyYWl044KC44GX44GP44GvbGFuZHNjYXBl44KS5oyH5a6a44GZ44KL44Go44CB44OH44OQ44Kk44K544Gu55S76Z2i44GM57im5ZCR44GN44KC44GX44GP44Gv5qiq5ZCR44GN44Gr44Gq44Gj44Gf5pmC44Gr6YGp55So44GV44KM44G+44GZ44CCXG4gICAqICAgICDjg6Hjg4fjgqPjgqLjgq/jgqjjg6rjgpLmjIflrprjgZnjgovjgajjgIHmjIflrprjgZfjgZ/jgq/jgqjjg6rjgavpganlkIjjgZfjgabjgYTjgovloLTlkIjjgavpgannlKjjgZXjgozjgb7jgZnjgIJcbiAgICogICAgIOWApOOBq+S9leOCguaMh+WumuOBl+OBquOBhOWgtOWQiOOBq+OBr+OAgeW4uOOBq2NvbGxhcHNl44Oi44O844OJ44Gr44Gq44KK44G+44GZ44CCXG4gICAqICAgWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgc3dpcGUtdGFyZ2V0LXdpZHRoXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgd2lkdGggb2Ygc3dpcGVhYmxlIGFyZWEgY2FsY3VsYXRlZCBmcm9tIHRoZSBlZGdlIChpbiBwaXhlbHMpLiBVc2UgdGhpcyB0byBlbmFibGUgc3dpcGUgb25seSB3aGVuIHRoZSBmaW5nZXIgdG91Y2ggb24gdGhlIHNjcmVlbiBlZGdlLlsvZW5dXG4gICAqICAgW2phXeOCueODr+OCpOODl+OBruWIpOWumumgmOWfn+OCkuODlOOCr+OCu+ODq+WNmOS9jeOBp+aMh+WumuOBl+OBvuOBmeOAgueUu+mdouOBruerr+OBi+OCieaMh+WumuOBl+OBn+i3nembouOBq+mBlOOBmeOCi+OBqOODmuODvOOCuOOBjOihqOekuuOBleOCjOOBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHdpZHRoXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DYW4gYmUgc3BlY2lmaWVkIGluIGVpdGhlciBwaXhlbHMgb3IgYXMgYSBwZXJjZW50YWdlLCBlLmcuIGA5MCVgIG9yIGAyMDBweGAuWy9lbl1cbiAgICogICBbamFd44GT44Gu6KaB57Sg44Gu5qiq5bmF44KS5oyH5a6a44GX44G+44GZ44CCcHjjgagl44Gn44Gu5oyH5a6a44GM5Y+v6IO944Gn44GZ44CCZWcuIDkwJSwgMjAwcHhbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzaWRlXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGxlZnRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNwZWNpZnkgd2hpY2ggc2lkZSBvZiB0aGUgc2NyZWVuIHRoZSBgPG9ucy1zcGxpdHRlci1zaWRlPmAgZWxlbWVudCBpcyBsb2NhdGVkLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBcImxlZnRcImAgYW5kIGBcInJpZ2h0XCJgLlsvZW5dXG4gICAqICAgW2phXeOBk+OBruimgee0oOOBjOW3puOBi+WPs+OBi+OCkuaMh+WumuOBl+OBvuOBmeOAguaMh+WumuOBp+OBjeOCi+WApOOBr1wibGVmdFwi44GLXCJyaWdodFwi44Gu44G/44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgbW9kZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBtb2RlLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIGBcImNvbGxhcHNlXCJgIG9yIGBcInNwbGl0XCJgLiBUaGlzIGF0dHJpYnV0ZSBpcyByZWFkIG9ubHkuWy9lbl1cbiAgICogICBbamFd54++5Zyo44Gu44Oi44O844OJ44GM6Kit5a6a44GV44KM44G+44GZ44CCXCJjb2xsYXBzZVwi44KC44GX44GP44GvXCJzcGxpdFwi44GM5oyH5a6a44GV44KM44G+44GZ44CC44GT44Gu5bGe5oCn44Gv6Kqt44G/6L6844G/5bCC55So44Gn44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgcGFnZVxuICAgKiBAaW5pdG9ubHlcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBVUkwgb2YgdGhlIG1lbnUgcGFnZS5bL2VuXVxuICAgKiAgIFtqYV1vbnMtc3BsaXR0ZXItc2lkZeimgee0oOOBq+ihqOekuuOBmeOCi+ODmuODvOOCuOOBrlVSTOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHN3aXBlYWJsZVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdG8gZW5hYmxlIHN3aXBlIGludGVyYWN0aW9uIG9uIGNvbGxhcHNlIG1vZGUuWy9lbl1cbiAgICogICBbamFdY29sbGFwc2Xjg6Ljg7zjg4nmmYLjgavjgrnjg6/jgqTjg5fmk43kvZzjgpLmnInlirnjgavjgZnjgovloLTlkIjjgavmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fcGFnZSA9IG51bGw7XG4gICAgdGhpcy5fc3RhdGUgPSBDTE9TRURfU1RBVEU7XG4gICAgdGhpcy5fbG9jayA9IG5ldyBEb29yTG9jaygpO1xuICAgIHRoaXMuX3BhZ2VMb2FkZXIgPSBkZWZhdWx0UGFnZUxvYWRlcjtcbiAgICB0aGlzLl9jb2xsYXBzZURldGVjdGlvbiA9IG5ldyBDb2xsYXBzZURldGVjdGlvbih0aGlzKTtcblxuICAgIHRoaXMuX2FuaW1hdG9yRmFjdG9yeSA9IG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBTcGxpdHRlckVsZW1lbnQuYW5pbWF0b3JzLFxuICAgICAgYmFzZUNsYXNzOiBTcGxpdHRlckFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ1NwbGl0dGVyQW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgLy8gVGhlc2UgYXR0cmlidXRlcyBhcmUgdXNlZCBlYXJseSBieSB0aGUgcGFyZW50IGVsZW1lbnRcbiAgICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCd3aWR0aCcpO1xuICAgICAgaWYgKCF0aGlzLmhhc0F0dHJpYnV0ZSgnc2lkZScpKSB7XG4gICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdzaWRlJywgJ2xlZnQnKTtcbiAgICAgIH1cblxuICAgICAgcmV3cml0YWJsZXMucmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICBjb25zdCBwYWdlID0gdGhpcy5fcGFnZSB8fCB0aGlzLmdldEF0dHJpYnV0ZSgncGFnZScpO1xuICAgICAgICBwYWdlICYmIHRoaXMubG9hZChwYWdlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgaWYgKCF1dGlsLm1hdGNoKHRoaXMucGFyZW50Tm9kZSwgJ29ucy1zcGxpdHRlcicpKSB7XG4gICAgICB1dGlsLnRocm93KCdQYXJlbnQgbXVzdCBiZSBhbiBvbnMtc3BsaXR0ZXIgZWxlbWVudCcpO1xuICAgIH1cblxuICAgIHRoaXMuX3N3aXBlID0gbmV3IFN3aXBlUmV2ZWFsKHtcbiAgICAgIGVsZW1lbnQ6IHRoaXMsXG4gICAgICBlbGVtZW50SGFuZGxlcjogdGhpcy5wYXJlbnRFbGVtZW50LFxuICAgICAgc3dpcGVNYXg6ICgpID0+IHtcbiAgICAgICAgdGhpcy5fb25Td2lwZSAmJiB0aGlzLl9vblN3aXBlKDEsIHRoaXMuX2FuaW1hdGlvbk9wdCk7XG4gICAgICAgIHRoaXMub3BlbigpO1xuICAgICAgfSxcbiAgICAgIHN3aXBlTWlkOiAoZGlzdGFuY2UsIHdpZHRoKSA9PiB7XG4gICAgICAgIHRoaXMuX29uU3dpcGUgJiYgdGhpcy5fb25Td2lwZShkaXN0YW5jZS93aWR0aCk7XG4gICAgICAgIHRoaXMuX2FuaW1hdG9yLnRyYW5zbGF0ZShkaXN0YW5jZSk7XG4gICAgICB9LFxuICAgICAgc3dpcGVNaW46ICgpID0+IHtcbiAgICAgICAgdGhpcy5fb25Td2lwZSAmJiB0aGlzLl9vblN3aXBlKDAsIHRoaXMuX2FuaW1hdGlvbk9wdCk7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgIH0sXG4gICAgICBnZXRUaHJlc2hvbGQ6ICgpID0+IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHBhcnNlRmxvYXQodGhpcy5nZXRBdHRyaWJ1dGUoJ29wZW4tdGhyZXNob2xkJykpIHx8IDAuMykpLFxuICAgICAgZ2V0U2lkZTogKCkgPT4gdGhpcy5zaWRlLFxuICAgICAgaXNJbml0aWFsU3RhdGU6ICgpID0+IHtcbiAgICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5fc3RhdGUgPT09IENMT1NFRF9TVEFURTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBDSEFOR0lOR19TVEFURTtcbiAgICAgICAgcmV0dXJuIGNsb3NlZDtcbiAgICAgIH0sXG4gICAgICBpZ25vcmVTd2lwZTogKGV2ZW50LCBkaXN0YW5jZSkgPT4ge1xuICAgICAgICBjb25zdCBpc09wZW4gPSB0aGlzLmlzT3BlbjtcbiAgICAgICAgY29uc3QgdmFsaWREcmFnID0gZCA9PiB0aGlzLnNpZGUgPT09ICdsZWZ0J1xuICAgICAgICAgID8gKChkID09PSAnbGVmdCcgJiYgaXNPcGVuKSB8fCAoZCA9PT0gJ3JpZ2h0JyAmJiAhaXNPcGVuKSlcbiAgICAgICAgICA6ICgoZCA9PT0gJ2xlZnQnICYmICFpc09wZW4pIHx8IChkID09PSAncmlnaHQnICYmIGlzT3BlbikpO1xuXG4gICAgICAgIGNvbnN0IGFyZWEgPSBNYXRoLm1heCgwLCBwYXJzZUludCh0aGlzLmdldEF0dHJpYnV0ZSgnc3dpcGUtdGFyZ2V0LXdpZHRoJyksIDEwKSB8fCAwKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fbW9kZSA9PT0gU1BMSVRfTU9ERSB8fCB0aGlzLl9sb2NrLmlzTG9ja2VkKCkgfHwgdGhpcy5faXNPdGhlclNpZGVPcGVuKClcbiAgICAgICAgICB8fCAhdmFsaWREcmFnKGV2ZW50Lmdlc3R1cmUuZGlyZWN0aW9uKVxuICAgICAgICAgIHx8ICghaXNPcGVuICYmIGFyZWEgIT09IDAgJiYgZGlzdGFuY2UgPiBhcmVhKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdzd2lwZWFibGUnKTtcblxuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yLm9ic2VydmVkQXR0cmlidXRlcy5mb3JFYWNoKGF0dHIgPT4gdGhpcy5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soYXR0ciwgbnVsbCwgdGhpcy5nZXRBdHRyaWJ1dGUoYXR0cikpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBzaWRlKCkge1xuICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgnc2lkZScpID09PSAncmlnaHQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuX3N3aXBlICYmIHRoaXMuX3N3aXBlLmRpc3Bvc2UoKTtcbiAgICB0aGlzLl9hbmltYXRvciA9IHRoaXMuX2FuaW1hdGlvbk9wdCA9IHRoaXMuX3N3aXBlID0gbnVsbDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2FuaW1hdGlvbicsICd3aWR0aCcsICdjb2xsYXBzZScsICdzd2lwZWFibGUnLCAnYW5pbWF0aW9uLW9wdGlvbnMnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdzd2lwZWFibGUnOlxuICAgICAgICB0aGlzLl9zd2lwZSAmJiB0aGlzLl9zd2lwZS51cGRhdGUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd3aWR0aCc6XG4gICAgICAgIGN1cnJlbnQgPSB0aGlzLmdldEF0dHJpYnV0ZSgnd2lkdGgnKTsgLy8gU29tZXRpbWVzIHVuZGVmaW5lZC4gQ0UgYnVnP1xuICAgICAgICB0aGlzLnN0eWxlLndpZHRoID0gL15cXGQrKHB4fCUpJC8udGVzdChjdXJyZW50KSA/IGN1cnJlbnQgOiAnODAlJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzW3V0aWwuY2FtZWxpemUoYF91cGRhdGUtJHtuYW1lfWApXShjdXJyZW50KTtcbiAgICB9XG4gIH1cblxuICBfZW1pdEV2ZW50KG5hbWUpIHtcbiAgICBpZiAobmFtZS5zbGljZSgwLCAzKSAhPT0gJ3ByZScpIHtcbiAgICAgIHJldHVybiB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgbmFtZSwge3NpZGU6IHRoaXN9KTtcbiAgICB9XG4gICAgbGV0IGlzQ2FuY2VsZWQgPSBmYWxzZTtcblxuICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCBuYW1lLCB7XG4gICAgICBzaWRlOiB0aGlzLFxuICAgICAgY2FuY2VsOiAoKSA9PiBpc0NhbmNlbGVkID0gdHJ1ZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGlzQ2FuY2VsZWQ7XG4gIH1cblxuICBfaXNPdGhlclNpZGVPcGVuKCkge1xuICAgIHJldHVybiAhIXV0aWwuZmluZENoaWxkKHRoaXMucGFyZW50RWxlbWVudCxcbiAgICAgIGVsID0+IGVsIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvciAmJiBlbCAhPT0gdGhpcyAmJiBlbC5fbW9kZSA9PT0gQ09MTEFQU0VfTU9ERSAmJiBlbC5pc09wZW5cbiAgICApO1xuICB9XG5cbiAgX3VwZGF0ZUNvbGxhcHNlKHZhbHVlID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2NvbGxhcHNlJykpIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09ICdzcGxpdCcpIHtcbiAgICAgIHRoaXMuX2NvbGxhcHNlRGV0ZWN0aW9uLmRpc2FibGUoKTtcbiAgICAgIHJldHVybiB0aGlzLl91cGRhdGVNb2RlKFNQTElUX01PREUpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSAnY29sbGFwc2UnKSB7XG4gICAgICB0aGlzLl9jb2xsYXBzZURldGVjdGlvbi5kaXNhYmxlKCk7XG4gICAgICByZXR1cm4gdGhpcy5fdXBkYXRlTW9kZShDT0xMQVBTRV9NT0RFKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jb2xsYXBzZURldGVjdGlvbi5jaGFuZ2VUYXJnZXQodmFsdWUpO1xuICB9XG5cbiAgX3VwZGF0ZU1vZGUobW9kZSkge1xuICAgIGlmIChtb2RlICE9PSB0aGlzLl9tb2RlKSB7XG4gICAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKCdtb2RlJywgbW9kZSk7IC8vIHJlYWRvbmx5IGF0dHJpYnV0ZSBmb3IgdGhlIHVzZXJzXG5cbiAgICAgIGlmIChtb2RlID09PSBTUExJVF9NT0RFKSB7XG4gICAgICAgIHRoaXMuX2FuaW1hdG9yICYmIHRoaXMuX2FuaW1hdG9yLmRlYWN0aXZhdGUoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBDTE9TRURfU1RBVEU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9hbmltYXRvciAmJiB0aGlzLl9hbmltYXRvci5hY3RpdmF0ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPT09IE9QRU5fU1RBVEUgJiYgdGhpcy5fYW5pbWF0b3Iub3BlbigpO1xuICAgICAgfVxuXG4gICAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ21vZGVjaGFuZ2UnLCB7IHNpZGU6IHRoaXMsIG1vZGUgfSk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZUFuaW1hdGlvbihhbmltYXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgnYW5pbWF0aW9uJykpIHtcbiAgICBpZiAodGhpcy5wYXJlbnROb2RlKSB7XG4gICAgICB0aGlzLl9hbmltYXRvciAmJiB0aGlzLl9hbmltYXRvci5kZWFjdGl2YXRlKCk7XG4gICAgICB0aGlzLl9hbmltYXRvciA9IHRoaXMuX2FuaW1hdG9yRmFjdG9yeS5uZXdBbmltYXRvcih7YW5pbWF0aW9ufSk7XG4gICAgICB0aGlzLl9hbmltYXRvci5hY3RpdmF0ZSh0aGlzKTtcbiAgICAgIHRoaXMuX2FuaW1hdGlvbk9wdCA9IHtcbiAgICAgICAgdGltaW5nOiB0aGlzLl9hbmltYXRvci5kdXJhdGlvbixcbiAgICAgICAgZHVyYXRpb246IHRoaXMuX2FuaW1hdG9yLmR1cmF0aW9uXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVBbmltYXRpb25PcHRpb25zKHZhbHVlID0gdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbi1vcHRpb25zJykpIHtcbiAgICB0aGlzLl9hbmltYXRvci51cGRhdGVPcHRpb25zKEFuaW1hdG9yRmFjdG9yeS5wYXJzZUFuaW1hdGlvbk9wdGlvbnNTdHJpbmcodmFsdWUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgcGFnZVxuICAgKiBAdHlwZSB7Kn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVBhZ2UgbG9jYXRpb24gdG8gbG9hZCBpbiB0aGUgc3BsaXR0ZXIgc2lkZS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7opoHntKDlhoXjgavooajnpLrjgZnjgovjg5rjg7zjgrjjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHBhZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2U7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsqfSBwYWdlXG4gICAqL1xuICBzZXQgcGFnZShwYWdlKSB7XG4gICAgdGhpcy5fcGFnZSA9IHBhZ2U7XG4gIH1cblxuICBnZXQgX2NvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF07XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHBhZ2VMb2FkZXJcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgcGFnZUxvYWRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFnZUxvYWRlcjtcbiAgfVxuXG4gIHNldCBwYWdlTG9hZGVyKGxvYWRlcikge1xuICAgIGlmICghKGxvYWRlciBpbnN0YW5jZW9mIFBhZ2VMb2FkZXIpKSB7XG4gICAgICB1dGlsLnRocm93UGFnZUxvYWRlcigpO1xuICAgIH1cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gbG9hZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBtb2RlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQ3VycmVudCBtb2RlLiBQb3NzaWJsZSB2YWx1ZXMgYXJlIFwic3BsaXRcIiwgXCJjb2xsYXBzZVwiLCBcImNsb3NlZFwiLCBcIm9wZW5cIiBvciBcImNoYW5naW5nXCIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBtb2RlKCkge1xuICAgIHJldHVybiB0aGlzLl9tb2RlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBvblN3aXBlXG4gICAqIEB0eXBlIHtGdW5jdGlvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUhvb2sgY2FsbGVkIHdoZW5ldmVyIHRoZSB1c2VyIHNsaWRlcyB0aGUgc3BsaXR0ZXIuIEl0IGdldHMgYSBkZWNpbWFsIHJhdGlvICgwLTEpIGFuZCBhbiBhbmltYXRpb25PcHRpb25zIG9iamVjdCBhcyBhcmd1bWVudHMuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBvblN3aXBlKCkge1xuICAgIHJldHVybiB0aGlzLl9vblN3aXBlO1xuICB9XG5cbiAgc2V0IG9uU3dpcGUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgdXRpbC50aHJvdygnXCJvblN3aXBlXCIgbXVzdCBiZSBhIGZ1bmN0aW9uJylcbiAgICB9XG4gICAgdGhpcy5fb25Td2lwZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBpc09wZW5cbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEByZWFkb25seVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhpcyB2YWx1ZSBpcyBgdHJ1ZWAgd2hlbiB0aGUgbWVudSBpcyBvcGVuLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuICBnZXQgaXNPcGVuKCkge1xuICAgIHJldHVybiB0aGlzLl9tb2RlID09PSBDT0xMQVBTRV9NT0RFICYmIHRoaXMuX3N0YXRlICE9PSBDTE9TRURfU1RBVEU7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBvcGVuXG4gICAqIEBzaWduYXR1cmUgb3Blbihbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBhZnRlciB0aGUgbWVudSBoYXMgYmVlbiBvcGVuZWQuWy9lbl1cbiAgICogICBbamFd44Oh44OL44Ol44O844GM6ZaL44GE44Gf5b6M44Gr5ZG844Gz5Ye644GV44KM44KL6Zai5pWw44Kq44OW44K444Kn44Kv44OI44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXU9wZW4gbWVudSBpbiBjb2xsYXBzZSBtb2RlLlsvZW5dXG4gICAqICAgW2phXWNvbGxhcHNl44Oi44O844OJ44Gr44Gq44Gj44Gm44GE44KLb25zLXNwbGl0dGVyLXNpZGXopoHntKDjgpLplovjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgc3BsaXR0ZXIgc2lkZSBlbGVtZW50IG9yIGZhbHNlIGlmIG5vdCBpbiBjb2xsYXBzZSBtb2RlWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIG9wZW4ob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnRvZ2dsZShvcHRpb25zLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIGNsb3NlXG4gICAqIEBzaWduYXR1cmUgY2xvc2UoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqICAgW2VuXVRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgYWZ0ZXIgdGhlIG1lbnUgaGFzIGJlZW4gY2xvc2VkLlsvZW5dXG4gICAqICAgW2phXeODoeODi+ODpeODvOOBjOmWieOBmOOBn+W+jOOBq+WRvOOBs+WHuuOBleOCjOOCi+mWouaVsOOCquODluOCuOOCp+OCr+ODiOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1DbG9zZSBtZW51IGluIGNvbGxhcHNlIG1vZGUuWy9lbl1cbiAgICogICBbamFdY29sbGFwc2Xjg6Ljg7zjg4njgavjgarjgaPjgabjgYTjgotvbnMtc3BsaXR0ZXItc2lkZeimgee0oOOCkumWieOBmOOBvuOBmeOAglsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBzcGxpdHRlciBzaWRlIGVsZW1lbnQgb3IgZmFsc2UgaWYgbm90IGluIGNvbGxhcHNlIG1vZGVbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgY2xvc2Uob3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLnRvZ2dsZShvcHRpb25zLCBmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCB0b2dnbGVcbiAgICogQHNpZ25hdHVyZSB0b2dnbGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1PcGVucyBpZiBpdCdzIGNsb3NlZC4gQ2xvc2VzIGlmIGl0J3Mgb3Blbi5bL2VuXVxuICAgKiAgIFtqYV3plovjgZHjgabjgYTjgovloLTlkIjjga/opoHntKDjgpLplonjgZjjgb7jgZnjgZ3jgZfjgabplovjgZHjgabjgYTjgovloLTlkIjjga/opoHntKDjgpLplovjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1SZXNvbHZlcyB0byB0aGUgc3BsaXR0ZXIgc2lkZSBlbGVtZW50IG9yIGZhbHNlIGlmIG5vdCBpbiBjb2xsYXBzZSBtb2RlWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHRvZ2dsZShvcHRpb25zID0ge30sIGZvcmNlKSB7XG4gICAgY29uc3Qgc2hvdWxkT3BlbiA9IHR5cGVvZiBmb3JjZSA9PT0gJ2Jvb2xlYW4nID8gZm9yY2UgOiAhdGhpcy5pc09wZW47XG4gICAgY29uc3QgYWN0aW9uID0gc2hvdWxkT3BlbiA/ICdvcGVuJyA6ICdjbG9zZSc7XG4gICAgY29uc3QgRklOQUxfU1RBVEUgPSBzaG91bGRPcGVuID8gT1BFTl9TVEFURSA6IENMT1NFRF9TVEFURTtcblxuICAgIGlmICh0aGlzLl9tb2RlID09PSBTUExJVF9NT0RFKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3N0YXRlID09PSBGSU5BTF9TVEFURSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xvY2suaXNMb2NrZWQoKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdBbm90aGVyIHNwbGl0dGVyLXNpZGUgYWN0aW9uIGlzIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICB9XG4gICAgaWYgKHNob3VsZE9wZW4gJiYgdGhpcy5faXNPdGhlclNpZGVPcGVuKCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQW5vdGhlciBtZW51IGlzIGFscmVhZHkgb3Blbi4nKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2VtaXRFdmVudChgcHJlJHthY3Rpb259YCkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgQ2FuY2VsZWQgaW4gcHJlJHthY3Rpb259IGV2ZW50LmApO1xuICAgIH1cblxuICAgIGNvbnN0IHVubG9jayA9IHRoaXMuX2xvY2subG9jaygpO1xuICAgIHRoaXMuX3N0YXRlID0gQ0hBTkdJTkdfU1RBVEU7XG5cbiAgICBpZiAob3B0aW9ucy5hbmltYXRpb24pIHtcbiAgICAgIHRoaXMuX3VwZGF0ZUFuaW1hdGlvbihvcHRpb25zLmFuaW1hdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgdGhpcy5fYW5pbWF0b3JbYWN0aW9uXSgoKSA9PiB7XG4gICAgICAgIHV0aWwuaW9zUGFnZVNjcm9sbEZpeChzaG91bGRPcGVuKTtcbiAgICAgICAgdGhpcy5fc3RhdGUgPSBGSU5BTF9TVEFURTtcbiAgICAgICAgdW5sb2NrKCk7XG4gICAgICAgIHRoaXMuX2VtaXRFdmVudChgcG9zdCR7YWN0aW9ufWApO1xuICAgICAgICBvcHRpb25zLmNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24gJiYgb3B0aW9ucy5jYWxsYmFjayh0aGlzKTtcbiAgICAgICAgcmVzb2x2ZSh0aGlzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgbG9hZFxuICAgKiBAc2lnbmF0dXJlIGxvYWQocGFnZSwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFnZVxuICAgKiAgIFtlbl1QYWdlIFVSTC4gQ2FuIGJlIGVpdGhlciBhbiBIVE1MIGRvY3VtZW50IG9yIGEgYDx0ZW1wbGF0ZT5gLlsvZW5dXG4gICAqICAgW2phXXBhZ2Xjga5VUkzjgYvjgIFgPHRlbXBsYXRlPmDjgaflrqPoqIDjgZfjgZ/jg4bjg7Pjg5fjg6zjg7zjg4jjga5pZOWxnuaAp+OBruWApOOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuY2FsbGJhY2tdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TaG93IHRoZSBwYWdlIHNwZWNpZmllZCBpbiBwYWdlVXJsIGluIHRoZSByaWdodCBzZWN0aW9uWy9lbl1cbiAgICogICBbamFd5oyH5a6a44GX44GfVVJM44KS44Oh44Kk44Oz44Oa44O844K444KS6Kqt44G/6L6844G/44G+44GZ44CCWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIG5ldyBwYWdlIGVsZW1lbnRbL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgbG9hZChwYWdlLCBvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLl9wYWdlID0gcGFnZTtcbiAgICBjb25zdCBjYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2sgfHwgKCgpID0+IHt9KTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGxldCBvbGRDb250ZW50ID0gdGhpcy5fY29udGVudCB8fCBudWxsO1xuXG4gICAgICB0aGlzLl9wYWdlTG9hZGVyLmxvYWQoe3BhZ2UsIHBhcmVudDogdGhpc30sIHBhZ2VFbGVtZW50ID0+IHtcbiAgICAgICAgaWYgKG9sZENvbnRlbnQpIHtcbiAgICAgICAgICB0aGlzLl9wYWdlTG9hZGVyLnVubG9hZChvbGRDb250ZW50KTtcbiAgICAgICAgICBvbGRDb250ZW50ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldEltbWVkaWF0ZSgoKSA9PiB0aGlzLl9zaG93KCkpO1xuXG4gICAgICAgIGNhbGxiYWNrKHBhZ2VFbGVtZW50KTtcbiAgICAgICAgcmVzb2x2ZShwYWdlRWxlbWVudCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIGlmICh0aGlzLl9jb250ZW50KSB7XG4gICAgICB0aGlzLl9jb250ZW50Ll9zaG93KCk7XG4gICAgfVxuICB9XG5cbiAgX2hpZGUoKSB7XG4gICAgaWYgKHRoaXMuX2NvbnRlbnQpIHtcbiAgICAgIHRoaXMuX2NvbnRlbnQuX2hpZGUoKTtcbiAgICB9XG4gIH1cblxuICBfZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fY29udGVudCkge1xuICAgICAgdGhpcy5fcGFnZUxvYWRlci51bmxvYWQodGhpcy5fY29udGVudCk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGV2ZW50cygpIHtcbiAgICByZXR1cm4gWydwcmVvcGVuJywgJ3Bvc3RvcGVuJywgJ3ByZWNsb3NlJywgJ3Bvc3RjbG9zZScsICdtb2RlY2hhbmdlJ107XG4gIH1cblxuICBzdGF0aWMgZ2V0IHJld3JpdGFibGVzKCkge1xuICAgIHJldHVybiByZXdyaXRhYmxlcztcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5TcGxpdHRlclNpZGUgPSBTcGxpdHRlclNpZGVFbGVtZW50O1xuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdvbnMtc3BsaXR0ZXItc2lkZScsIFNwbGl0dGVyU2lkZUVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUNoZWNrYm94RWxlbWVudCBmcm9tICcuL2Jhc2UvYmFzZS1jaGVja2JveCc7XG5pbXBvcnQgY29udGVudFJlYWR5IGZyb20gJy4uL29ucy9jb250ZW50LXJlYWR5JztcbmltcG9ydCBHZXN0dXJlRGV0ZWN0b3IgZnJvbSAnLi4vb25zL2dlc3R1cmUtZGV0ZWN0b3InO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcnOiAnc3dpdGNoLS0qJyxcbiAgJy5zd2l0Y2hfX2lucHV0JzogJ3N3aXRjaC0tKl9faW5wdXQnLFxuICAnLnN3aXRjaF9faGFuZGxlJzogJ3N3aXRjaC0tKl9faGFuZGxlJyxcbiAgJy5zd2l0Y2hfX3RvZ2dsZSc6ICdzd2l0Y2gtLSpfX3RvZ2dsZSdcbn07XG5cbmNvbnN0IGxvY2F0aW9ucyA9IHtcbiAgaW9zOiBbMSwgMjFdLFxuICBtYXRlcmlhbDogWzAsIDE2XVxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtc3dpdGNoXG4gKiBAY2F0ZWdvcnkgZm9ybVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1cbiAqICAgICBTd2l0Y2ggY29tcG9uZW50LiBUaGUgc3dpdGNoIGNhbiBiZSB0b2dnbGVkIGJvdGggYnkgZHJhZ2dpbmcgYW5kIHRhcHBpbmcuXG4gKlxuICogICAgIFdpbGwgYXV0b21hdGljYWxseSBkaXNwbGF5cyBhIE1hdGVyaWFsIERlc2lnbiBzd2l0Y2ggb24gQW5kcm9pZCBkZXZpY2VzLlxuICogICBbL2VuXVxuICogICBbamFd44K544Kk44OD44OB44KS6KGo56S644GZ44KL44Kz44Oz44Od44O844ON44Oz44OI44Gn44GZ44CCWy9qYV1cbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dTWF0ZXJpYWwgRGVzaWduIHN3aXRjaFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGNvZGVwZW4gTHBYWlFRXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2Uvc3dpdGNoXG4gKiBAZ3VpZGUgdGhlbWluZy5odG1sI21vZGlmaWVycyBbZW5dTW9yZSBkZXRhaWxzIGFib3V0IHRoZSBgbW9kaWZpZXJgIGF0dHJpYnV0ZVsvZW5dW2phXW1vZGlmaWVy5bGe5oCn44Gu5L2/44GE5pa5Wy9qYV1cbiAqIEBleGFtcGxlXG4gKiA8b25zLXN3aXRjaCBjaGVja2VkPjwvb25zLXN3aXRjaD5cbiAqIDxvbnMtc3dpdGNoIGRpc2FibGVkPjwvb25zLXN3aXRjaD5cbiAqIDxvbnMtc3dpdGNoIG1vZGlmaWVyPVwibWF0ZXJpYWxcIj48L29ucy1zd2l0Y2g+XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3dpdGNoRWxlbWVudCBleHRlbmRzIEJhc2VDaGVja2JveEVsZW1lbnQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2soJ21vZGlmaWVyJywgbnVsbCwgdGhpcy5nZXRBdHRyaWJ1dGUoJ21vZGlmaWVyJykpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fb25DaGFuZ2UgPSB0aGlzLl9vbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX29uUmVsZWFzZSA9IHRoaXMuX29uUmVsZWFzZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2xhc3RUaW1lU3RhbXAgPSAwO1xuICB9XG5cbiAgZ2V0IF9zY2hlbWUoKSB7XG4gICAgcmV0dXJuIHNjaGVtZTtcbiAgfVxuXG4gIGdldCBfZGVmYXVsdENsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ3N3aXRjaCc7XG4gIH1cblxuICBnZXQgX3RlbXBsYXRlKCkge1xuICAgIHJldHVybiBgXG4gICAgICA8aW5wdXQgdHlwZT1cIiR7dGhpcy50eXBlfVwiIGNsYXNzPVwiJHt0aGlzLl9kZWZhdWx0Q2xhc3NOYW1lfV9faW5wdXRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X190b2dnbGVcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIiR7dGhpcy5fZGVmYXVsdENsYXNzTmFtZX1fX2hhbmRsZVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCIke3RoaXMuX2RlZmF1bHRDbGFzc05hbWV9X190b3VjaFwiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIGA7XG4gIH1cblxuICBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gJ2NoZWNrYm94JztcbiAgfVxuXG4gIC8qIE93biBwcm9wcyAqL1xuXG4gIF9nZXRQb3NpdGlvbihlKSB7XG4gICAgY29uc3QgbCA9IHRoaXMuX2xvY2F0aW9ucztcbiAgICByZXR1cm4gTWF0aC5taW4obFsxXSwgTWF0aC5tYXgobFswXSwgdGhpcy5fc3RhcnRYICsgZS5nZXN0dXJlLmRlbHRhWCkpO1xuICB9XG5cbiAgX2VtaXRDaGFuZ2VFdmVudCgpIHtcbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ2NoYW5nZScsIHtcbiAgICAgIHZhbHVlOiB0aGlzLmNoZWNrZWQsXG4gICAgICBzd2l0Y2g6IHRoaXMsXG4gICAgICBpc0ludGVyYWN0aXZlOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICBfb25DaGFuZ2UoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQgJiYgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLl9lbWl0Q2hhbmdlRXZlbnQoKTtcbiAgfVxuXG4gIF9vbkNsaWNrKGV2KSB7XG4gICAgaWYgKGV2LnRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoYCR7dGhpcy5kZWZhdWx0RWxlbWVudENsYXNzfV9fdG91Y2hgKVxuICAgICAgfHwgKGV2LnRpbWVTdGFtcCAtIHRoaXMuX2xhc3RUaW1lU3RhbXAgPCA1MCkgLy8gUHJldmVudCBzZWNvbmQgY2xpY2sgdHJpZ2dlcmVkIGJ5IDxsYWJlbD5cbiAgICApIHtcbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHRoaXMuX2xhc3RUaW1lU3RhbXAgPSBldi50aW1lU3RhbXA7XG4gIH1cblxuICBfb25Ib2xkKGUpIHtcbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIE1vZGlmaWVyVXRpbC5hZGRNb2RpZmllcih0aGlzLCAnYWN0aXZlJyk7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWxlYXNlJywgdGhpcy5fb25SZWxlYXNlKTtcbiAgICB9XG4gIH1cblxuICBfb25EcmFnU3RhcnQoZSkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkIHx8IFsnbGVmdCcsICdyaWdodCddLmluZGV4T2YoZS5nZXN0dXJlLmRpcmVjdGlvbikgPT09IC0xKSB7XG4gICAgICBNb2RpZmllclV0aWwucmVtb3ZlTW9kaWZpZXIodGhpcywgJ2FjdGl2ZScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGUuY29uc3VtZWQgPSB0cnVlO1xuXG4gICAgTW9kaWZpZXJVdGlsLmFkZE1vZGlmaWVyKHRoaXMsICdhY3RpdmUnKTtcbiAgICB0aGlzLl9zdGFydFggPSB0aGlzLl9sb2NhdGlvbnNbdGhpcy5jaGVja2VkID8gMSA6IDBdOy8vIC0gZS5nZXN0dXJlLmRlbHRhWDtcblxuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZHJhZycsIHRoaXMuX29uRHJhZyk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigncmVsZWFzZScsIHRoaXMuX29uUmVsZWFzZSk7XG4gIH1cblxuICBfb25EcmFnKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuX2hhbmRsZS5zdHlsZS5sZWZ0ID0gdGhpcy5fZ2V0UG9zaXRpb24oZSkgKyAncHgnO1xuICB9XG5cbiAgX29uUmVsZWFzZShlKSB7XG4gICAgY29uc3QgbCA9IHRoaXMuX2xvY2F0aW9ucztcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuX2dldFBvc2l0aW9uKGUpO1xuICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSB0aGlzLmNoZWNrZWQ7XG5cbiAgICB0aGlzLmNoZWNrZWQgPSBwb3NpdGlvbiA+PSAobFswXSArIGxbMV0pIC8gMjtcblxuICAgIGlmICh0aGlzLmNoZWNrZWQgIT09IHByZXZpb3VzVmFsdWUpIHtcbiAgICAgIHRoaXMuX2VtaXRDaGFuZ2VFdmVudCgpO1xuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZycsIHRoaXMuX29uRHJhZyk7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVsZWFzZScsIHRoaXMuX29uUmVsZWFzZSk7XG5cbiAgICB0aGlzLl9oYW5kbGUuc3R5bGUubGVmdCA9ICcnO1xuICAgIE1vZGlmaWVyVXRpbC5yZW1vdmVNb2RpZmllcih0aGlzLCAnYWN0aXZlJyk7XG4gIH1cblxuICBjbGljayhldiA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLmNoZWNrZWQgPSAhdGhpcy5jaGVja2VkO1xuICAgICAgdGhpcy5fZW1pdENoYW5nZUV2ZW50KCk7XG4gICAgICB0aGlzLl9sYXN0VGltZVN0YW1wID0gZXYudGltZVN0YW1wIHx8IDA7XG4gICAgfVxuICB9XG5cbiAgZ2V0IF9oYW5kbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcihgLiR7dGhpcy5fZGVmYXVsdENsYXNzTmFtZX1fX2hhbmRsZWApO1xuICB9XG5cbiAgZ2V0IGNoZWNrYm94KCkge1xuICAgIHJldHVybiB0aGlzLl9pbnB1dDtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9pbnB1dC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCB0aGlzLl9vbkNoYW5nZSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdzdGFydCcsIHRoaXMuX29uRHJhZ1N0YXJ0KTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2hvbGQnLCB0aGlzLl9vbkhvbGQpO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndGFwJywgdGhpcy5jbGljayk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uQ2xpY2spO1xuICAgIHRoaXMuX2dlc3R1cmVEZXRlY3RvciA9IG5ldyBHZXN0dXJlRGV0ZWN0b3IodGhpcywgeyBkcmFnTWluRGlzdGFuY2U6IDEsIGhvbGRUaW1lb3V0OiAyNTEsIHBhc3NpdmU6IHRydWUgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5faW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgdGhpcy5fb25DaGFuZ2UpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCB0aGlzLl9vbkRyYWdTdGFydCk7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdob2xkJywgdGhpcy5fb25Ib2xkKTtcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RhcCcsIHRoaXMuY2xpY2spO1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrKTtcbiAgICBpZiAodGhpcy5fZ2VzdHVyZURldGVjdG9yKSB7XG4gICAgICB0aGlzLl9nZXN0dXJlRGV0ZWN0b3IuZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXQgb2JzZXJ2ZWRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbLi4uc3VwZXIub2JzZXJ2ZWRBdHRyaWJ1dGVzLCAnbW9kaWZpZXInXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIGNvbnN0IG1kID0gKGN1cnJlbnQgfHwgJycpLmluZGV4T2YoJ21hdGVyaWFsJykgIT09IC0xO1xuICAgICAgdGhpcy5fbG9jYXRpb25zID0gbG9jYXRpb25zW21kID8gJ21hdGVyaWFsJyA6ICdpb3MnXTtcbiAgICB9XG5cbiAgICBzdXBlci5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQGV2ZW50IGNoYW5nZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRmlyZWQgd2hlbiB0aGUgc3dpdGNoIGlzIHRvZ2dsZWQuWy9lbl1cbiAgICogICBbamFdT04vT0ZG44GM5aSJ44KP44Gj44Gf5pmC44Gr55m654Gr44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gICAqICAgW2VuXUV2ZW50IG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqTjg5njg7Pjg4jjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQuc3dpdGNoXG4gICAqICAgW2VuXVN3aXRjaCBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kk44OZ44Oz44OI44GM55m654Gr44GX44GfU3dpdGNo44Kq44OW44K444Kn44Kv44OI44KS6L+U44GX44G+44GZ44CCWy9qYV1cbiAgICogQHBhcmFtIHtCb29sZWFufSBldmVudC52YWx1ZVxuICAgKiAgIFtlbl1DdXJyZW50IHZhbHVlLlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOBruWApOOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZXZlbnQuaXNJbnRlcmFjdGl2ZVxuICAgKiAgIFtlbl1UcnVlIGlmIHRoZSBjaGFuZ2Ugd2FzIHRyaWdnZXJlZCBieSB0aGUgdXNlciBjbGlja2luZyBvbiB0aGUgc3dpdGNoLlsvZW5dXG4gICAqICAgW2phXeOCv+ODg+ODl+OChOOCr+ODquODg+OCr+OBquOBqeOBruODpuODvOOCtuOBruaTjeS9nOOBq+OCiOOBo+OBpuWkieOCj+OBo+OBn+WgtOWQiOOBq+OBr3RydWXjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgc3dpdGNoLlsvZW5dXG4gICAqICBbamFd44K544Kk44OD44OB44Gu6KGo54++44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgZGlzYWJsZWRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIHN3aXRjaCBpcyBiZSBkaXNhYmxlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjgqTjg4Pjg4HjgpLnhKHlirnjga7nirbmhYvjgavjgZnjgovloLTlkIjjgavmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBjaGVja2VkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRoZSBzd2l0Y2ggaXMgY2hlY2tlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjgqTjg4Pjg4HjgYxPTuOBrueKtuaFi+OBq+OBmeOCi+OBqOOBjeOBq+aMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGlucHV0LWlkXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBgaWRgIGF0dHJpYnV0ZSBvZiB0aGUgaW5uZXIgYDxpbnB1dD5gIGVsZW1lbnQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gdXNpbmcgYDxsYWJlbCBmb3I9XCIuLi5cIj5gIGVsZW1lbnRzLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgY2hlY2tlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoaXMgdmFsdWUgaXMgYHRydWVgIGlmIHRoZSBzd2l0Y2ggaXMgY2hlY2tlZC5bL2VuXVxuICAgKiAgIFtqYV3jgrnjgqTjg4Pjg4HjgYxPTuOBruWgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkgdmFsdWVcbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBpbnB1dC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IGRpc2FibGVkXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyBkaXNhYmxlZCBvciBub3QuWy9lbl1cbiAgICogICBbamFd54Sh5Yq55YyW44GV44KM44Gm44GE44KL5aC05ZCI44GrYHRydWVg44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBjaGVja2JveFxuICAgKiBAcmVhZG9ubHlcbiAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHVuZGVybHlpbmcgY2hlY2tib3ggZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV3jgrPjg7Pjg53jg7zjg43jg7Pjg4jlhoXpg6jjga5jaGVja2JveOimgee0oOOBq+OBquOCiuOBvuOBmeOAglsvamFdXG4gICAqL1xuXG59XG5cbm9uc0VsZW1lbnRzLlN3aXRjaCA9IFN3aXRjaEVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy1zd2l0Y2gnLCBTd2l0Y2hFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi8uLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGludGVybmFsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uLy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IFN3aXBlciBmcm9tICcuLi8uLi9vbnMvaW50ZXJuYWwvc3dpcGVyJztcbmltcG9ydCBNb2RpZmllclV0aWwgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL21vZGlmaWVyLXV0aWwnO1xuaW1wb3J0IEJhc2VFbGVtZW50IGZyb20gJy4uL2Jhc2UvYmFzZS1lbGVtZW50JztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcudGFiYmFyX19jb250ZW50JzogJ3RhYmJhci0tKl9fY29udGVudCcsXG4gICcudGFiYmFyX19ib3JkZXInOiAndGFiYmFyLS0qX19ib3JkZXInLFxuICAnLnRhYmJhcic6ICd0YWJiYXItLSonXG59O1xuXG5jb25zdCByZXdyaXRhYmxlcyA9IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gdGFiYmFyRWxlbWVudFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgcmVhZHkodGFiYmFyRWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59O1xuXG5jb25zdCBudWxsUGFnZSA9IGludGVybmFsLm51bGxFbGVtZW50O1xuY29uc3QgbGVycCA9ICh4MCwgeDEsIHQpID0+ICgxIC0gdCkgKiB4MCArIHQgKiB4MTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtdGFiYmFyXG4gKiBAY2F0ZWdvcnkgdGFiYmFyXG4gKiBAZGVzY3JpcHRpb25cbiAqICAgW2VuXUEgY29tcG9uZW50IHRvIGRpc3BsYXkgYSB0YWIgYmFyIG9uIHRoZSBib3R0b20gb2YgYSBwYWdlLiBVc2VkIHdpdGggYDxvbnMtdGFiPmAgdG8gbWFuYWdlIHBhZ2VzIHVzaW5nIHRhYnMuWy9lbl1cbiAqICAgW2phXeOCv+ODluODkOODvOOCkuODmuODvOOCuOS4i+mDqOOBq+ihqOekuuOBmeOCi+OBn+OCgeOBruOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAgm9ucy10YWLjgajntYTjgb/lkIjjgo/jgZvjgabkvb/jgYbjgZPjgajjgafjgIHjg5rjg7zjgrjjgpLnrqHnkIbjgafjgY3jgb7jgZnjgIJbL2phXVxuICogQGNvZGVwZW4gcEd1RExcbiAqIEB0dXRvcmlhbCB2YW5pbGxhL1JlZmVyZW5jZS90YWJiYXJcbiAqIEBtb2RpZmllciBtYXRlcmlhbFxuICogICBbZW5dQSB0YWJiYXIgaW4gTWF0ZXJpYWwgRGVzaWduLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIGF1dG9ncm93XG4gKiAgIFtlbl1UYWJzIGF1dG9tYXRpY2FsbHkgZ3JvdyBkZXBlbmRpbmcgb24gdGhlaXIgY29udGVudCBpbnN0ZWFkIG9mIGhhdmluZyBhIGZpeGVkIHdpZHRoLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQG1vZGlmaWVyIHRvcC1ib3JkZXJcbiAqICAgW2VuXVNob3dzIGEgc3RhdGljIGJvcmRlci1ib3R0b20gaW4gdGFicyBmb3IgaU9TIHRvcCB0YWJiYXJzLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQGd1aWRlIGZ1bmRhbWVudGFscy5odG1sI21hbmFnaW5nLXBhZ2VzXG4gKiAgW2VuXU1hbmFnaW5nIG11bHRpcGxlIHBhZ2VzLlsvZW5dXG4gKiAgW2phXeikh+aVsOOBruODmuODvOOCuOOCkueuoeeQhuOBmeOCi1svamFdXG4gKiBAc2VlYWxzbyBvbnMtdGFiXG4gKiAgIFtlbl1UaGUgYDxvbnMtdGFiPmAgY29tcG9uZW50LlsvZW5dXG4gKiAgIFtqYV1vbnMtdGFi44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1wYWdlXG4gKiAgIFtlbl1UaGUgYDxvbnMtcGFnZT5gIGNvbXBvbmVudC5bL2VuXVxuICogICBbamFdb25zLXBhZ2XjgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtdGFiYmFyPlxuICogICA8b25zLXRhYlxuICogICAgIHBhZ2U9XCJob21lLmh0bWxcIlxuICogICAgIGxhYmVsPVwiSG9tZVwiXG4gKiAgICAgYWN0aXZlPlxuICogICA8L29ucy10YWI+XG4gKiAgIDxvbnMtdGFiXG4gKiAgICAgcGFnZT1cInNldHRpbmdzLmh0bWxcIlxuICogICAgIGxhYmVsPVwiU2V0dGluZ3NcIlxuICogICAgIGFjdGl2ZT5cbiAqICAgPC9vbnMtdGFiPlxuICogPC9vbnMtdGFiYmFyPlxuICpcbiAqIDx0ZW1wbGF0ZSBpZD1cImhvbWUuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG4gKlxuICogPHRlbXBsYXRlIGlkPVwic2V0dGluZ3MuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRhYmJhckVsZW1lbnQgZXh0ZW5kcyBCYXNlRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBldmVudCBwcmVjaGFuZ2VcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVzIGp1c3QgYmVmb3JlIHRoZSB0YWIgaXMgY2hhbmdlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgq/jg4bjgqPjg5bjgarjgr/jg5bjgYzlpInjgo/jgovliY3jgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5pbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi29ucy10YWLjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQudGFiSXRlbVxuICAgKiAgIFtlbl1UYWIgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFddGFiSXRlbeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGV2ZW50LmNhbmNlbFxuICAgKiAgIFtlbl1DYWxsIHRoaXMgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBjaGFuZ2UgZXZlbnQuWy9lbl1cbiAgICogICBbamFd44GT44Gu6Zai5pWw44KS5ZG844Gz5Ye644GZ44Go44CB44Ki44Kv44OG44Kj44OW44Gq44K/44OW44Gu5aSJ5pu044GM44Kt44Oj44Oz44K744Or44GV44KM44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBldmVudCBwb3N0Y2hhbmdlXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1GaXJlcyBqdXN0IGFmdGVyIHRoZSB0YWIgaXMgY2hhbmdlZC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgq/jg4bjgqPjg5bjgarjgr/jg5bjgYzlpInjgo/jgaPjgZ/lvozjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5pbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi29ucy10YWLjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQudGFiSXRlbVxuICAgKiAgIFtlbl1UYWIgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFddGFiSXRlbeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAZXZlbnQgcmVhY3RpdmVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUZpcmVzIGlmIHRoZSBhbHJlYWR5IG9wZW4gdGFiIGlzIHRhcHBlZCBhZ2Fpbi5bL2VuXVxuICAgKiAgIFtqYV3jgZnjgafjgavjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovjgr/jg5bjgYzjgoLjgYbkuIDluqbjgr/jg4Pjg5fjgoTjgq/jg6rjg4Pjgq/jgZXjgozjgZ/loLTlkIjjgavnmbrngavjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAgICogICBbZW5dRXZlbnQgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCpOODmeODs+ODiOOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBldmVudC5pbmRleFxuICAgKiAgIFtlbl1DdXJyZW50IGluZGV4LlsvZW5dXG4gICAqICAgW2phXeePvuWcqOOCouOCr+ODhuOCo+ODluOBq+OBquOBo+OBpuOBhOOCi29ucy10YWLjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQudGFiSXRlbVxuICAgKiAgIFtlbl1UYWIgaXRlbSBvYmplY3QuWy9lbl1cbiAgICogICBbamFddGFiSXRlbeOCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGFuaW1hdGlvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCBub25lXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1JZiB0aGlzIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYFwibm9uZVwiYCB0aGUgdHJhbnNpdGlvbnMgd2lsbCBub3QgYmUgYW5pbWF0ZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uLW9wdGlvbnNcbiAgICogQHR5cGUge0V4cHJlc3Npb259XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCB0aW1pbmcgYW5kIGRlbGF5IHdpdGggYW4gb2JqZWN0IGxpdGVyYWwuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCB0aW1pbmcsIGRlbGF544KS44Kq44OW44K444Kn44Kv44OI44Oq44OG44Op44Or44Gn5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDEsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIHBvc2l0aW9uXG4gICAqIEBpbml0b25seVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVmYXVsdCBib3R0b21cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRhYmJhcidzIHBvc2l0aW9uLiBBdmFpbGFibGUgdmFsdWVzIGFyZSBgXCJib3R0b21cImAgYW5kIGBcInRvcFwiYC4gVXNlIGBcImF1dG9cImAgdG8gY2hvb3NlIHBvc2l0aW9uIGRlcGVuZGluZyBvbiBwbGF0Zm9ybSAoYm90dG9tIGZvciBpT1MgZmxhdCBkZXNpZ24sIHRvcCBmb3IgTWF0ZXJpYWwgRGVzaWduKS5bL2VuXVxuICAgKiAgIFtqYV3jgr/jg5bjg5Djg7zjga7kvY3nva7jgpLmjIflrprjgZfjgb7jgZnjgIJcImJvdHRvbVwi44KC44GX44GP44GvXCJ0b3BcIuOCkumBuOaKnuOBp+OBjeOBvuOBmeOAguODh+ODleOCqeODq+ODiOOBr1wiYm90dG9tXCLjgafjgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBzd2lwZWFibGVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXUlmIHRoaXMgYXR0cmlidXRlIGlzIHNldCB0aGUgdGFiIGJhciBjYW4gYmUgc2Nyb2xsZWQgYnkgZHJhZyBvciBzd2lwZS5bL2VuXVxuICAgKiAgIFtqYV3jgZPjga7lsZ7mgKfjgYzjgYLjgovmmYLjgIHjgr/jg5bjg5Djg7zjgpLjgrnjg6/jgqTjg5fjgoTjg4njg6njg4PjgrDjgafnp7vli5XjgafjgY3jgovjgojjgYbjgavjgarjgorjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBpZ25vcmUtZWRnZS13aWR0aFxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKiBAZGVmYXVsdCAyMFxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRGlzdGFuY2UgaW4gcGl4ZWxzIGZyb20gYm90aCBlZGdlcy4gU3dpcGluZyBvbiB0aGVzZSBhcmVhcyB3aWxsIHByaW9yaXRpemUgcGFyZW50IGNvbXBvbmVudHMgc3VjaCBhcyBgb25zLXNwbGl0dGVyYCBvciBgb25zLW5hdmlnYXRvcmAuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaGlkZS10YWJzXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1XaGV0aGVyIHRvIGhpZGUgdGhlIHRhYnMuWy9lbl1cbiAgICogICBbamFd44K/44OW44KS6Z2e6KGo56S644Gr44GZ44KL5aC05ZCI44Gr5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgdGFiLWJvcmRlclxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSWYgdGhpcyBhdHRyaWJ1dGUgaXMgc2V0IHRoZSB0YWJzIHNob3cgYSBkeW5hbWljIGJvdHRvbSBib3JkZXIuIE9ubHkgd29ya3MgZm9yIGlPUyBmbGF0IGRlc2lnbiBzaW5jZSB0aGUgYm9yZGVyIGlzIGFsd2F5cyB2aXNpYmxlIGluIE1hdGVyaWFsIERlc2lnbi5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBtb2RpZmllclxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGFwcGVhcmFuY2Ugb2YgdGhlIHRhYmJhci5bL2VuXVxuICAgKiAgIFtqYV3jgr/jg5bjg5Djg7zjga7ooajnj77jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2xvYWRJbmFjdGl2ZSA9IHV0aWwuZGVmZXIoKTsgLy8gSW1wcm92ZXMgIzIzMjRcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIGlmICghdGhpcy5fc3dpcGVyKSB7XG4gICAgICB0aGlzLl9zd2lwZXIgPSBuZXcgU3dpcGVyKHtcbiAgICAgICAgZ2V0RWxlbWVudDogKCkgPT4gdGhpcy5fY29udGVudEVsZW1lbnQsXG4gICAgICAgIGdldEluaXRpYWxJbmRleDogKCkgPT4gdGhpcy5nZXRBdHRyaWJ1dGUoJ2FjdGl2ZUluZGV4JykgfHwgdGhpcy5nZXRBdHRyaWJ1dGUoJ2FjdGl2ZS1pbmRleCcpLFxuICAgICAgICBnZXRBdXRvU2Nyb2xsUmF0aW86IHRoaXMuX2dldEF1dG9TY3JvbGxSYXRpby5iaW5kKHRoaXMpLFxuICAgICAgICBnZXRCdWJibGVXaWR0aDogKCkgPT4gcGFyc2VJbnQodGhpcy5nZXRBdHRyaWJ1dGUoJ2lnbm9yZS1lZGdlLXdpZHRoJykgfHwgMjUsIDEwKSxcbiAgICAgICAgaXNBdXRvU2Nyb2xsYWJsZTogKCkgPT4gdHJ1ZSxcbiAgICAgICAgcHJlQ2hhbmdlSG9vazogdGhpcy5fb25QcmVDaGFuZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgcG9zdENoYW5nZUhvb2s6IHRoaXMuX29uUG9zdENoYW5nZS5iaW5kKHRoaXMpLFxuICAgICAgICByZWZyZXNoSG9vazogdGhpcy5fb25SZWZyZXNoLmJpbmQodGhpcyksXG4gICAgICAgIHNjcm9sbEhvb2s6IHRoaXMuX29uU2Nyb2xsLmJpbmQodGhpcylcbiAgICAgIH0pO1xuXG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIgPSB1dGlsLmZpbmRDaGlsZCh0aGlzLl90YWJiYXJFbGVtZW50LCAnLnRhYmJhcl9fYm9yZGVyJyk7XG4gICAgICAgIHRoaXMuX3N3aXBlci5pbml0KHsgc3dpcGVhYmxlOiB0aGlzLmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJykgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgdGhpcy5fdXBkYXRlUG9zaXRpb24oKTtcblxuICAgICAgaWYgKCF1dGlsLmZpbmRQYXJlbnQodGhpcywgJ29ucy1wYWdlJywgcCA9PiBwID09PSBkb2N1bWVudC5ib2R5KSkge1xuICAgICAgICB0aGlzLl9zaG93KCk7IC8vIFRoaXMgdGFiYmFyIGlzIHRoZSB0b3AgY29tcG9uZW50XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBpZiAodGhpcy5fc3dpcGVyICYmIHRoaXMuX3N3aXBlci5pbml0aWFsaXplZCkge1xuICAgICAgdGhpcy5fc3dpcGVyLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMuX3N3aXBlciA9IG51bGw7XG4gICAgICB0aGlzLl90YWJiYXJCb3JkZXIgPSBudWxsO1xuICAgICAgdGhpcy5fdGFic1JlY3QgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIF9ub3JtYWxpemVFdmVudChldmVudCkge1xuICAgIHJldHVybiB7IC4uLmV2ZW50LCBpbmRleDogZXZlbnQuYWN0aXZlSW5kZXgsIHRhYkl0ZW06IHRoaXMudGFic1tldmVudC5hY3RpdmVJbmRleF0gfTtcbiAgfVxuXG4gIF9vblBvc3RDaGFuZ2UoZXZlbnQpIHtcbiAgICBldmVudCA9IHRoaXMuX25vcm1hbGl6ZUV2ZW50KGV2ZW50KTtcbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ3Bvc3RjaGFuZ2UnLCBldmVudCk7XG4gICAgY29uc3QgcGFnZSA9IGV2ZW50LnRhYkl0ZW0ucGFnZUVsZW1lbnQ7XG4gICAgcGFnZSAmJiBwYWdlLl9zaG93KCk7XG4gIH1cblxuICBfb25QcmVDaGFuZ2UoZXZlbnQpIHtcbiAgICBldmVudCA9IHRoaXMuX25vcm1hbGl6ZUV2ZW50KGV2ZW50KTtcbiAgICBldmVudC5jYW5jZWwgPSAoKSA9PiBldmVudC5jYW5jZWxlZCA9IHRydWU7XG5cbiAgICB1dGlsLnRyaWdnZXJFbGVtZW50RXZlbnQodGhpcywgJ3ByZWNoYW5nZScsIGV2ZW50KTtcblxuICAgIGlmICghZXZlbnQuY2FuY2VsZWQpIHtcbiAgICAgIGNvbnN0IHsgYWN0aXZlSW5kZXgsIGxhc3RBY3RpdmVJbmRleCB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCB0YWJzID0gdGhpcy50YWJzO1xuXG4gICAgICB0YWJzW2FjdGl2ZUluZGV4XS5zZXRBY3RpdmUodHJ1ZSk7XG4gICAgICBpZiAobGFzdEFjdGl2ZUluZGV4ID49IDApIHtcbiAgICAgICAgY29uc3QgcHJldlRhYiA9IHRhYnNbbGFzdEFjdGl2ZUluZGV4XTtcbiAgICAgICAgcHJldlRhYi5zZXRBY3RpdmUoZmFsc2UpO1xuICAgICAgICBwcmV2VGFiLnBhZ2VFbGVtZW50ICYmIHByZXZUYWIucGFnZUVsZW1lbnQuX2hpZGUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXZlbnQuY2FuY2VsZWRcbiAgfVxuXG4gIF9vblNjcm9sbChpbmRleCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuX3RhYmJhckJvcmRlcikge1xuICAgICAgdGhpcy5fdGFiYmFyQm9yZGVyLnN0eWxlLnRyYW5zaXRpb24gPSBgYWxsICR7b3B0aW9ucy5kdXJhdGlvbiB8fCAwfXMgJHtvcHRpb25zLnRpbWluZyB8fCAnJ31gO1xuXG4gICAgICBpZiAodGhpcy5fYXV0b2dyb3cgJiYgdGhpcy5fdGFic1JlY3QubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBhID0gTWF0aC5mbG9vcihpbmRleCksIGIgPSBNYXRoLmNlaWwoaW5kZXgpLCByID0gaW5kZXggJSAxO1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIuc3R5bGUud2lkdGggPSBsZXJwKHRoaXMuX3RhYnNSZWN0W2FdLndpZHRoLCB0aGlzLl90YWJzUmVjdFtiXS53aWR0aCwgcikgKyAncHgnO1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZTNkKCR7bGVycCh0aGlzLl90YWJzUmVjdFthXS5sZWZ0LCB0aGlzLl90YWJzUmVjdFtiXS5sZWZ0LCByKX1weCwgMCwgMClgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fdGFiYmFyQm9yZGVyLnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUzZCgke2luZGV4ICogMTAwfSUsIDAsIDApYDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9vblN3aXBlICYmIHRoaXMuX29uU3dpcGUoaW5kZXgsIG9wdGlvbnMpO1xuICB9XG5cbiAgX29uUmVmcmVzaCgpIHtcbiAgICB0aGlzLl9hdXRvZ3JvdyA9IHV0aWwuaGFzTW9kaWZpZXIodGhpcywgJ2F1dG9ncm93Jyk7XG4gICAgdGhpcy5fdGFic1JlY3QgPSB0aGlzLnRhYnMubWFwKHRhYiA9PiB0YWIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICAgIGlmICh0aGlzLl90YWJiYXJCb3JkZXIpIHtcbiAgICAgIHRoaXMuX3RhYmJhckJvcmRlci5zdHlsZS5kaXNwbGF5ID0gdGhpcy5oYXNBdHRyaWJ1dGUoJ3RhYi1ib3JkZXInKSB8fCB1dGlsLmhhc01vZGlmaWVyKHRoaXMsICdtYXRlcmlhbCcpID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJJbmRleCgpO1xuICAgICAgaWYgKHRoaXMuX3RhYnNSZWN0Lmxlbmd0aCA+IDAgJiYgaW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLl90YWJiYXJCb3JkZXIuc3R5bGUud2lkdGggPSB0aGlzLl90YWJzUmVjdFtpbmRleF0ud2lkdGggKyAncHgnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9nZXRBdXRvU2Nyb2xsUmF0aW8obWF0Y2hlcywgdmVsb2NpdHksIHNpemUpIHtcbiAgICBjb25zdCByYXRpbyA9IC42OyAvLyBCYXNlIHJhdGlvXG4gICAgY29uc3QgbW9kaWZpZXIgPSBzaXplIC8gMzAwICogKG1hdGNoZXMgPyAtMSA6IDEpOyAvLyBCYXNlZCBvbiBzY3JlZW4gc2l6ZVxuICAgIHJldHVybiBNYXRoLm1pbigxLCBNYXRoLm1heCgwLCByYXRpbyArIHZlbG9jaXR5ICogbW9kaWZpZXIpKTtcbiAgfVxuXG4gIGdldCBfdGFiYmFyRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kQ2hpbGQodGhpcywgJy50YWJiYXInKTtcbiAgfVxuXG4gIGdldCBfY29udGVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcudGFiYmFyX19jb250ZW50Jyk7XG4gIH1cblxuICBnZXQgX3RhcmdldEVsZW1lbnQoKSB7XG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuX2NvbnRlbnRFbGVtZW50O1xuICAgIHJldHVybiBjb250ZW50ICYmIGNvbnRlbnQuY2hpbGRyZW5bMF0gfHwgbnVsbDtcbiAgfVxuXG4gIF9jb21waWxlKCkge1xuICAgIGF1dG9TdHlsZS5wcmVwYXJlKHRoaXMpO1xuXG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuX2NvbnRlbnRFbGVtZW50IHx8IHV0aWwuY3JlYXRlKCcudGFiYmFyX19jb250ZW50Jyk7XG4gICAgY29udGVudC5jbGFzc0xpc3QuYWRkKCdvbnMtdGFiYmFyX19jb250ZW50Jyk7XG4gICAgY29uc3QgdGFiYmFyID0gdGhpcy5fdGFiYmFyRWxlbWVudCB8fCB1dGlsLmNyZWF0ZSgnLnRhYmJhcicpO1xuICAgIHRhYmJhci5jbGFzc0xpc3QuYWRkKCdvbnMtdGFiYmFyX19mb290ZXInKTtcblxuICAgIGlmICghdGFiYmFyLnBhcmVudE5vZGUpIHtcbiAgICAgIHdoaWxlICh0aGlzLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgdGFiYmFyLmFwcGVuZENoaWxkKHRoaXMuZmlyc3RDaGlsZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSBOdW1iZXIodGhpcy5nZXRBdHRyaWJ1dGUoJ2FjdGl2ZUluZGV4JykpOyAvLyAwIGJ5IGRlZmF1bHRcbiAgICBpZiAodGFiYmFyLmNoaWxkcmVuLmxlbmd0aCA+IGFjdGl2ZUluZGV4ICYmICF1dGlsLmZpbmRDaGlsZCh0YWJiYXIsICdbYWN0aXZlXScpKSB7XG4gICAgICB0YWJiYXIuY2hpbGRyZW5bYWN0aXZlSW5kZXhdLnNldEF0dHJpYnV0ZSgnYWN0aXZlJywgJycpO1xuICAgIH1cblxuICAgIHRoaXMuX3RhYmJhckJvcmRlciA9IHV0aWwuZmluZENoaWxkKHRhYmJhciwgJy50YWJiYXJfX2JvcmRlcicpIHx8IHV0aWwuY3JlYXRlKCcudGFiYmFyX19ib3JkZXInKTtcbiAgICB0YWJiYXIuYXBwZW5kQ2hpbGQodGhpcy5fdGFiYmFyQm9yZGVyKTtcbiAgICB0YWJiYXIuY2xhc3NMaXN0LmFkZCgnb25zLXN3aXBlci10YWJiYXInKTsgLy8gSGlkZXMgbWF0ZXJpYWwgYm9yZGVyXG5cbiAgICAhY29udGVudC5jaGlsZHJlblswXSAmJiBjb250ZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICAhY29udGVudC5jaGlsZHJlblsxXSAmJiBjb250ZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcbiAgICBjb250ZW50LmFwcGVuZENoaWxkID0gY29udGVudC5hcHBlbmRDaGlsZC5iaW5kKGNvbnRlbnQuY2hpbGRyZW5bMF0pO1xuICAgIGNvbnRlbnQuaW5zZXJ0QmVmb3JlID0gY29udGVudC5pbnNlcnRCZWZvcmUuYmluZChjb250ZW50LmNoaWxkcmVuWzBdKTtcblxuICAgIHRoaXMuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gICAgdGhpcy5hcHBlbmRDaGlsZCh0YWJiYXIpOyAvLyBUcmlnZ2VycyBvbnMtdGFiIGNvbm5lY3RlZENhbGxiYWNrXG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHNjaGVtZSk7XG4gIH1cblxuICBfdXBkYXRlUG9zaXRpb24ocG9zaXRpb24gPSB0aGlzLmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKSkge1xuICAgIGNvbnN0IHRvcCA9IHRoaXMuX3RvcCA9IHBvc2l0aW9uID09PSAndG9wJyB8fCAocG9zaXRpb24gPT09ICdhdXRvJyAmJiB1dGlsLmhhc01vZGlmaWVyKHRoaXMsICdtYXRlcmlhbCcpKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0b3AgPyB1dGlsLmFkZE1vZGlmaWVyIDogdXRpbC5yZW1vdmVNb2RpZmllcjtcblxuICAgIGFjdGlvbih0aGlzLCAndG9wJyk7XG5cbiAgICBjb25zdCBwYWdlID0gdXRpbC5maW5kUGFyZW50KHRoaXMsICdvbnMtcGFnZScpO1xuICAgIGlmIChwYWdlKSB7XG4gICAgICBjb250ZW50UmVhZHkocGFnZSwgKCkgPT4ge1xuICAgICAgICBsZXQgcCA9IDA7XG4gICAgICAgIGlmIChwYWdlLmNoaWxkcmVuWzBdICYmIHV0aWwubWF0Y2gocGFnZS5jaGlsZHJlblswXSwgJ29ucy10b29sYmFyJykpIHtcbiAgICAgICAgICBhY3Rpb24ocGFnZS5jaGlsZHJlblswXSwgJ25vc2hhZG93Jyk7XG4gICAgICAgICAgcCA9IDE7IC8vIFZpc3VhbCBmaXggZm9yIHNvbWUgZGV2aWNlc1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29udGVudCA9IHBhZ2UuX2dldENvbnRlbnRFbGVtZW50KCk7XG4gICAgICAgIGNvbnN0IGNzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUocGFnZS5fZ2V0Q29udGVudEVsZW1lbnQoKSwgbnVsbClcblxuICAgICAgICB0aGlzLnN0eWxlLnRvcCA9IHRvcCA/IHBhcnNlSW50KGNzLmdldFByb3BlcnR5VmFsdWUoJ3BhZGRpbmctdG9wJyksIDEwKSAtIHAgKyAncHgnIDogJyc7XG5cbiAgICAgICAgLy8gUmVmcmVzaCBjb250ZW50IHRvcCAtIEZpeCBmb3IgaU9TIDhcbiAgICAgICAgY29udGVudC5zdHlsZS50b3AgPSBjcy50b3A7XG4gICAgICAgIGNvbnRlbnQuc3R5bGUudG9wID0gJyc7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpbnRlcm5hbC5hdXRvU3RhdHVzQmFyRmlsbCgoKSA9PiB7XG4gICAgICBjb25zdCBmaWxsZWQgPSB1dGlsLmZpbmRQYXJlbnQodGhpcywgZSA9PiBlLmhhc0F0dHJpYnV0ZSgnc3RhdHVzLWJhci1maWxsJykpO1xuICAgICAgdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ3N0YXR1cy1iYXItZmlsbCcsIHRvcCAmJiAhZmlsbGVkKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCB0b3BQYWdlKCkge1xuICAgIGNvbnN0IHRhYnMgPSB0aGlzLnRhYnMsXG4gICAgICBpbmRleCA9IHRoaXMuZ2V0QWN0aXZlVGFiSW5kZXgoKTtcbiAgICByZXR1cm4gdGFic1tpbmRleF1cbiAgICAgID8gdGFic1tpbmRleF0ucGFnZUVsZW1lbnQgfHwgdGhpcy5wYWdlc1swXSB8fCBudWxsXG4gICAgICA6IG51bGw7XG4gIH1cblxuICBnZXQgcGFnZXMoKSB7XG4gICAgcmV0dXJuIHV0aWwuYXJyYXlGcm9tKHRoaXMuX3RhcmdldEVsZW1lbnQuY2hpbGRyZW4pO1xuICB9XG5cbiAgZ2V0IHRhYnMoKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbCh0aGlzLl90YWJiYXJFbGVtZW50LmNoaWxkcmVuLCBlID0+IGUudGFnTmFtZSA9PT0gJ09OUy1UQUInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNldEFjdGl2ZVRhYlxuICAgKiBAc2lnbmF0dXJlIHNldEFjdGl2ZVRhYihpbmRleCwgW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogICBbZW5dVGFiIGluZGV4LlsvZW5dXG4gICAqICAgW2phXeOCv+ODluOBruOCpOODs+ODh+ODg+OCr+OCueOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5jYWxsYmFja11cbiAgICogICBbZW5dRnVuY3Rpb24gdGhhdCBydW5zIHdoZW4gdGhlIG5ldyBwYWdlIGhhcyBsb2FkZWQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dSWYgdGhpcyBvcHRpb24gaXMgXCJub25lXCIsIHRoZSB0cmFuc2l0aW9uIHdvbid0IHNsaWRlLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dU2hvdyBzcGVjaWZpZWQgdGFiIHBhZ2UuIEFuaW1hdGlvbnMgYW5kIHRoZWlyIG9wdGlvbnMgY2FuIGJlIHNwZWNpZmllZCBieSB0aGUgc2Vjb25kIHBhcmFtZXRlci5bL2VuXVxuICAgKiAgIFtqYV3mjIflrprjgZfjgZ/jgqTjg7Pjg4fjg4Pjgq/jgrnjga7jgr/jg5bjgpLooajnpLrjgZfjgb7jgZnjgILjgqLjg4vjg6Hjg7zjgrfjg6fjg7Pjgarjganjga7jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgafjgY3jgb7jgZnjgIJbL2phXVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKiAgIFtlbl1BIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHBhZ2UgZWxlbWVudC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKi9cbiAgc2V0QWN0aXZlVGFiKG5leHRJbmRleCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcHJldkluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJJbmRleCgpO1xuICAgIGNvbnN0IHByZXZUYWIgPSB0aGlzLnRhYnNbcHJldkluZGV4XSxcbiAgICAgIG5leHRUYWIgPSB0aGlzLnRhYnNbbmV4dEluZGV4XTtcblxuICAgIGlmICghbmV4dFRhYikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdTcGVjaWZpZWQgaW5kZXggZG9lcyBub3QgbWF0Y2ggYW55IHRhYi4nKTtcbiAgICB9XG5cbiAgICBpZiAobmV4dEluZGV4ID09PSBwcmV2SW5kZXgpIHtcbiAgICAgIHV0aWwudHJpZ2dlckVsZW1lbnRFdmVudCh0aGlzLCAncmVhY3RpdmUnLCB7IGluZGV4OiBuZXh0SW5kZXgsIGFjdGl2ZUluZGV4OiBuZXh0SW5kZXgsIHRhYkl0ZW06IG5leHRUYWIgfSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHRUYWIucGFnZUVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIEZJWE1FOiBuZXh0VGFiLmxvYWRlZCBpcyBicm9rZW4gaW4gWm9uZS5qcyBwcm9taXNlcyAoQW5ndWxhcjIpXG4gICAgY29uc3QgbmV4dFBhZ2UgPSBuZXh0VGFiLnBhZ2VFbGVtZW50O1xuICAgIHJldHVybiAobmV4dFBhZ2UgPyBQcm9taXNlLnJlc29sdmUobmV4dFBhZ2UpIDogbmV4dFRhYi5sb2FkZWQpXG4gICAgICAudGhlbihuZXh0UGFnZSA9PiB0aGlzLl9zd2lwZXIuc2V0QWN0aXZlSW5kZXgobmV4dEluZGV4LCB7XG4gICAgICAgIHJlamVjdDogdHJ1ZSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgYW5pbWF0aW9uOiBwcmV2VGFiICYmIG5leHRQYWdlID8gb3B0aW9ucy5hbmltYXRpb24gfHwgdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpIDogJ25vbmUnLFxuICAgICAgICBhbmltYXRpb25PcHRpb25zOiB1dGlsLmV4dGVuZChcbiAgICAgICAgICB7IGR1cmF0aW9uOiAuMywgdGltaW5nOiAnY3ViaWMtYmV6aWVyKC40LCAuNywgLjUsIDEpJyB9LFxuICAgICAgICAgIHRoaXMuaGFzQXR0cmlidXRlKCdhbmltYXRpb24tb3B0aW9ucycpID8gdXRpbC5hbmltYXRpb25PcHRpb25zUGFyc2UodGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbi1vcHRpb25zJykpIDoge30sXG4gICAgICAgICAgb3B0aW9ucy5hbmltYXRpb25PcHRpb25zIHx8IHt9XG4gICAgICAgIClcbiAgICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICBvcHRpb25zLmNhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24gJiYgb3B0aW9ucy5jYWxsYmFjayhuZXh0UGFnZSk7XG4gICAgICAgIHJldHVybiBuZXh0UGFnZTtcbiAgICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAbWV0aG9kIHNldFRhYmJhclZpc2liaWxpdHlcbiAgICogQHNpZ25hdHVyZSBzZXRUYWJiYXJWaXNpYmlsaXR5KHZpc2libGUpXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gdmlzaWJsZVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVXNlZCB0byBoaWRlIG9yIHNob3cgdGhlIHRhYiBiYXIuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIHNldFRhYmJhclZpc2liaWxpdHkodmlzaWJsZSkge1xuICAgIGNvbnRlbnRSZWFkeSh0aGlzLCAoKSA9PiB7XG4gICAgICB0aGlzLl9jb250ZW50RWxlbWVudC5zdHlsZVt0aGlzLl90b3AgPyAndG9wJyA6ICdib3R0b20nXSA9IHZpc2libGUgPyAnJyA6ICcwcHgnO1xuICAgICAgdGhpcy5fdGFiYmFyRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA/ICcnIDogJ25vbmUnO1xuICAgICAgdmlzaWJsZSAmJiB0aGlzLl9vblJlZnJlc2goKTtcbiAgICB9KTtcbiAgfVxuXG4gIHNob3coKSB7XG4gICAgdGhpcy5zZXRUYWJiYXJWaXNpYmlsaXR5KHRydWUpO1xuICB9XG5cbiAgaGlkZSgpIHtcbiAgICB0aGlzLnNldFRhYmJhclZpc2liaWxpdHkoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSB2aXNpYmxlXG4gICAqIEByZWFkb25seVxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIHRhYmJhciBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3jgr/jg5bjg5Djg7zjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cbiAgZ2V0IHZpc2libGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmJhckVsZW1lbnQuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBzd2lwZWFibGVcbiAgICogQHR5cGUge0Jvb2xlYW59XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1FbmFibGUgc3dpcGUgaW50ZXJhY3Rpb24uWy9lbl1cbiAgICogICBbamFdc3dpcGVhYmxl44Gn44GC44KM44GwdHJ1ZeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXQgc3dpcGVhYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmhhc0F0dHJpYnV0ZSgnc3dpcGVhYmxlJyk7XG4gIH1cblxuICBzZXQgc3dpcGVhYmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIHV0aWwudG9nZ2xlQXR0cmlidXRlKHRoaXMsICdzd2lwZWFibGUnLCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uU3dpcGVcbiAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dSG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIHVzZXIgc2xpZGVzIHRoZSB0YWJiYXIuIEl0IGdldHMgYSBkZWNpbWFsIGluZGV4IGFuZCBhbiBhbmltYXRpb25PcHRpb25zIG9iamVjdCBhcyBhcmd1bWVudHMuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG4gIGdldCBvblN3aXBlKCkge1xuICAgIHJldHVybiB0aGlzLl9vblN3aXBlO1xuICB9XG5cbiAgc2V0IG9uU3dpcGUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgdXRpbC50aHJvdyhgXCJvblN3aXBlXCIgbXVzdCBiZSBhIGZ1bmN0aW9uYClcbiAgICB9XG4gICAgdGhpcy5fb25Td2lwZSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBtZXRob2QgZ2V0QWN0aXZlVGFiSW5kZXhcbiAgICogQHNpZ25hdHVyZSBnZXRBY3RpdmVUYWJJbmRleCgpXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICogICBbZW5dVGhlIGluZGV4IG9mIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRhYi5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovjgr/jg5bjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgIJbL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dUmV0dXJucyB0YWIgaW5kZXggb24gY3VycmVudCBhY3RpdmUgdGFiLiBJZiBhY3RpdmUgdGFiIGlzIG5vdCBmb3VuZCwgcmV0dXJucyAtMS5bL2VuXVxuICAgKiAgIFtqYV3nj77lnKjjgqLjgq/jg4bjgqPjg5bjgavjgarjgaPjgabjgYTjgovjgr/jg5bjga7jgqTjg7Pjg4fjg4Pjgq/jgrnjgpLov5TjgZfjgb7jgZnjgILnj77lnKjjgqLjgq/jg4bjgqPjg5bjgarjgr/jg5bjgYzjgarjgYTloLTlkIjjgavjga8tMeOCkui/lOOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuICBnZXRBY3RpdmVUYWJJbmRleCh0YWJzID0gdGhpcy50YWJzKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodGFic1tpXSAmJiB0YWJzW2ldLnRhZ05hbWUgPT09ICdPTlMtVEFCJyAmJiB0YWJzW2ldLmlzQWN0aXZlKCkpIHtcbiAgICAgICAgcmV0dXJuIGk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIF9zaG93KCkge1xuICAgIHRoaXMuX3N3aXBlci5zaG93KCk7XG5cbiAgICBzZXRJbW1lZGlhdGUoKCkgPT4ge1xuICAgICAgY29uc3QgdGFicyA9IHRoaXMudGFicztcbiAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gdGhpcy5nZXRBY3RpdmVUYWJJbmRleCh0YWJzKTtcbiAgICAgIHRoaXMuX2xvYWRJbmFjdGl2ZS5yZXNvbHZlKCk7XG4gICAgICBpZiAodGFicy5sZW5ndGggPiAwICYmIGFjdGl2ZUluZGV4ID49IDApIHtcbiAgICAgICAgdGFic1thY3RpdmVJbmRleF0ubG9hZGVkLnRoZW4oZWwgPT4gZWwgJiYgc2V0SW1tZWRpYXRlKCgpID0+IGVsLl9zaG93KCkpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIF9oaWRlKCkge1xuICAgIHRoaXMuX3N3aXBlci5oaWRlKCk7XG4gICAgY29uc3QgdG9wUGFnZSA9IHRoaXMudG9wUGFnZTtcbiAgICB0b3BQYWdlICYmIHRvcFBhZ2UuX2hpZGUoKTtcbiAgfVxuXG4gIF9kZXN0cm95KCkge1xuICAgIHRoaXMudGFicy5mb3JFYWNoKHRhYiA9PiB0YWIucmVtb3ZlKCkpO1xuICAgIHRoaXMucmVtb3ZlKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdwb3NpdGlvbicsICdzd2lwZWFibGUnLCAndGFiLWJvcmRlcicsICdoaWRlLXRhYnMnXTtcbiAgfVxuXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBsYXN0LCBjdXJyZW50KSB7XG4gICAgaWYgKG5hbWUgPT09ICdtb2RpZmllcicpIHtcbiAgICAgIE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpO1xuICAgICAgY29uc3QgaXNUb3AgPSBtID0+IC8oXnxcXHMrKXRvcCgkfFxccyspL2kudGVzdChtKTtcbiAgICAgIGlzVG9wKGxhc3QpICE9PSBpc1RvcChjdXJyZW50KSAmJiB0aGlzLl91cGRhdGVQb3NpdGlvbigpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3Bvc2l0aW9uJykge1xuICAgICAgdXRpbC5pc0F0dGFjaGVkKHRoaXMpICYmIHRoaXMuX3VwZGF0ZVBvc2l0aW9uKCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAnc3dpcGVhYmxlJykge1xuICAgICAgdGhpcy5fc3dpcGVyICYmIHRoaXMuX3N3aXBlci51cGRhdGVTd2lwZWFibGUodGhpcy5oYXNBdHRyaWJ1dGUoJ3N3aXBlYWJsZScpKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdoaWRlLXRhYnMnKSB7XG4gICAgICB0aGlzLnNldFRhYmJhclZpc2liaWxpdHkoIXRoaXMuaGFzQXR0cmlidXRlKCdoaWRlLXRhYnMnKSB8fCBjdXJyZW50ID09PSAnZmFsc2UnKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgZ2V0IHJld3JpdGFibGVzKCkge1xuICAgIHJldHVybiByZXdyaXRhYmxlcztcbiAgfVxuXG4gIHN0YXRpYyBnZXQgZXZlbnRzKCkge1xuICAgIHJldHVybiBbJ3ByZWNoYW5nZScsICdwb3N0Y2hhbmdlJywgJ3JlYWN0aXZlJ107XG4gIH1cbn1cblxub25zRWxlbWVudHMuVGFiYmFyID0gVGFiYmFyRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXRhYmJhcicsIFRhYmJhckVsZW1lbnQpO1xuIiwiLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IG9uc0VsZW1lbnRzIGZyb20gJy4uL29ucy9lbGVtZW50cyc7XG5pbXBvcnQgdXRpbCBmcm9tICcuLi9vbnMvdXRpbCc7XG5pbXBvcnQgYXV0b1N0eWxlIGZyb20gJy4uL29ucy9hdXRvc3R5bGUnO1xuaW1wb3J0IE1vZGlmaWVyVXRpbCBmcm9tICcuLi9vbnMvaW50ZXJuYWwvbW9kaWZpZXItdXRpbCc7XG5pbXBvcnQgQmFzZUVsZW1lbnQgZnJvbSAnLi9iYXNlL2Jhc2UtZWxlbWVudCc7XG5pbXBvcnQgVGFiYmFyRWxlbWVudCBmcm9tICcuL29ucy10YWJiYXInO1xuaW1wb3J0IGNvbnRlbnRSZWFkeSBmcm9tICcuLi9vbnMvY29udGVudC1yZWFkeSc7XG5pbXBvcnQgeyBQYWdlTG9hZGVyLCBkZWZhdWx0UGFnZUxvYWRlciB9IGZyb20gJy4uL29ucy9wYWdlLWxvYWRlcic7XG5cbmNvbnN0IGRlZmF1bHRDbGFzc05hbWUgPSAndGFiYmFyX19pdGVtJztcblxuY29uc3Qgc2NoZW1lID0ge1xuICAnJzogJ3RhYmJhci0tKl9faXRlbScsXG4gICcudGFiYmFyX19idXR0b24nOiAndGFiYmFyLS0qX19idXR0b24nXG59O1xuXG4vKipcbiAqIEBlbGVtZW50IG9ucy10YWJcbiAqIEBjYXRlZ29yeSB0YWJiYXJcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dUmVwcmVzZW50cyBhIHRhYiBpbnNpZGUgdGFiIGJhci4gRWFjaCBgPG9ucy10YWI+YCByZXByZXNlbnRzIGEgcGFnZS5bL2VuXVxuICogICBbamFdXG4gKiAgICAg44K/44OW44OQ44O844Gr6YWN572u44GV44KM44KL5ZCE44Ki44Kk44OG44Og44Gu44Kz44Oz44Od44O844ON44Oz44OI44Gn44GZ44CC44Gd44KM44Ge44KM44Gub25zLXRhYuOBr+ODmuODvOOCuOOCkuihqOOBl+OBvuOBmeOAglxuICogICAgIG9ucy10YWLopoHntKDjga7kuK3jgavjga/jgIHjgr/jg5bjgavooajnpLrjgZXjgozjgovjgrPjg7Pjg4bjg7Pjg4TjgpLnm7TmjqXoqJjov7DjgZnjgovjgZPjgajjgYzlh7rmnaXjgb7jgZnjgIJcbiAqICAgWy9qYV1cbiAqIEBjb2RlcGVuIHBHdURMXG4gKiBAdHV0b3JpYWwgdmFuaWxsYS9SZWZlcmVuY2UvdGFiYmFyXG4gKiBAZ3VpZGUgZnVuZGFtZW50YWxzLmh0bWwjbWFuYWdpbmctcGFnZXNcbiAqICAgW2VuXU1hbmFnaW5nIG11bHRpcGxlIHBhZ2VzLlsvZW5dXG4gKiAgIFtqYV3opIfmlbDjga7jg5rjg7zjgrjjgpLnrqHnkIbjgZnjgotbL2phXV1cbiAqIEBndWlkZSBhcHBzaXplLmh0bWwjcmVtb3ZpbmctaWNvbi1wYWNrcyBbZW5dUmVtb3ZpbmcgaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQGd1aWRlIGZhcS5odG1sI2hvdy1jYW4taS11c2UtY3VzdG9tLWljb24tcGFja3MgW2VuXUFkZGluZyBjdXN0b20gaWNvbiBwYWNrcy5bL2VuXVtqYV1bL2phXVxuICogQHNlZWFsc28gb25zLXRhYmJhclxuICogICBbZW5db25zLXRhYmJhciBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLXRhYmJhcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtcGFnZVxuICogICBbZW5db25zLXBhZ2UgY29tcG9uZW50Wy9lbl1cbiAqICAgW2phXW9ucy1wYWdl44Kz44Oz44Od44O844ON44Oz44OIWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy1pY29uXG4gKiAgIFtlbl1vbnMtaWNvbiBjb21wb25lbnRbL2VuXVxuICogICBbamFdb25zLWljb27jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtdGFiYmFyPlxuICogICA8b25zLXRhYlxuICogICAgIHBhZ2U9XCJob21lLmh0bWxcIlxuICogICAgIGxhYmVsPVwiSG9tZVwiXG4gKiAgICAgYWN0aXZlPlxuICogICA8L29ucy10YWI+XG4gKiAgIDxvbnMtdGFiXG4gKiAgICAgcGFnZT1cInNldHRpbmdzLmh0bWxcIlxuICogICAgIGxhYmVsPVwiU2V0dGluZ3NcIlxuICogICAgIGFjdGl2ZT5cbiAqICAgPC9vbnMtdGFiPlxuICogPC9vbnMtdGFiYmFyPlxuICpcbiAqIDx0ZW1wbGF0ZSBpZD1cImhvbWUuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG4gKlxuICogPHRlbXBsYXRlIGlkPVwic2V0dGluZ3MuaHRtbFwiPlxuICogICAuLi5cbiAqIDwvdGVtcGxhdGU+XG5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGFiRWxlbWVudCBleHRlbmRzIEJhc2VFbGVtZW50IHtcblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBwYWdlXG4gICAqIEBpbml0b25seVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIHBhZ2UgdGhhdCBpcyBkaXNwbGF5ZWQgd2hlbiB0aGUgdGFiIGlzIHRhcHBlZC5bL2VuXVxuICAgKiAgIFtqYV1vbnMtdGFi44GM5Y+C54Wn44GZ44KL44Oa44O844K444G444GuVVJM44KS5oyH5a6a44GX44G+44GZ44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgaWNvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dXG4gICAqICAgICBUaGUgaWNvbiBuYW1lIGZvciB0aGUgdGFiLiBDYW4gc3BlY2lmeSB0aGUgc2FtZSBpY29uIG5hbWUgYXMgYDxvbnMtaWNvbj5gLiBDaGVjayBbU2VlIGFsc29dKCNzZWVhbHNvKSBzZWN0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuICAgKiAgIFsvZW5dXG4gICAqICAgW2phXVxuICAgKiAgICAg44Ki44Kk44Kz44Oz5ZCN44KS5oyH5a6a44GX44G+44GZ44CCb25zLWljb27jgajlkIzjgZjjgqLjgqTjgrPjg7PlkI3jgpLmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICAgIOWAi+WIpeOBq+OCouOCpOOCs+ODs+OCkuOCq+OCueOCv+ODnuOCpOOCuuOBmeOCi+WgtOWQiOOBr+OAgWJhY2tncm91bmQtaW1hZ2Xjgarjganjga5DU1Pjgrnjgr/jgqTjg6vjgpLnlKjjgYTjgabmjIflrprjgafjgY3jgb7jgZnjgIJcbiAgICogICBbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhY3RpdmUtaWNvblxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIG5hbWUgb2YgdGhlIGljb24gd2hlbiB0aGUgdGFiIGlzIGFjdGl2ZS5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgq/jg4bjgqPjg5bjga7pmpvjga7jgqLjgqTjgrPjg7PlkI3jgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBsYWJlbFxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVGhlIGxhYmVsIG9mIHRoZSB0YWIgaXRlbS5bL2VuXVxuICAgKiAgIFtqYV3jgqLjgqTjgrPjg7PkuIvjgavooajnpLrjgZXjgozjgovjg6njg5njg6vjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBiYWRnZVxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dRGlzcGxheSBhIG5vdGlmaWNhdGlvbiBiYWRnZSBvbiB0b3Agb2YgdGhlIHRhYi5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4PjgrjjgavooajnpLrjgZnjgovlhoXlrrnjgpLmjIflrprjgZfjgb7jgZnjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhY3RpdmVcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVRoaXMgYXR0cmlidXRlIHNob3VsZCBiZSBzZXQgdG8gdGhlIHRhYiB0aGF0IGlzIGFjdGl2ZSBieSBkZWZhdWx0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoWydsYWJlbCcsICdpY29uJywgJ2JhZGdlJ10uc29tZSh0aGlzLmhhc0F0dHJpYnV0ZS5iaW5kKHRoaXMpKSkge1xuICAgICAgdGhpcy5fY29tcGlsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgICB9XG5cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gZGVmYXVsdFBhZ2VMb2FkZXI7XG4gICAgdGhpcy5fb25DbGljayA9IHRoaXMuX29uQ2xpY2suYmluZCh0aGlzKTtcbiAgfVxuXG4gIHNldCBwYWdlTG9hZGVyKGxvYWRlcikge1xuICAgIGlmICghKGxvYWRlciBpbnN0YW5jZW9mIFBhZ2VMb2FkZXIpKSB7XG4gICAgICB1dGlsLnRocm93UGFnZUxvYWRlcigpO1xuICAgIH1cbiAgICB0aGlzLl9wYWdlTG9hZGVyID0gbG9hZGVyO1xuICB9XG5cbiAgZ2V0IHBhZ2VMb2FkZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BhZ2VMb2FkZXI7XG4gIH1cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcbiAgICB0aGlzLmNsYXNzTGlzdC5hZGQoZGVmYXVsdENsYXNzTmFtZSk7XG5cbiAgICBpZiAodGhpcy5fYnV0dG9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYnV0dG9uID0gdXRpbC5jcmVhdGUoJ2J1dHRvbi50YWJiYXJfX2J1dHRvbicpO1xuICAgIHdoaWxlICh0aGlzLmNoaWxkTm9kZXNbMF0pIHtcbiAgICAgIGJ1dHRvbi5hcHBlbmRDaGlsZCh0aGlzLmNoaWxkTm9kZXNbMF0pO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0ID0gdXRpbC5jcmVhdGUoJ2lucHV0JywgeyBkaXNwbGF5OiAnbm9uZScgfSk7XG4gICAgaW5wdXQudHlwZSA9ICdyYWRpbyc7XG5cbiAgICB0aGlzLmFwcGVuZENoaWxkKGlucHV0KTtcbiAgICB0aGlzLmFwcGVuZENoaWxkKGJ1dHRvbik7XG5cbiAgICB0aGlzLl91cGRhdGVCdXR0b25Db250ZW50KCk7XG4gICAgTW9kaWZpZXJVdGlsLmluaXRNb2RpZmllcih0aGlzLCBzY2hlbWUpO1xuICAgIHRoaXMuX3VwZGF0ZVJpcHBsZSgpO1xuICB9XG5cbiAgX3VwZGF0ZVJpcHBsZSgpIHtcbiAgICB0aGlzLl9idXR0b24gJiYgdXRpbC51cGRhdGVSaXBwbGUodGhpcy5fYnV0dG9uLCB0aGlzLmhhc0F0dHJpYnV0ZSgncmlwcGxlJykpO1xuICB9XG5cbiAgX3VwZGF0ZUJ1dHRvbkNvbnRlbnQoKSB7XG4gICAgY29uc3QgYnV0dG9uID0gdGhpcy5fYnV0dG9uO1xuXG4gICAgbGV0IGljb25XcmFwcGVyID0gdGhpcy5faWNvbjtcbiAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoJ2ljb24nKSkge1xuICAgICAgaWNvbldyYXBwZXIgPSBpY29uV3JhcHBlciB8fCB1dGlsLmNyZWF0ZUVsZW1lbnQoJzxkaXYgY2xhc3M9XCJ0YWJiYXJfX2ljb25cIj48b25zLWljb24+PC9vbnMtaWNvbj48L2Rpdj4nKTtcbiAgICAgIGNvbnN0IGljb24gPSBpY29uV3JhcHBlci5jaGlsZHJlblswXTtcbiAgICAgIGNvbnN0IGZpeCA9IChsYXN0ID0+ICgpID0+IGljb24uYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKCdpY29uJywgbGFzdCwgdGhpcy5nZXRBdHRyaWJ1dGUoJ2ljb24nKSkpKGljb24uZ2V0QXR0cmlidXRlKCdpY29uJykpO1xuICAgICAgaWNvbi5zZXRBdHRyaWJ1dGUoJ2ljb24nLCB0aGlzLmdldEF0dHJpYnV0ZSgnaWNvbicpKTtcbiAgICAgIGljb25XcmFwcGVyLnBhcmVudEVsZW1lbnQgIT09IGJ1dHRvbiAmJiBidXR0b24uaW5zZXJ0QmVmb3JlKGljb25XcmFwcGVyLCBidXR0b24uZmlyc3RDaGlsZCk7XG5cbiAgICAgIC8vIGRpcnR5IGZpeCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL09uc2VuVUkvT25zZW5VSS9pc3N1ZXMvMTY1NFxuICAgICAgaWNvbi5hdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sgaW5zdGFuY2VvZiBGdW5jdGlvblxuICAgICAgICA/IGZpeCgpXG4gICAgICAgIDogc2V0SW1tZWRpYXRlKCgpID0+IGljb24uYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrIGluc3RhbmNlb2YgRnVuY3Rpb24gJiYgZml4KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpY29uV3JhcHBlciAmJiBpY29uV3JhcHBlci5yZW1vdmUoKTtcbiAgICB9XG5cbiAgICBbJ2xhYmVsJywgJ2JhZGdlJ10uZm9yRWFjaCgoYXR0ciwgaW5kZXgpID0+IHtcbiAgICAgIGxldCBwcm9wID0gdGhpcy5xdWVyeVNlbGVjdG9yKGAudGFiYmFyX18ke2F0dHJ9YCk7XG4gICAgICBpZiAodGhpcy5oYXNBdHRyaWJ1dGUoYXR0cikpIHtcbiAgICAgICAgcHJvcCA9IHByb3AgfHwgdXRpbC5jcmVhdGUoYC50YWJiYXJfXyR7YXR0cn1gICsgKGF0dHIgPT09ICdiYWRnZScgPyAnIG5vdGlmaWNhdGlvbicgOiAnJykpO1xuICAgICAgICBwcm9wLnRleHRDb250ZW50ID0gdGhpcy5nZXRBdHRyaWJ1dGUoYXR0cik7XG4gICAgICAgIHByb3AucGFyZW50RWxlbWVudCAhPT0gYnV0dG9uICYmIGJ1dHRvbi5hcHBlbmRDaGlsZChwcm9wKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb3AgJiYgcHJvcC5yZW1vdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGdldCBfaW5wdXQoKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICdpbnB1dCcpO1xuICB9XG5cbiAgZ2V0IF9idXR0b24oKSB7XG4gICAgcmV0dXJuIHV0aWwuZmluZENoaWxkKHRoaXMsICcudGFiYmFyX19idXR0b24nKTtcbiAgfVxuXG4gIGdldCBfaWNvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yKCcudGFiYmFyX19pY29uJyk7XG4gIH1cblxuICBnZXQgX3RhYmJhcigpIHtcbiAgICByZXR1cm4gdXRpbC5maW5kUGFyZW50KHRoaXMsICdvbnMtdGFiYmFyJyk7XG4gIH1cblxuICBnZXQgaW5kZXgoKSB7XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwodGhpcy5wYXJlbnRFbGVtZW50LmNoaWxkcmVuLCB0aGlzKTtcbiAgfVxuXG4gIF9vbkNsaWNrKCkge1xuICAgIGlmICh0aGlzLm9uQ2xpY2sgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgdGhpcy5vbkNsaWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RhYmJhci5zZXRBY3RpdmVUYWIodGhpcy5pbmRleCwgeyByZWplY3Q6IGZhbHNlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNldEFjdGl2ZShhY3RpdmUgPSB0cnVlKSB7XG4gICAgdGhpcy5faW5wdXQuY2hlY2tlZCA9IGFjdGl2ZTtcbiAgICB0aGlzLmNsYXNzTGlzdC50b2dnbGUoJ2FjdGl2ZScsIGFjdGl2ZSk7XG4gICAgdXRpbC50b2dnbGVBdHRyaWJ1dGUodGhpcywgJ2FjdGl2ZScsIGFjdGl2ZSlcblxuICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnaWNvbicpICYmIHRoaXMuaGFzQXR0cmlidXRlKCdhY3RpdmUtaWNvbicpKSB7XG4gICAgICB0aGlzLl9pY29uLmNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgnaWNvbicsIHRoaXMuZ2V0QXR0cmlidXRlKGFjdGl2ZSA/ICdhY3RpdmUtaWNvbicgOiAnaWNvbicpKTtcbiAgICB9XG4gIH1cblxuICBfbG9hZFBhZ2VFbGVtZW50KHBhcmVudCwgcGFnZSkge1xuICAgIHRoaXMuX2hhc0xvYWRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLl9wYWdlTG9hZGVyLmxvYWQoeyBwYXJlbnQsIHBhZ2UgfSwgcGFnZUVsZW1lbnQgPT4ge1xuICAgICAgICBwYXJlbnQucmVwbGFjZUNoaWxkKHBhZ2VFbGVtZW50LCBwYXJlbnQuY2hpbGRyZW5bdGhpcy5pbmRleF0pOyAvLyBFbnN1cmUgcG9zaXRpb25cbiAgICAgICAgdGhpcy5fbG9hZGVkUGFnZSA9IHBhZ2VFbGVtZW50O1xuICAgICAgICByZXNvbHZlKHBhZ2VFbGVtZW50KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHBhZ2VFbGVtZW50KCkge1xuICAgIC8vIEl0IGhhcyBiZWVuIGxvYWRlZCBieSBvbnMtdGFiXG4gICAgaWYgKHRoaXMuX2xvYWRlZFBhZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLl9sb2FkZWRQYWdlO1xuICAgIH1cbiAgICAvLyBNYW51YWxseSBhdHRhY2hlZCB0byBET00sIDEgcGVyIHRhYlxuICAgIGNvbnN0IHRhYmJhciA9IHRoaXMuX3RhYmJhcjtcbiAgICBpZiAodGFiYmFyLnBhZ2VzLmxlbmd0aCA9PT0gdGFiYmFyLnRhYnMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGFiYmFyLnBhZ2VzW3RoaXMuaW5kZXhdO1xuICAgIH1cbiAgICAvLyBMb2FkZWQgaW4gYW5vdGhlciB3YXlcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgaXNBY3RpdmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xhc3NMaXN0LmNvbnRhaW5zKCdhY3RpdmUnKTtcbiAgfVxuXG4gIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrLCBmYWxzZSk7XG4gICAgaWYgKHRoaXMuX2xvYWRlZFBhZ2UpIHtcbiAgICAgIHRoaXMuX2hhc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5sb2FkZWQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vbkNsaWNrLCBmYWxzZSk7XG5cbiAgICBpZiAoIXV0aWwuaXNBdHRhY2hlZCh0aGlzKSB8fCB0aGlzLmxvYWRlZCkge1xuICAgICAgcmV0dXJuOyAvLyBvbnMtdGFiYmFyIGNvbXBpbGF0aW9uIG1heSB0cmlnZ2VyIHRoaXNcbiAgICB9XG5cbiAgICBjb25zdCBkZWZlcnJlZCA9IHV0aWwuZGVmZXIoKTtcbiAgICB0aGlzLmxvYWRlZCA9IGRlZmVycmVkLnByb21pc2U7XG5cbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4ge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmluZGV4O1xuICAgICAgY29uc3QgdGFiYmFyID0gdGhpcy5fdGFiYmFyO1xuICAgICAgaWYgKCF0YWJiYXIpIHtcbiAgICAgICAgdXRpbC50aHJvdygnVGFiIGVsZW1lbnRzIG11c3QgYmUgY2hpbGRyZW4gb2YgVGFiYmFyJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YWJiYXIuaGFzQXR0cmlidXRlKCdtb2RpZmllcicpKSB7XG4gICAgICAgIHV0aWwuYWRkTW9kaWZpZXIodGhpcywgdGFiYmFyLmdldEF0dHJpYnV0ZSgnbW9kaWZpZXInKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5faGFzTG9hZGVkKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0F0dHJpYnV0ZSgnYWN0aXZlJykpIHtcbiAgICAgICAgICB0aGlzLnNldEFjdGl2ZSh0cnVlKTtcbiAgICAgICAgICB0YWJiYXIuc2V0QXR0cmlidXRlKCdhY3RpdmVJbmRleCcsIGluZGV4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbmRleCA9PT0gdGFiYmFyLnRhYnMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgIHRhYmJhci5fb25SZWZyZXNoKCk7XG4gICAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IHRhYmJhci5fb25SZWZyZXNoKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgVGFiYmFyRWxlbWVudC5yZXdyaXRhYmxlcy5yZWFkeSh0YWJiYXIsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBwYWdlVGFyZ2V0ID0gdGhpcy5wYWdlIHx8IHRoaXMuZ2V0QXR0cmlidXRlKCdwYWdlJyk7XG4gICAgICAgICAgaWYgKCF0aGlzLnBhZ2VFbGVtZW50ICYmIHBhZ2VUYXJnZXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudFRhcmdldCA9IHRhYmJhci5fdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgICAgIGNvbnN0IGR1bW15UGFnZSA9IHV0aWwuY3JlYXRlKCdkaXYnLCB7IGhlaWdodDogJzEwMCUnLCB3aWR0aDogJzEwMCUnLCB2aXNpYmlsaXR5OiAnaGlkZGVuJyB9KTtcbiAgICAgICAgICAgIHBhcmVudFRhcmdldC5pbnNlcnRCZWZvcmUoZHVtbXlQYWdlLCBwYXJlbnRUYXJnZXQuY2hpbGRyZW5baW5kZXhdKTsgLy8gRW5zdXJlIHBvc2l0aW9uXG5cbiAgICAgICAgICAgIGNvbnN0IGxvYWQgPSAoKSA9PiB0aGlzLl9sb2FkUGFnZUVsZW1lbnQocGFyZW50VGFyZ2V0LCBwYWdlVGFyZ2V0KS50aGVuKGRlZmVycmVkLnJlc29sdmUpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNBY3RpdmUoKSA/IGxvYWQoKSA6IHRhYmJhci5fbG9hZEluYWN0aXZlLnByb21pc2UudGhlbihsb2FkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZGVmZXJyZWQucmVzb2x2ZSh0aGlzLnBhZ2VFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydtb2RpZmllcicsICdyaXBwbGUnLCAnaWNvbicsICdsYWJlbCcsICdwYWdlJywgJ2JhZGdlJywgJ2NsYXNzJ107XG4gIH1cblxuICBhdHRyaWJ1dGVDaGFuZ2VkQ2FsbGJhY2sobmFtZSwgbGFzdCwgY3VycmVudCkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOlxuICAgICAgICB1dGlsLnJlc3RvcmVDbGFzcyh0aGlzLCBkZWZhdWx0Q2xhc3NOYW1lLCBzY2hlbWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21vZGlmaWVyJzpcbiAgICAgICAgY29udGVudFJlYWR5KHRoaXMsICgpID0+IE1vZGlmaWVyVXRpbC5vbk1vZGlmaWVyQ2hhbmdlZChsYXN0LCBjdXJyZW50LCB0aGlzLCBzY2hlbWUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaXBwbGUnOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlUmlwcGxlKCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ljb24nOlxuICAgICAgY2FzZSAnbGFiZWwnOlxuICAgICAgY2FzZSAnYmFkZ2UnOlxuICAgICAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fdXBkYXRlQnV0dG9uQ29udGVudCgpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdwYWdlJzpcbiAgICAgICAgdGhpcy5wYWdlID0gY3VycmVudCB8fCAnJztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbm9uc0VsZW1lbnRzLlRhYiA9IFRhYkVsZW1lbnQ7XG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ29ucy10YWInLCBUYWJFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBCYXNlQW5pbWF0b3IgZnJvbSAnLi4vLi4vb25zL2Jhc2UtYW5pbWF0b3InO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2FzdEFuaW1hdG9yIGV4dGVuZHMgQmFzZUFuaW1hdG9yIHtcblxuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMudGltaW5nXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmR1cmF0aW9uXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmRlbGF5XG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGltaW5nID0gJ2xpbmVhcicsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjJ9ID0ge30pIHtcbiAgICBzdXBlcih7IHRpbWluZywgZGVsYXksIGR1cmF0aW9uIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IG1vZGFsXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KG1vZGFsLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbW9kYWxcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUobW9kYWwsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxufVxuIiwiXG4vKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgYW5pbWl0IGZyb20gJy4uLy4uL29ucy9hbmltaXQnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogaU9TIHN0eWxlIGFuaW1hdG9yIGZvciBkaWFsb2cuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZhZGVUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3Ioe3RpbWluZyA9ICdsaW5lYXInLCBkZWxheSA9IDAsIGR1cmF0aW9uID0gMC4zfSA9IHt9KSB7XG4gICAgc3VwZXIoeyB0aW1pbmcsIGRlbGF5LCBkdXJhdGlvbiB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IGNhbGxiYWNrID8gY2FsbGJhY2sgOiBmdW5jdGlvbigpIHt9O1xuXG4gICAgYW5pbWl0KHRvYXN0LCB0aGlzLmRlZilcbiAgICAgIC5kZWZhdWx0KHsgb3BhY2l0eTogMCB9LCB7IG9wYWNpdHk6IDEgfSlcbiAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSlcbiAgICAgIC5wbGF5KCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdG9hc3RcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIGhpZGUodG9hc3QsIGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBjYWxsYmFjayA/IGNhbGxiYWNrIDogZnVuY3Rpb24oKSB7fTtcblxuICAgIGFuaW1pdCh0b2FzdCwgdGhpcy5kZWYpXG4gICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDEgfSwgeyBvcGFjaXR5OiAwIH0pXG4gICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0pXG4gICAgICAucGxheSgpO1xuICB9XG59XG4iLCJcbi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhbmltaXQgZnJvbSAnLi4vLi4vb25zL2FuaW1pdCc7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBpUGhvbmVYUGF0Y2ggZnJvbSAnLi4vLi4vb25zL2lwaG9uZXgtcGF0Y2gnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogQXNjZW5kIFRvYXN0IEFuaW1hdG9yLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBc2NlbmRUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3IoeyB0aW1pbmcgPSAnZWFzZScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjI1IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG5cbiAgICB0aGlzLm1lc3NhZ2VEZWxheSA9IHRoaXMuZHVyYXRpb24gKiAwLjQgKyB0aGlzLmRlbGF5OyAvLyBEZWxheSBtZXNzYWdlIG9wYWNpdHkgY2hhbmdlXG4gICAgaWYgKHBsYXRmb3JtLmlzQW5kcm9pZCgpKSB7XG4gICAgICB0aGlzLmFzY2Vuc2lvbiA9IDQ4OyAvLyBUb2FzdHMgYXJlIGFsd2F5cyAxIGxpbmVcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlQaG9uZVhQYXRjaC5pc0lQaG9uZVhQb3J0cmFpdFBhdGNoQWN0aXZlKCkpIHtcbiAgICAgICAgdGhpcy5hc2NlbnNpb24gPSA5ODsgLy8gNjQgKyAzNFxuICAgICAgfSBlbHNlIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYTGFuZHNjYXBlUGF0Y2hBY3RpdmUoKSkge1xuICAgICAgICB0aGlzLmFzY2Vuc2lvbiA9IDg1OyAvLyA2NCArIDIxXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFzY2Vuc2lvbiA9IDY0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICB0b2FzdCA9IHRvYXN0Ll90b2FzdDtcbiAgICB1dGlsLmdsb2JhbHMuZmFiT2Zmc2V0ID0gdGhpcy5hc2NlbnNpb247XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRvYXN0LCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMuYXNjZW5zaW9ufXB4LCAwKWAgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJyB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KSxcblxuICAgICAgYW5pbWl0KHRoaXMuX2dldEZhYnMoKSlcbiAgICAgICAgLndhaXQodGhpcy5kZWxheSlcbiAgICAgICAgLnF1ZXVlKHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgLSR7dGhpcy5hc2NlbnNpb259cHgsIDApIHNjYWxlKDEpYCB9LCB0aGlzLmRlZiksXG5cbiAgICAgIGFuaW1pdCh1dGlsLmFycmF5RnJvbSh0b2FzdC5jaGlsZHJlbiksIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdCh7IG9wYWNpdHk6IDAgfSwgeyBvcGFjaXR5OiAxIH0pXG4gICAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRvYXN0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKHRvYXN0LCBjYWxsYmFjaykge1xuICAgIHRvYXN0ID0gdG9hc3QuX3RvYXN0O1xuICAgIHV0aWwuZ2xvYmFscy5mYWJPZmZzZXQgPSAwO1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgIGFuaW1pdCh0b2FzdCwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknIH0sXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMuYXNjZW5zaW9ufXB4LCAwKWAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGFuaW1pdCh0aGlzLl9nZXRGYWJzKCksIHRoaXMuZGVmKVxuICAgICAgICAud2FpdCh0aGlzLmRlbGF5KVxuICAgICAgICAucXVldWUoeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAwLCAwKSBzY2FsZSgxKWAgfSwgdGhpcy5kZWYpLFxuXG4gICAgICBhbmltaXQodXRpbC5hcnJheUZyb20odG9hc3QuY2hpbGRyZW4pLCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoeyBvcGFjaXR5OiAxIH0sIHsgb3BhY2l0eTogMCB9KVxuICAgICk7XG4gIH1cblxuICBfZ2V0RmFicygpIHtcbiAgICByZXR1cm4gdXRpbC5hcnJheUZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnb25zLWZhYltwb3NpdGlvbn49Ym90dG9tXSwgb25zLXNwZWVkLWRpYWxbcG9zaXRpb25+PWJvdHRvbV0nKSkuZmlsdGVyKGZhYiA9PiBmYWIudmlzaWJsZSk7XG4gIH1cbn1cbiIsIlxuLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBpUGhvbmVYUGF0Y2ggZnJvbSAnLi4vLi4vb25zL2lwaG9uZXgtcGF0Y2gnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogTGlmdC1mYWRlIFRvYXN0IEFuaW1hdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpZnRUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3IoeyB0aW1pbmcgPSAnZWFzZScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjM1IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gICAgdGhpcy5ib2R5SGVpZ2h0ID0gZG9jdW1lbnQuYm9keS5jbGllbnRIZWlnaHQ7IC8vIGF2b2lkIEZvcmNlZCBTeW5jaHJvbm91cyBMYXlvdXRcbiAgICBpZiAoaVBob25lWFBhdGNoLmlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUoKSkge1xuICAgICAgdGhpcy5saWZ0QW1vdW50ID0gJ2NhbGMoMTAwJSArIDM0cHgpJztcbiAgICB9IGVsc2UgaWYgKGlQaG9uZVhQYXRjaC5pc0lQaG9uZVhMYW5kc2NhcGVQYXRjaEFjdGl2ZSgpKSB7XG4gICAgICB0aGlzLmxpZnRBbW91bnQgPSAnY2FsYygxMDAlICsgMjFweCknO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpZnRBbW91bnQgPSAnMTAwJSc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRvYXN0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBzaG93KHRvYXN0LCBjYWxsYmFjaykge1xuICAgIHRvYXN0ID0gdG9hc3QuX3RvYXN0O1xuXG4gICAgYW5pbWl0LnJ1bkFsbChcbiAgICAgIGFuaW1pdCh0b2FzdCwgdGhpcy5kZWYpXG4gICAgICAgIC5kZWZhdWx0KFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmxpZnRBbW91bnR9LCAwKWAsIG9wYWNpdHk6IDAgfSxcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9XG4gICAgICAgIClcbiAgICAgICAgLnF1ZXVlKGRvbmUgPT4ge1xuICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgaGlkZSh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICB0b2FzdCA9IHRvYXN0Ll90b2FzdDtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodG9hc3QsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmxpZnRBbW91bnR9LCAwKWAsIG9wYWNpdHk6IDAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjaygpO1xuICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgX3VwZGF0ZVBvc2l0aW9uKHRvYXN0KSB7XG4gICAgaWYgKHBhcnNlSW50KHRvYXN0LnN0eWxlLnRvcCwgMTApID09PSAwKSB7XG4gICAgICB0b2FzdC5zdHlsZS50b3AgPSB0b2FzdC5zdHlsZS5ib3R0b20gPSAnJztcbiAgICB9XG4gIH1cbn1cbiIsIlxuLypcbkNvcHlyaWdodCAyMDEzLTIwMTUgQVNJQUwgQ09SUE9SQVRJT05cblxuTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbnlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbllvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuXG4gICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuKi9cblxuaW1wb3J0IHV0aWwgZnJvbSAnLi4vLi4vb25zL3V0aWwnO1xuaW1wb3J0IGFuaW1pdCBmcm9tICcuLi8uLi9vbnMvYW5pbWl0JztcbmltcG9ydCBpUGhvbmVYUGF0Y2ggZnJvbSAnLi4vLi4vb25zL2lwaG9uZXgtcGF0Y2gnO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5cbi8qKlxuICogRmFsbC1mYWRlIFRvYXN0IEFuaW1hdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZhbGxUb2FzdEFuaW1hdG9yIGV4dGVuZHMgVG9hc3RBbmltYXRvciB7XG5cbiAgY29uc3RydWN0b3IoeyB0aW1pbmcgPSAnZWFzZScsIGRlbGF5ID0gMCwgZHVyYXRpb24gPSAwLjM1IH0gPSB7fSkge1xuICAgIHN1cGVyKHsgdGltaW5nLCBkZWxheSwgZHVyYXRpb24gfSk7XG4gICAgaWYgKGlQaG9uZVhQYXRjaC5pc0lQaG9uZVhQb3J0cmFpdFBhdGNoQWN0aXZlKCkpIHtcbiAgICAgIHRoaXMuZmFsbEFtb3VudCA9ICdjYWxjKC0xMDAlIC0gNDRweCknO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZhbGxBbW91bnQgPSAnLTEwMCUnO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0b2FzdFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgc2hvdyh0b2FzdCwgY2FsbGJhY2spIHtcbiAgICB0b2FzdCA9IHRvYXN0Ll90b2FzdDtcbiAgICB0aGlzLl91cGRhdGVQb3NpdGlvbih0b2FzdCk7XG5cbiAgICBhbmltaXQucnVuQWxsKFxuICAgICAgYW5pbWl0KHRvYXN0LCB0aGlzLmRlZilcbiAgICAgICAgLmRlZmF1bHQoXG4gICAgICAgICAgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgwLCAke3RoaXMuZmFsbEFtb3VudH0sIDApYCwgb3BhY2l0eTogMCB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlM2QoMCwgMCwgMCknLCBvcGFjaXR5OiAxIH1cbiAgICAgICAgKVxuICAgICAgICAucXVldWUoZG9uZSA9PiB7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRvYXN0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBoaWRlKHRvYXN0LCBjYWxsYmFjaykge1xuICAgIHRvYXN0ID0gdG9hc3QuX3RvYXN0O1xuICAgIHRoaXMuX3VwZGF0ZVBvc2l0aW9uKHRvYXN0KTtcblxuICAgIGFuaW1pdC5ydW5BbGwoXG4gICAgICBhbmltaXQodG9hc3QsIHRoaXMuZGVmKVxuICAgICAgICAuZGVmYXVsdChcbiAgICAgICAgICB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJywgb3BhY2l0eTogMSB9LFxuICAgICAgICAgIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlM2QoMCwgJHt0aGlzLmZhbGxBbW91bnR9LCAwKWAsIG9wYWNpdHk6IDAgfVxuICAgICAgICApXG4gICAgICAgIC5xdWV1ZShkb25lID0+IHtcbiAgICAgICAgICB0aGlzLl91cGRhdGVQb3NpdGlvbih0b2FzdCwgdHJ1ZSk7XG4gICAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIF91cGRhdGVQb3NpdGlvbih0b2FzdCwgY2xlYW5VcCkge1xuICAgIGxldCBjb3JyZWN0VG9wO1xuICAgIGlmIChpUGhvbmVYUGF0Y2guaXNJUGhvbmVYUG9ydHJhaXRQYXRjaEFjdGl2ZSgpKSB7XG4gICAgICBjb3JyZWN0VG9wID0gJzQ0cHgnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb3JyZWN0VG9wID0gJzAnO1xuICAgIH1cblxuICAgIGlmICh0b2FzdC5zdHlsZS50b3AgIT09IGNvcnJlY3RUb3ApIHtcbiAgICAgIHRvYXN0LnN0eWxlLnRvcCA9IGNvcnJlY3RUb3A7XG4gICAgICB0b2FzdC5zdHlsZS5ib3R0b20gPSAnaW5pdGlhbCc7XG4gICAgfVxuICB9XG59XG4iLCIvKlxuQ29weXJpZ2h0IDIwMTMtMjAxNSBBU0lBTCBDT1JQT1JBVElPTlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuXG4qL1xuXG5pbXBvcnQgb25zRWxlbWVudHMgZnJvbSAnLi4vLi4vb25zL2VsZW1lbnRzJztcbmltcG9ydCB1dGlsIGZyb20gJy4uLy4uL29ucy91dGlsJztcbmltcG9ydCBhdXRvU3R5bGUgZnJvbSAnLi4vLi4vb25zL2F1dG9zdHlsZSc7XG5pbXBvcnQgTW9kaWZpZXJVdGlsIGZyb20gJy4uLy4uL29ucy9pbnRlcm5hbC9tb2RpZmllci11dGlsJztcbmltcG9ydCBBbmltYXRvckZhY3RvcnkgZnJvbSAnLi4vLi4vb25zL2ludGVybmFsL2FuaW1hdG9yLWZhY3RvcnknO1xuaW1wb3J0IFRvYXN0QW5pbWF0b3IgZnJvbSAnLi9hbmltYXRvcic7XG5pbXBvcnQgRmFkZVRvYXN0QW5pbWF0b3IgZnJvbSAnLi9mYWRlLWFuaW1hdG9yJztcbmltcG9ydCBBc2NlbmRUb2FzdEFuaW1hdG9yIGZyb20gJy4vYXNjZW5kLWFuaW1hdG9yJztcbmltcG9ydCBMaWZ0VG9hc3RBbmltYXRvciBmcm9tICcuL2xpZnQtYW5pbWF0b3InO1xuaW1wb3J0IEZhbGxUb2FzdEFuaW1hdG9yIGZyb20gJy4vZmFsbC1hbmltYXRvcic7XG5pbXBvcnQgcGxhdGZvcm0gZnJvbSAnLi4vLi4vb25zL3BsYXRmb3JtJztcbmltcG9ydCBCYXNlRGlhbG9nRWxlbWVudCBmcm9tICcuLi9iYXNlL2Jhc2UtZGlhbG9nJztcbmltcG9ydCBjb250ZW50UmVhZHkgZnJvbSAnLi4vLi4vb25zL2NvbnRlbnQtcmVhZHknO1xuXG5jb25zdCBzY2hlbWUgPSB7XG4gICcudG9hc3QnOiAndG9hc3QtLSonLFxuICAnLnRvYXN0X19tZXNzYWdlJzogJ3RvYXN0LS0qX19tZXNzYWdlJyxcbiAgJy50b2FzdF9fYnV0dG9uJzogJ3RvYXN0LS0qX19idXR0b24nXG59O1xuXG5jb25zdCBkZWZhdWx0Q2xhc3NOYW1lID0gJ3RvYXN0JztcblxuY29uc3QgX2FuaW1hdG9yRGljdCA9IHtcbiAgJ2RlZmF1bHQnOiBwbGF0Zm9ybS5pc0FuZHJvaWQoKSA/IEFzY2VuZFRvYXN0QW5pbWF0b3IgOiBMaWZ0VG9hc3RBbmltYXRvcixcbiAgJ2ZhZGUnOiBGYWRlVG9hc3RBbmltYXRvcixcbiAgJ2FzY2VuZCc6IEFzY2VuZFRvYXN0QW5pbWF0b3IsXG4gICdsaWZ0JzogTGlmdFRvYXN0QW5pbWF0b3IsXG4gICdmYWxsJzogRmFsbFRvYXN0QW5pbWF0b3IsXG4gICdub25lJzogVG9hc3RBbmltYXRvclxufTtcblxuLyoqXG4gKiBAZWxlbWVudCBvbnMtdG9hc3RcbiAqIEBjYXRlZ29yeSBkaWFsb2dcbiAqIEBkZXNjcmlwdGlvblxuICogICBbZW5dXG4gKiAgICAgVGhlIFRvYXN0IG9yIFNuYWNrYmFyIGNvbXBvbmVudCBpcyB1c2VmdWwgZm9yIGRpc3BsYXlpbmcgZGlzbWlzc2FibGUgaW5mb3JtYXRpb24gb3Igc2ltcGxlIGFjdGlvbnMgYXQgKG5vcm1hbGx5KSB0aGUgYm90dG9tIG9mIHRoZSBwYWdlLlxuICpcbiAqICAgICBUaGlzIGNvbXBvbmVudCBkb2VzIG5vdCBibG9jayB1c2VyIGlucHV0LCBhbGxvd2luZyB0aGUgYXBwIHRvIGNvbnRpbnVlIGl0cyBmbG93LiBGb3Igc2ltcGxlIHRvYXN0cywgY29uc2lkZXIgYG9ucy5ub3RpZmljYXRpb24udG9hc3RgIGluc3RlYWQuXG4gKiAgIFsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3RvYXN0XG4gKiBAc2VlYWxzbyBvbnMtYWxlcnQtZGlhbG9nXG4gKiAgIFtlbl1UaGUgYDxvbnMtYWxlcnQtZGlhbG9nPmAgY29tcG9uZW50IGlzIHByZWZlcnJlZCBmb3IgZGlzcGxheWluZyB1bmRpc21pc3NhYmxlIGluZm9ybWF0aW9uLlsvZW5dXG4gKiAgIFtqYV1bL2phXVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb2FzdEVsZW1lbnQgZXh0ZW5kcyBCYXNlRGlhbG9nRWxlbWVudCB7XG5cbiAgLyoqXG4gICAqIEBhdHRyaWJ1dGUgYW5pbWF0aW9uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZWZhdWx0IGRlZmF1bHRcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dVGhlIGFuaW1hdGlvbiB1c2VkIHdoZW4gc2hvd2luZyBhbmQgaGlkaW5nIHRoZSB0b2FzdC4gQ2FuIGJlIGVpdGhlciBgXCJkZWZhdWx0XCJgLCBgXCJhc2NlbmRcImAgKEFuZHJvaWQpLCBgXCJsaWZ0XCJgIChpT1MpLCBgXCJmYWxsXCJgLCBgXCJmYWRlXCJgIG9yIGBcIm5vbmVcImAuWy9lbl1cbiAgICogIFtqYV1bL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQGF0dHJpYnV0ZSBhbmltYXRpb24tb3B0aW9uc1xuICAgKiBAdHlwZSB7RXhwcmVzc2lvbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIHRpbWluZyBhbmQgZGVsYXkgd2l0aCBhbiBvYmplY3QgbGl0ZXJhbC4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAxLCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIHRpbWluZywgZGVsYXnjgpLjgqrjg5bjgrjjgqfjgq/jg4jjg6rjg4bjg6njg6vjgafmjIflrprjgZfjgb7jgZnjgIJlLmcuIDxjb2RlPntkdXJhdGlvbjogMC4yLCBkZWxheTogMSwgdGltaW5nOiAnZWFzZS1pbid9PC9jb2RlPlsvamFdXG4gICAqL1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9kZWZhdWx0REJCID0gbnVsbDtcbiAgICBjb250ZW50UmVhZHkodGhpcywgKCkgPT4gdGhpcy5fY29tcGlsZSgpKTtcbiAgfVxuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiBzY2hlbWU7XG4gIH1cblxuICBnZXQgX3RvYXN0KCkge1xuICAgIHJldHVybiB1dGlsLmZpbmRDaGlsZCh0aGlzLCBgLiR7ZGVmYXVsdENsYXNzTmFtZX1gKTtcbiAgfVxuXG4gIF91cGRhdGVBbmltYXRvckZhY3RvcnkoKSB7XG4gICAgLy8gUmVzZXQgcG9zaXRpb24gc3R5bGVcbiAgICB0aGlzLl90b2FzdCAmJiAodGhpcy5fdG9hc3Quc3R5bGUudG9wID0gdGhpcy5fdG9hc3Quc3R5bGUuYm90dG9tID0gJycpO1xuXG4gICAgcmV0dXJuIG5ldyBBbmltYXRvckZhY3Rvcnkoe1xuICAgICAgYW5pbWF0b3JzOiBfYW5pbWF0b3JEaWN0LFxuICAgICAgYmFzZUNsYXNzOiBUb2FzdEFuaW1hdG9yLFxuICAgICAgYmFzZUNsYXNzTmFtZTogJ1RvYXN0QW5pbWF0b3InLFxuICAgICAgZGVmYXVsdEFuaW1hdGlvbjogdGhpcy5nZXRBdHRyaWJ1dGUoJ2FuaW1hdGlvbicpXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IG9uRGV2aWNlQmFja0J1dHRvblxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dQmFjay1idXR0b24gaGFuZGxlci5bL2VuXVxuICAgKiAgIFtqYV3jg5Djg4Pjgq/jg5zjgr/jg7Pjg4/jg7Pjg4njg6njgIJbL2phXVxuICAgKi9cblxuICBfY29tcGlsZSgpIHtcbiAgICBhdXRvU3R5bGUucHJlcGFyZSh0aGlzKTtcblxuICAgIHRoaXMuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnN0eWxlLnpJbmRleCA9IDEwMDAwOyAvLyBMb3dlciB0aGFuIGRpYWxvZ3NcblxuICAgIGNvbnN0IG1lc3NhZ2VDbGFzc05hbWUgPSAndG9hc3RfX21lc3NhZ2UnO1xuICAgIGNvbnN0IGJ1dHRvbkNsYXNzTmFtZSA9ICd0b2FzdF9fYnV0dG9uJztcblxuICAgIGxldCB0b2FzdCA9IHV0aWwuZmluZENoaWxkKHRoaXMsIGAuJHtkZWZhdWx0Q2xhc3NOYW1lfWApO1xuICAgIGlmICghdG9hc3QpIHtcbiAgICAgIHRvYXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICB0b2FzdC5jbGFzc0xpc3QuYWRkKGRlZmF1bHRDbGFzc05hbWUpO1xuICAgICAgd2hpbGUgKHRoaXMuY2hpbGROb2Rlc1swXSkge1xuICAgICAgICB0b2FzdC5hcHBlbmRDaGlsZCh0aGlzLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBidXR0b24gPSB1dGlsLmZpbmRDaGlsZCh0b2FzdCwgYC4ke2J1dHRvbkNsYXNzTmFtZX1gKTtcbiAgICBpZiAoIWJ1dHRvbikge1xuICAgICAgYnV0dG9uID0gdXRpbC5maW5kQ2hpbGQodG9hc3QsIGUgPT4gdXRpbC5tYXRjaChlLCAnLmJ1dHRvbicpIHx8IHV0aWwubWF0Y2goZSwgJ2J1dHRvbicpKTtcbiAgICAgIGlmIChidXR0b24pIHtcbiAgICAgICAgYnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ2J1dHRvbicpO1xuICAgICAgICBidXR0b24uY2xhc3NMaXN0LmFkZChidXR0b25DbGFzc05hbWUpO1xuICAgICAgICB0b2FzdC5hcHBlbmRDaGlsZChidXR0b24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghdXRpbC5maW5kQ2hpbGQodG9hc3QsIGAuJHttZXNzYWdlQ2xhc3NOYW1lfWApKSB7XG4gICAgICBsZXQgbWVzc2FnZSA9IHV0aWwuZmluZENoaWxkKHRvYXN0LCAnLm1lc3NhZ2UnKTtcbiAgICAgIGlmICghbWVzc2FnZSkge1xuICAgICAgICBtZXNzYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGZvciAobGV0IGkgPSB0b2FzdC5jaGlsZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKHRvYXN0LmNoaWxkTm9kZXNbaV0gIT09IGJ1dHRvbikge1xuICAgICAgICAgICAgbWVzc2FnZS5pbnNlcnRCZWZvcmUodG9hc3QuY2hpbGROb2Rlc1tpXSwgbWVzc2FnZS5maXJzdENoaWxkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG1lc3NhZ2UuY2xhc3NMaXN0LmFkZChtZXNzYWdlQ2xhc3NOYW1lKTtcblxuICAgICAgdG9hc3QuaW5zZXJ0QmVmb3JlKG1lc3NhZ2UsIHRvYXN0LmZpcnN0Q2hpbGQpO1xuICAgIH1cblxuICAgIGlmICh0b2FzdC5wYXJlbnROb2RlICE9PSB0aGlzKSB7XG4gICAgICB0aGlzLmFwcGVuZENoaWxkKHRvYXN0KTtcbiAgICB9XG5cbiAgICBNb2RpZmllclV0aWwuaW5pdE1vZGlmaWVyKHRoaXMsIHRoaXMuX3NjaGVtZSk7XG4gIH1cblxuICAvKipcbiAgICogQHByb3BlcnR5IHZpc2libGVcbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dV2hldGhlciB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIG9yIG5vdC5bL2VuXVxuICAgKiAgIFtqYV3opoHntKDjgYzopovjgYjjgovloLTlkIjjgatgdHJ1ZWDjgIJbL2phXVxuICAgKi9cblxuICAvKipcbiAgICogQG1ldGhvZCBzaG93XG4gICAqIEBzaWduYXR1cmUgc2hvdyhbb3B0aW9uc10pXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAgICogICBbZW5dUGFyYW1ldGVyIG9iamVjdC5bL2VuXVxuICAgKiAgIFtqYV3jgqrjg5fjgrfjg6fjg7PjgpLmjIflrprjgZnjgovjgqrjg5bjgrjjgqfjgq/jg4jjgIJbL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uXVxuICAgKiAgIFtlbl1BbmltYXRpb24gbmFtZS4gQXZhaWxhYmxlIGFuaW1hdGlvbnMgYXJlIGBcImRlZmF1bHRcImAsIGBcImFzY2VuZFwiYCAoQW5kcm9pZCksIGBcImxpZnRcImAgKGlPUyksIGBcImZhbGxcImAsIGBcImZhZGVcImAgb3IgYFwibm9uZVwiYC5bL2VuXVxuICAgKiAgIFtqYV1bL2phXVxuICAgKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMuYW5pbWF0aW9uT3B0aW9uc11cbiAgICogICBbZW5dU3BlY2lmeSB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24sIGRlbGF5IGFuZCB0aW1pbmcuIEUuZy4gYHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31gLlsvZW5dXG4gICAqICAgW2phXeOCouODi+ODoeODvOOCt+ODp+ODs+aZguOBrmR1cmF0aW9uLCBkZWxheSwgdGltaW5n44KS5oyH5a6a44GX44G+44GZ44CCZS5nLiB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9Wy9qYV1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVNob3cgdGhlIGVsZW1lbnQuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogICBbZW5dUmVzb2x2ZXMgdG8gdGhlIGRpc3BsYXllZCBlbGVtZW50Wy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgdG9nZ2xlXG4gICAqIEBzaWduYXR1cmUgdG9nZ2xlKFtvcHRpb25zXSlcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgIFtlbl1QYXJhbWV0ZXIgb2JqZWN0LlsvZW5dXG4gICAqICAgW2phXeOCquODl+OCt+ODp+ODs+OCkuaMh+WumuOBmeOCi+OCquODluOCuOOCp+OCr+ODiOOAglsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25dXG4gICAqICAgW2VuXUFuaW1hdGlvbiBuYW1lLiBBdmFpbGFibGUgYW5pbWF0aW9ucyBhcmUgYFwiZGVmYXVsdFwiYCwgYFwiYXNjZW5kXCJgIChBbmRyb2lkKSwgYFwibGlmdFwiYCAoaU9TKSwgYFwiZmFsbFwiYCwgYFwiZmFkZVwiYCBvciBgXCJub25lXCJgLlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRpb25PcHRpb25zXVxuICAgKiAgIFtlbl1TcGVjaWZ5IHRoZSBhbmltYXRpb24ncyBkdXJhdGlvbiwgZGVsYXkgYW5kIHRpbWluZy4gRS5nLiBge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfWAuWy9lbl1cbiAgICogICBbamFd44Ki44OL44Oh44O844K344On44Oz5pmC44GuZHVyYXRpb24sIGRlbGF5LCB0aW1pbmfjgpLmjIflrprjgZfjgb7jgZnjgIJlLmcuIHtkdXJhdGlvbjogMC4yLCBkZWxheTogMC40LCB0aW1pbmc6ICdlYXNlLWluJ31bL2phXVxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogICBbZW5dVG9nZ2xlIHRvYXN0IHZpc2liaWxpdHkuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZXRob2QgaGlkZVxuICAgKiBAc2lnbmF0dXJlIGhpZGUoW29wdGlvbnNdKVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqICAgW2VuXVBhcmFtZXRlciBvYmplY3QuWy9lbl1cbiAgICogICBbamFd44Kq44OX44K344On44Oz44KS5oyH5a6a44GZ44KL44Kq44OW44K444Kn44Kv44OI44CCWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbl1cbiAgICogICBbZW5dQW5pbWF0aW9uIG5hbWUuIEF2YWlsYWJsZSBhbmltYXRpb25zIGFyZSBgXCJkZWZhdWx0XCJgLCBgXCJhc2NlbmRcImAgKEFuZHJvaWQpLCBgXCJsaWZ0XCJgIChpT1MpLCBgXCJmYWxsXCJgLCBgXCJmYWRlXCJgIG9yIGBcIm5vbmVcImAuWy9lbl1cbiAgICogICBbamFdWy9qYV1cbiAgICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmFuaW1hdGlvbk9wdGlvbnNdXG4gICAqICAgW2VuXVNwZWNpZnkgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLCBkZWxheSBhbmQgdGltaW5nLiBFLmcuIGB7ZHVyYXRpb246IDAuMiwgZGVsYXk6IDAuNCwgdGltaW5nOiAnZWFzZS1pbid9YC5bL2VuXVxuICAgKiAgIFtqYV3jgqLjg4vjg6Hjg7zjgrfjg6fjg7PmmYLjga5kdXJhdGlvbiwgZGVsYXksIHRpbWluZ+OCkuaMh+WumuOBl+OBvuOBmeOAgmUuZy4ge2R1cmF0aW9uOiAwLjIsIGRlbGF5OiAwLjQsIHRpbWluZzogJ2Vhc2UtaW4nfVsvamFdXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1IaWRlIHRvYXN0LlsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqICAgW2VuXVJlc29sdmVzIHRvIHRoZSBoaWRkZW4gZWxlbWVudFsvZW5dXG4gICAqICAgW2phXVsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBBbmltYXRvclxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyQW5pbWF0b3IobmFtZSwgQW5pbWF0b3IpIHtcbiAgICBpZiAoIShBbmltYXRvci5wcm90b3R5cGUgaW5zdGFuY2VvZiBUb2FzdEFuaW1hdG9yKSkge1xuICAgICAgdXRpbC50aHJvdygnXCJBbmltYXRvclwiIHBhcmFtIG11c3QgaW5oZXJpdCBPbnNUb2FzdEVsZW1lbnQuVG9hc3RBbmltYXRvcicpO1xuICAgIH1cbiAgICBfYW5pbWF0b3JEaWN0W25hbWVdID0gQW5pbWF0b3I7XG4gIH1cblxuICBzdGF0aWMgZ2V0IGFuaW1hdG9ycygpIHtcbiAgICByZXR1cm4gX2FuaW1hdG9yRGljdDtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgVG9hc3RBbmltYXRvcigpIHtcbiAgICByZXR1cm4gVG9hc3RBbmltYXRvcjtcbiAgfVxufVxuXG5vbnNFbGVtZW50cy5Ub2FzdCA9IFRvYXN0RWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXRvYXN0JywgVG9hc3RFbGVtZW50KTtcbiIsIi8qXG5Db3B5cmlnaHQgMjAxMy0yMDE1IEFTSUFMIENPUlBPUkFUSU9OXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cblVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbmRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbldJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxubGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG5cbiovXG5cbmltcG9ydCBvbnNFbGVtZW50cyBmcm9tICcuLi9vbnMvZWxlbWVudHMnO1xuaW1wb3J0IEJhc2VCdXR0b25FbGVtZW50IGZyb20gJy4vYmFzZS9iYXNlLWJ1dHRvbic7XG5cbi8qKlxuICogQGVsZW1lbnQgb25zLXRvb2xiYXItYnV0dG9uXG4gKiBAY2F0ZWdvcnkgcGFnZVxuICogQG1vZGlmaWVyIG1hdGVyaWFsXG4gKiAgIFtlbl1NYXRlcmlhbCBEZXNpZ24gdG9vbGJhciBidXR0b24uWy9lbl1cbiAqICAgW2phXVsvamFdXG4gKiBAbW9kaWZpZXIgb3V0bGluZVxuICogICBbZW5dQSBidXR0b24gd2l0aCBhbiBvdXRsaW5lLlsvZW5dXG4gKiAgIFtqYV3jgqLjgqbjg4jjg6njgqTjg7PjgpLjgoLjgaPjgZ/jg5zjgr/jg7PjgpLooajnpLrjgZfjgb7jgZnjgIJbL2phXVxuICogQGRlc2NyaXB0aW9uXG4gKiAgIFtlbl1CdXR0b24gY29tcG9uZW50IGZvciBvbnMtdG9vbGJhciBhbmQgb25zLWJvdHRvbS10b29sYmFyLlsvZW5dXG4gKiAgIFtqYV1vbnMtdG9vbGJhcuOBguOCi+OBhOOBr29ucy1ib3R0b20tdG9vbGJhcuOBq+ioree9ruOBp+OBjeOCi+ODnOOCv+ODs+eUqOOCs+ODs+ODneODvOODjeODs+ODiOOBp+OBmeOAglsvamFdXG4gKiBAY29kZXBlbiBhSG1HTFxuICogQHR1dG9yaWFsIHZhbmlsbGEvUmVmZXJlbmNlL3BhZ2VcbiAqIEBndWlkZSBjb21waWxhdGlvbi5odG1sI3Rvb2xiYXItY29tcGlsYXRpb25cbiAqICAgW2VuXUFkZGluZyBhIHRvb2xiYXJbL2VuXVxuICogICBbamFd44OE44O844Or44OQ44O844Gu6L+95YqgWy9qYV1cbiAqIEBzZWVhbHNvIG9ucy10b29sYmFyXG4gKiAgIFtlbl1UaGUgYDxvbnMtdG9vbGJhcj5gIGNvbXBvbmVudCBkaXNwbGF5cyBhIG5hdmlnYXRpb24gYmFyIGF0IHRoZSB0b3Agb2YgYSBwYWdlLlsvZW5dXG4gKiAgIFtqYV1vbnMtdG9vbGJhcuOCs+ODs+ODneODvOODjeODs+ODiFsvamFdXG4gKiBAc2VlYWxzbyBvbnMtYmFjay1idXR0b25cbiAqICAgW2VuXVRoZSBgPG9ucy1iYWNrLWJ1dHRvbj5gIGRpc3BsYXlzIGEgYmFjayBidXR0b24gaW4gdGhlIG5hdmlnYXRpb24gYmFyLlsvZW5dXG4gKiAgIFtqYV1vbnMtYmFjay1idXR0b27jgrPjg7Pjg53jg7zjg43jg7Pjg4hbL2phXVxuICogQGV4YW1wbGVcbiAqIDxvbnMtdG9vbGJhcj5cbiAqICAgPGRpdiBjbGFzcz1cImxlZnRcIj5cbiAqICAgICA8b25zLXRvb2xiYXItYnV0dG9uPlxuICogICAgICAgQnV0dG9uXG4gKiAgICAgPC9vbnMtdG9vbGJhci1idXR0b24+XG4gKiAgIDwvZGl2PlxuICogICA8ZGl2IGNsYXNzPVwiY2VudGVyXCI+XG4gKiAgICAgVGl0bGVcbiAqICAgPC9kaXY+XG4gKiAgIDxkaXYgY2xhc3M9XCJyaWdodFwiPlxuICogICAgIDxvbnMtdG9vbGJhci1idXR0b24+XG4gKiAgICAgICA8b25zLWljb24gaWNvbj1cImlvbi1uYXZpY29uXCIgc2l6ZT1cIjI4cHhcIj48L29ucy1pY29uPlxuICogICAgIDwvb25zLXRvb2xiYXItYnV0dG9uPlxuICogICA8L2Rpdj5cbiAqIDwvb25zLXRvb2xiYXI+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRvb2xiYXJCdXR0b25FbGVtZW50IGV4dGVuZHMgQmFzZUJ1dHRvbkVsZW1lbnQge1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIG1vZGlmaWVyXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1UaGUgYXBwZWFyYW5jZSBvZiB0aGUgYnV0dG9uLlsvZW5dXG4gICAqICAgW2phXeODnOOCv+ODs+OBruihqOePvuOCkuaMh+WumuOBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGljb25cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICBbZW5dQ3JlYXRlcyBhbiBgb25zLWljb25gIGNvbXBvbmVudCB3aXRoIHRoaXMgc3RyaW5nLlsvZW5dXG4gICAqICBbamFdYG9ucy1pY29uYOOCs+ODs+ODneODvOODjeODs+ODiOOCkuaCquaAp+OBl+OBvuOBmeOAglsvamFdXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAYXR0cmlidXRlIGRpc2FibGVkXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiAgIFtlbl1TcGVjaWZ5IGlmIGJ1dHRvbiBzaG91bGQgYmUgZGlzYWJsZWQuWy9lbl1cbiAgICogICBbamFd44Oc44K/44Oz44KS54Sh5Yq55YyW44GZ44KL5aC05ZCI44Gv5oyH5a6a44GX44Gm44GP44Gg44GV44GE44CCWy9qYV1cbiAgICovXG5cbiAgLyoqXG4gICAqIEBwcm9wZXJ0eSBkaXNhYmxlZFxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICogQGRlc2NyaXB0aW9uXG4gICAqICAgW2VuXVdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgZGlzYWJsZWQgb3Igbm90LlsvZW5dXG4gICAqICAgW2phXeeEoeWKueWMluOBleOCjOOBpuOBhOOCi+WgtOWQiOOBq2B0cnVlYOOAglsvamFdXG4gICAqL1xuXG4gIGdldCBfc2NoZW1lKCkge1xuICAgIHJldHVybiB7ICcnOiAndG9vbGJhci1idXR0b24tLSonIH07XG4gIH1cblxuICBnZXQgX2RlZmF1bHRDbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICd0b29sYmFyLWJ1dHRvbic7XG4gIH1cblxuICBnZXQgX3JpcHBsZU9wdCgpIHtcbiAgICByZXR1cm4gW3RoaXMsIHVuZGVmaW5lZCwgeyBjZW50ZXI6ICcnLCAnc2l6ZSc6ICdjb250YWluJywgJ2JhY2tncm91bmQnOiAndHJhbnNwYXJlbnQnIH1dO1xuICB9XG59XG5cbm9uc0VsZW1lbnRzLlRvb2xiYXJCdXR0b24gPSBUb29sYmFyQnV0dG9uRWxlbWVudDtcbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnb25zLXRvb2xiYXItYnV0dG9uJywgVG9vbGJhckJ1dHRvbkVsZW1lbnQpO1xuIiwiaW1wb3J0IG9ucyBmcm9tICcuL29ucyc7IC8vIEFkZCBvbnMgaW50ZXJuYWxzXG5pbXBvcnQgc2V0dXAgZnJvbSAnLi9zZXR1cCc7IC8vIEFkZCBwb2x5ZmlsbHNcblxuLy8gQWRkIGFuZCByZWdpc3RlciBDdXN0b20gRWxlbWVudHNcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtdGVtcGxhdGUnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1pZic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWFjdGlvbi1zaGVldCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWFjdGlvbi1zaGVldC1idXR0b24nO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1hbGVydC1kaWFsb2cnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1hbGVydC1kaWFsb2ctYnV0dG9uJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtYmFjay1idXR0b24nO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1ib3R0b20tdG9vbGJhcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWJ1dHRvbic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWNhcmQnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1jYXJvdXNlbC1pdGVtJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtY2Fyb3VzZWwnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1jb2wnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1kaWFsb2cnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1mYWInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1nZXN0dXJlLWRldGVjdG9yJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtaWNvbic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWxhenktcmVwZWF0JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbGlzdC1oZWFkZXInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1saXN0LXRpdGxlJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbGlzdC1pdGVtJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbGlzdCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLWlucHV0JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtY2hlY2tib3gnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1yYWRpbyc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNlYXJjaC1pbnB1dCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLW1vZGFsJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtbmF2aWdhdG9yJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtcGFnZSc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXBvcG92ZXInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1wcm9ncmVzcy1iYXInO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1wcm9ncmVzcy1jaXJjdWxhcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXB1bGwtaG9vayc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXJhbmdlJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtcmlwcGxlJztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtcm93JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtc2VnbWVudCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNlbGVjdCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNwZWVkLWRpYWwtaXRlbSc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNwZWVkLWRpYWwnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1zcGxpdHRlci1jb250ZW50JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtc3BsaXR0ZXItbWFzayc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXNwbGl0dGVyLXNpZGUnO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy1zcGxpdHRlcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXN3aXRjaCc7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXRhYic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXRhYmJhcic7XG5pbXBvcnQgJy4vZWxlbWVudHMvb25zLXRvYXN0JztcbmltcG9ydCAnLi9lbGVtZW50cy9vbnMtdG9vbGJhci1idXR0b24nO1xuaW1wb3J0ICcuL2VsZW1lbnRzL29ucy10b29sYmFyJztcblxuc2V0dXAob25zKTsgLy8gU2V0dXAgaW5pdGlhbCBsaXN0ZW5lcnNcbndpbmRvdy5fc3VwZXJTZWNyZXRPbnMgPSBvbnM7XG5cbmV4cG9ydCBkZWZhdWx0IG9ucztcbiJdLCJuYW1lcyI6WyJwcmVmaXgiLCJzdHlsZXMiLCJ3aW5kb3ciLCJnZXRDb21wdXRlZFN0eWxlIiwiZG9jdW1lbnQiLCJkb2N1bWVudEVsZW1lbnQiLCJBcnJheSIsInByb3RvdHlwZSIsInNsaWNlIiwiY2FsbCIsImpvaW4iLCJtYXRjaCIsIk9MaW5rIiwibmFtZSIsInV0aWwiLCJoeXBoZW5hdGUiLCJzdHlsZXIiLCJlbGVtZW50Iiwic3R5bGUiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsIndhcm4iLCJjbGVhciIsImNsZWFybGlzdCIsInNwbGl0IiwicmVkdWNlIiwiciIsInMiLCJjb25jYXQiLCJpIiwibGVuZ3RoIiwic29tZSIsImluZGV4T2YiLCJwdXNoIiwiZ2V0QXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwiTmF0aXZlSFRNTEVsZW1lbnQiLCJIVE1MRWxlbWVudCIsIlBsYXRmb3JtIiwiX3NlbGVjdGVkUGxhdGZvcm0iLCJfaWdub3JlUGxhdGZvcm1TZWxlY3QiLCJwbGF0Zm9ybSIsInRyaW0iLCJ0b0xvd2VyQ2FzZSIsImZuIiwicmVzdWx0IiwicmVhZHlTdGF0ZSIsIkVycm9yIiwiY29yZG92YSIsInBob25lZ2FwIiwiUGhvbmVHYXAiLCJ0ZXN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiaXNJUGhvbmUiLCJzY3JlZW4iLCJ3aWR0aCIsImhlaWdodCIsImZvcmNlQWN0dWFsUGxhdGZvcm0iLCJfZ2V0U2VsZWN0ZWRQbGF0Zm9ybSIsImRldmljZSIsInBhcnNlSW50IiwidmVyc2lvbiIsInZlciIsInJlcGxhY2UiLCJ1YSIsImlzSU9TIiwic3RhbmRhbG9uZSIsImx0ZTkiLCJ3ZWJraXQiLCJtZXNzYWdlSGFuZGxlcnMiLCJpbmRleGVkREIiLCJpc0lPU1NhZmFyaSIsImlzV0tXZWJWaWV3Iiwib3BlcmEiLCJJbnN0YWxsVHJpZ2dlciIsIk9iamVjdCIsInRvU3RyaW5nIiwicCIsInNhZmFyaSIsInB1c2hOb3RpZmljYXRpb24iLCJjaHJvbWUiLCJkb2N1bWVudE1vZGUiLCJpc0FuZHJvaWQiLCJpc1dQIiwiaXNJUGFkIiwiaXNJUG9kIiwiZXJyb3IiLCJ0aHJvdyIsIm1lc3NhZ2UiLCJwYWdlQXR0cmlidXRlRXhwcmVzc2lvbiIsInZhbHVlIiwib3ZlcndyaXRlIiwiX3ZhcmlhYmxlcyIsImhhc093blByb3BlcnR5IiwicGFydCIsImMiLCJpbkludGVycG9sYXRpb24iLCJjdXJyZW50SW5kZXgiLCJ0b2tlbnMiLCJjaGFyQXQiLCJ0b2tlbiIsInN1YnN0cmluZyIsInJlIiwidmFyaWFibGUiLCJnZXRWYXJpYWJsZSIsInJ2IiwibWFwIiwiX3JlcGxhY2VUb2tlbiIsImJpbmQiLCJleHByZXNzaW9uIiwiX3BhcnNlUGFydCIsIl9yZXBsYWNlVG9rZW5zIiwiX3BhcnNlRXhwcmVzc2lvbiIsImRlZmluZVZhcmlhYmxlIiwiZ2V0TW9iaWxlT1MiLCJnZXRJT1NEZXZpY2UiLCJpc1dlYlZpZXciLCJpbnRlcm5hbCIsImNvbmZpZyIsIm51bGxFbGVtZW50IiwiY3JlYXRlRWxlbWVudCIsImlzRW5hYmxlZEF1dG9TdGF0dXNCYXJGaWxsIiwiYXV0b1N0YXR1c0JhckZpbGwiLCJub3JtYWxpemVQYWdlSFRNTCIsImh0bWwiLCJ3YWl0RE9NQ29udGVudExvYWRlZCIsIndyYXBwZWRDYWxsYmFjayIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJhZGRFdmVudExpc3RlbmVyIiwiY2FsbGJhY2siLCJvblJlYWR5Iiwic2hvdWxkRmlsbFN0YXR1c0JhciIsImlzSU9TN2Fib3ZlIiwiaXNJUGhvbmVYIiwiYm9keSIsInF1ZXJ5U2VsZWN0b3IiLCJ0ZW1wbGF0ZVN0b3JlIiwiX3N0b3JhZ2UiLCJ0ZW1wbGF0ZSIsImUiLCJ0YXJnZXQiLCJub2RlTmFtZSIsInNldCIsInRlbXBsYXRlSWQiLCJyZWdpc3RlciIsInF1ZXJ5IiwidGVtcGxhdGVzIiwicXVlcnlTZWxlY3RvckFsbCIsInRleHRDb250ZW50IiwiY29udGVudCIsImdldFRlbXBsYXRlSFRNTEFzeW5jIiwicGFnZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiY2FjaGUiLCJnZXQiLCJEb2N1bWVudEZyYWdtZW50IiwibG9jYWwiLCJnZXRFbGVtZW50QnlJZCIsInhociIsIlhNTEh0dHBSZXF1ZXN0Iiwib3BlbiIsIm9ubG9hZCIsInJlc3BvbnNlVGV4dCIsInN0YXR1cyIsImZyYWdtZW50IiwiY3JlYXRlRnJhZ21lbnQiLCJhcnJheUZyb20iLCJzY3JpcHQiLCJ0eXBlIiwiZWwiLCJhcHBlbmRDaGlsZCIsImNyZWF0ZVRleHROb2RlIiwidGV4dCIsImlubmVySFRNTCIsInBhcmVudE5vZGUiLCJyZXBsYWNlQ2hpbGQiLCJvbmVycm9yIiwic2VuZCIsImdldFBhZ2VIVE1MQXN5bmMiLCJwYWdlcyIsImV2YWx1YXRlIiwiZ2V0UGFnZSIsImNhdGNoIiwic2hpZnQiLCJBbmltYXRvckZhY3RvcnkiLCJvcHRzIiwiX2FuaW1hdG9ycyIsImFuaW1hdG9ycyIsIl9iYXNlQ2xhc3MiLCJiYXNlQ2xhc3MiLCJfYmFzZUNsYXNzTmFtZSIsImJhc2VDbGFzc05hbWUiLCJfYW5pbWF0aW9uIiwiZGVmYXVsdEFuaW1hdGlvbiIsIl9hbmltYXRpb25PcHRpb25zIiwiZGVmYXVsdEFuaW1hdGlvbk9wdGlvbnMiLCJvcHRpb25zIiwiZGVmYXVsdEFuaW1hdG9yIiwiYW5pbWF0b3IiLCJhbmltYXRpb24iLCJBbmltYXRvciIsImFuaW1hdGlvbk9wdHMiLCJleHRlbmQiLCJhbmltYXRpb25PcHRpb25zIiwiYW5pbWF0aW9uc0Rpc2FibGVkIiwiZHVyYXRpb24iLCJkZWxheSIsImpzb25TdHJpbmciLCJhbmltYXRpb25PcHRpb25zUGFyc2UiLCJhdXRvU3R5bGVFbmFibGVkIiwibW9kaWZpZXJzTWFwIiwicGxhdGZvcm1zIiwiYW5kcm9pZCIsImVsZW1lbnROYW1lIiwidGFnTmFtZSIsImhhc01vZGlmaWVyIiwib2xkTW9kaWZpZXIiLCJuZXdNb2RpZmllciIsInVuc2hpZnQiLCJzZXRBdHRyaWJ1dGUiLCJlbGVtZW50cyIsImhhc0F0dHJpYnV0ZSIsImlvcyIsInJlbW92ZU1vZGlmaWVyIiwiYWRkTW9kaWZpZXIiLCJ1bmxvY2tlZCIsImdldFBsYXRmb3JtIiwiZm9yY2UiLCJtb2JpbGVPUyIsIm9uc1BsYXRmb3JtIiwicHJlcGFyZSIsIm1hcE1vZGlmaWVyIiwibW9kaWZpZXIiLCJtIiwicmVzdG9yZU1vZGlmaWVyIiwiTW9kaWZpZXJVdGlsIiwibGFzdCIsImN1cnJlbnQiLCJtYWtlRGljdCIsInJlbW92ZWQiLCJhZGRlZCIsImRpY3QiLCJkaWZmIiwiY2xhc3NMaXN0Iiwia2xhc3MiLCJhZGQiLCJrIiwicmVtb3ZlIiwic2NoZW1lIiwidGFyZ2V0RWxlbWVudHMiLCJzZWxlY3RvciIsImZpbHRlciIsImZpbmRQYXJlbnQiLCJ0YXJnZXRFbGVtZW50IiwicGFyZW50IiwiYXBwbHlEaWZmVG9DbGFzc0xpc3QiLCJhcHBseURpZmZUb0VsZW1lbnQiLCJtb2RpZmllclRva2VuIiwiaW5kZXgiLCJzcGxpY2UiLCJfZG9tQ29udGVudExvYWRlZCIsIl9yZWFkeSIsIl9vbkRPTUNvbnRlbnRMb2FkZWQiLCJIYW5kbGVyUmVwb3NpdG9yeSIsImhhbmRsZXIiLCJkYXRhc2V0IiwiZGV2aWNlQmFja0J1dHRvbkhhbmRsZXJJZCIsImlkIiwiX2dlbklkIiwiX3N0b3JlIiwidW5kZWZpbmVkIiwiRGV2aWNlQmFja0J1dHRvbkRpc3BhdGNoZXIiLCJfaXNFbmFibGVkIiwiX2JvdW5kQ2FsbGJhY2siLCJfY2FsbGJhY2siLCJhZGRCYWNrQnV0dG9uTGlzdGVuZXIiLCJyZW1vdmVCYWNrQnV0dG9uTGlzdGVuZXIiLCJldmVudCIsImNyZWF0ZUV2ZW50IiwiaW5pdEV2ZW50IiwiZGlzcGF0Y2hFdmVudCIsIl9kaXNwYXRjaERldmljZUJhY2tCdXR0b25FdmVudCIsIkZ1bmN0aW9uIiwiX2VsZW1lbnQiLCJlbmFibGUiLCJ0cmVlIiwiX2NhcHR1cmVUcmVlIiwiX2ZpbmRIYW5kbGVyTGVhZkVsZW1lbnQiLCJjcmVhdGVUcmVlIiwiYXBwbHkiLCJhcnJheU9mIiwiY2hpbGRyZW4iLCJjaGlsZEVsZW1lbnQiLCJkaXNwbGF5IiwiX2lzU2hvd24iLCJoYXMiLCJzdWJUcmVlIiwiZmluZCIsIm5vZGUiLCJjaGlsZE5vZGUiLCJsZWZ0IiwicmlnaHQiLCJsZWZ0WiIsInpJbmRleCIsInJpZ2h0WiIsImlzTmFOIiwiZGJiRGlzcGF0Y2hlciIsImRldmljZUJhY2tCdXR0b25EaXNwYXRjaGVyIiwic3RhcnRzV2l0aCIsInN1YnN0ciIsImVuZHNXaXRoIiwidW53cmFwIiwiaXNPYmplY3RTdHJpbmciLCJpc0FycmF5U3RyaW5nIiwiaXNRdW90ZWRTdHJpbmciLCJzdHJpbmciLCJvcmlnaW5hbFN0cmluZyIsInByb2Nlc3NUb2tlbiIsInBhcnNlT2JqZWN0IiwicGFyc2VBcnJheSIsIm5leHRUb2tlbiIsImxpbWl0IiwiY2hhckNvZGVBdCIsIm5lc3RlZE9iamVjdCIsImlzVmFsaWRLZXkiLCJvYmplY3QiLCJyZWFkaW5nS2V5IiwicHJldmlvdXNUb2tlbiIsImFycmF5IiwicGFyc2UiLCJlcnJvclByZWZpeCIsImdsb2JhbHMiLCJfcnVuT25BY3R1YWxQbGF0Zm9ybSIsImFjdHVhbE1vYmlsZU9TIiwiaXNVSVdlYlZpZXciLCJkZWZpbmVQcm9wZXJ0eSIsInN1cHBvcnRzUGFzc2l2ZSIsIm9wdCIsImlzR0QiLCJjYXB0dXJlIiwicHJlcGFyZVF1ZXJ5IiwibWF0Y2hlcyIsIndlYmtpdE1hdGNoZXNTZWxlY3RvciIsIm1vek1hdGNoZXNTZWxlY3RvciIsIm1zTWF0Y2hlc1NlbGVjdG9yIiwiZmluZENoaWxkIiwiY2hpbGROb2RlcyIsIm5vZGVUeXBlIiwiTm9kZSIsIkVMRU1FTlRfTk9ERSIsInVudGlsIiwiaXNBdHRhY2hlZCIsImNvbnRhaW5zIiwiaGFzQW55Q29tcG9uZW50QXNQYXJlbnQiLCJnZXRBbGxDaGlsZE5vZGVzIiwiZnJvbSIsImNoaWxkRWwiLCJpc1BhZ2VDb250cm9sIiwicHJvcGFnYXRlQWN0aW9uIiwiYWN0aW9uIiwiY2hpbGQiLCJjYW1lbGl6ZSIsImwiLCJ0b1VwcGVyQ2FzZSIsImNyZWF0ZSIsImNsYXNzTmFtZSIsIndyYXBwZXIiLCJpbXBvcnROb2RlIiwiZHN0IiwiYXJncyIsImoiLCJhcnJheUxpa2UiLCJwYXJzZUpTT05PYmplY3RTYWZlbHkiLCJmYWlsU2FmZSIsIkpTT04iLCJmaW5kRnJvbVBhdGgiLCJwYXRoIiwiZ2V0VG9wUGFnZSIsImNvbnRhaW5lciIsInRvcFBhZ2UiLCJmaW5kVG9vbGJhclBhZ2UiLCJfY2FuQW5pbWF0ZVRvb2xiYXIiLCJfY29udGVudEVsZW1lbnQiLCJuZXh0UGFnZSIsInRyaWdnZXJFbGVtZW50RXZlbnQiLCJldmVudE5hbWUiLCJkZXRhaWwiLCJDdXN0b21FdmVudCIsIm1vZGlmaWVyTmFtZSIsIlJlZ0V4cCIsImF1dG9TdHlsZSIsImZvcmNlQXV0b1N0eWxlIiwibmV3TW9kaWZpZXJzIiwidG9nZ2xlTW9kaWZpZXIiLCJ0b2dnbGUiLCJyZXN0b3JlQ2xhc3MiLCJkZWZhdWx0Q2xhc3MiLCJyZWZyZXNoIiwidXBkYXRlUGFyZW50UG9zaXRpb24iLCJfcGFyZW50VXBkYXRlZCIsInBhcmVudEVsZW1lbnQiLCJnZXRQcm9wZXJ0eVZhbHVlIiwicG9zaXRpb24iLCJ0b2dnbGVBdHRyaWJ1dGUiLCJiaW5kTGlzdGVuZXJzIiwibGlzdGVuZXJOYW1lcyIsImJvdW5kTmFtZSIsImVhY2giLCJvYmoiLCJmIiwidXBkYXRlUmlwcGxlIiwiaGFzUmlwcGxlIiwiYXR0cnMiLCJyaXBwbGVFbGVtZW50IiwiaW5zZXJ0QmVmb3JlIiwiZmlyc3RDaGlsZCIsImlzSW50ZWdlciIsImlzRmluaXRlIiwiTWF0aCIsImZsb29yIiwiZGVmZXIiLCJkZWZlcnJlZCIsInByb21pc2UiLCJ3YXJuaW5nc0Rpc2FibGVkIiwidGhyb3dBYnN0cmFjdCIsInRocm93TWVtYmVyIiwidGhyb3dQYWdlTG9hZGVyIiwidGhyb3dBbmltYXRvciIsInByZXZlbnQiLCJjYW5jZWxhYmxlIiwicHJldmVudERlZmF1bHQiLCJpb3NQcmV2ZW50U2Nyb2xsIiwiY2xlYW4iLCJvZmYiLCJvbiIsImlvc1BhZ2VTY3JvbGxGaXgiLCJmb3JjZVVJV2ViVmlld1Njcm9sbEZpeCIsImlvc01hc2tTY3JvbGxGaXgiLCJpc1ZhbGlkR2VzdHVyZSIsImdlc3R1cmUiLCJkaXN0YW5jZSIsImRlbHRhVGltZSIsImNoZWNrTWlzc2luZ0ltcG9ydCIsImVsZW1lbnROYW1lcyIsIm9uc0VsZW1lbnRzIiwiVElNRU9VVF9SQVRJTyIsImNhcGl0YWxpemUiLCJzdHIiLCJidWlsZFRyYW5zaXRpb25WYWx1ZSIsInBhcmFtcyIsInByb3BlcnR5IiwidGltaW5nIiwicHJvcHMiLCJwcm9wIiwib25jZU9uVHJhbnNpdGlvbkVuZCIsInN0b3BQcm9wYWdhdGlvbiIsInJlbW92ZUxpc3RlbmVycyIsIl90cmFuc2l0aW9uRW5kRXZlbnRzIiwidmVuZG9yUHJlZml4IiwiX2Nzc1Byb3BlcnR5RGljdCIsImEiLCJ6IiwidXBwZXIiLCJoYXNDc3NQcm9wZXJ0eSIsInByZSIsImZvcmNlTGF5b3V0QXRPbmNlIiwiYmF0Y2hJbW1lZGlhdGUiLCJvZmZzZXRIZWlnaHQiLCJjYWxsYmFja3MiLCJjb25jcmVhdGVDYWxsYmFja3MiLCJiYXRjaEFuaW1hdGlvbkZyYW1lIiwicmFmIiwicmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwid2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwibW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwib1JlcXVlc3RBbmltYXRpb25GcmFtZSIsIm1zUmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwidHJhbnNpdGlvblByb3BlcnR5TmFtZSIsIkFuaW1pdCIsImRlZmF1bHRzIiwidHJhbnNpdGlvblF1ZXVlIiwibGFzdFN0eWxlQXR0cmlidXRlRGljdCIsImRvbmUiLCJzdGFydEFuaW1hdGlvbiIsInRvIiwic3RlcCIsImNzcyIsInNhdmVTdHlsZSIsInF1ZXVlIiwid2FpdCIsInJlc3RvcmVTdHlsZSIsInRyYW5zaXRpb24iLCJUcmFuc2l0aW9uIiwiYnVpbGQiLCJzZWNvbmRzIiwic2VsZiIsInRyYW5zaXRpb25OYW1lIiwidHJhbnNpdGlvblZhbHVlIiwidGltZW91dElkIiwiY2xlYXJUcmFuc2l0aW9uIiwic2V0VGltZW91dCIsImxlbiIsInJlc2V0IiwiX2RlcXVldWVUcmFuc2l0aW9uIiwiX2N1cnJlbnRUcmFuc2l0aW9uIiwiY2FsbGVkIiwicnVuQWxsIiwiYXJndW1lbnRzIiwicGxheSIsImNyZWF0ZUFjdHVhbENzc1Byb3BzIiwidGltZW91dCIsInByZWZpeGVkIiwiRXZlbnQiLCJVdGlscyIsIkRldGVjdGlvbiIsIlBvaW50ZXJFdmVudCIsIkdlc3R1cmVEZXRlY3RvciIsIkluc3RhbmNlIiwiRE9DVU1FTlQiLCJIQVNfUE9JTlRFUkVWRU5UUyIsInBvaW50ZXJFbmFibGVkIiwibXNQb2ludGVyRW5hYmxlZCIsIkhBU19UT1VDSEVWRU5UUyIsIklTX01PQklMRSIsIk5PX01PVVNFRVZFTlRTIiwiQ0FMQ1VMQVRFX0lOVEVSVkFMIiwiRVZFTlRfVFlQRVMiLCJESVJFQ1RJT05fRE9XTiIsIkRJUkVDVElPTl9MRUZUIiwiRElSRUNUSU9OX1VQIiwiRElSRUNUSU9OX1JJR0hUIiwiUE9JTlRFUl9NT1VTRSIsIlBPSU5URVJfVE9VQ0giLCJQT0lOVEVSX1BFTiIsIkVWRU5UX1NUQVJUIiwiRVZFTlRfTU9WRSIsIkVWRU5UX0VORCIsIkVWRU5UX1JFTEVBU0UiLCJFVkVOVF9UT1VDSCIsIlJFQURZIiwicGx1Z2lucyIsImdlc3R1cmVzIiwic2V0dXAiLCJkZXRlcm1pbmVFdmVudFR5cGVzIiwib25Ub3VjaCIsImRldGVjdCIsInV0aWxzIiwiZGVzdCIsInNyYyIsIm1lcmdlIiwiaXRlcmF0b3IiLCJjb250ZXh0IiwiaW5TdHIiLCJpbkFycmF5IiwiZGVlcCIsImV2ZXJ5IiwidG9BcnJheSIsImhhc1BhcmVudCIsImdldENlbnRlciIsInRvdWNoZXMiLCJwYWdlWCIsInBhZ2VZIiwiY2xpZW50WCIsImNsaWVudFkiLCJtaW4iLCJtYXgiLCJ0b3VjaCIsImdldFZlbG9jaXR5IiwiZGVsdGFYIiwiZGVsdGFZIiwiYWJzIiwiZ2V0QW5nbGUiLCJ0b3VjaDEiLCJ0b3VjaDIiLCJ4IiwieSIsImF0YW4yIiwiUEkiLCJnZXREaXJlY3Rpb24iLCJnZXREaXN0YW5jZSIsInNxcnQiLCJnZXRTY2FsZSIsInN0YXJ0IiwiZW5kIiwiZ2V0Um90YXRpb24iLCJpc1ZlcnRpY2FsIiwiZGlyZWN0aW9uIiwic2V0UHJlZml4ZWRDc3MiLCJwcmVmaXhlcyIsInRvQ2FtZWxDYXNlIiwidG9nZ2xlQmVoYXZpb3IiLCJmYWxzZUZuIiwidXNlclNlbGVjdCIsIm9uc2VsZWN0c3RhcnQiLCJ1c2VyRHJhZyIsIm9uZHJhZ3N0YXJ0IiwiaG9vayIsInR5cGVzIiwiZXZlbnRUeXBlIiwib25Ub3VjaEhhbmRsZXIiLCJldiIsInNyY1R5cGUiLCJpc1BvaW50ZXIiLCJpc01vdXNlIiwidHJpZ2dlclR5cGUiLCJwcmV2ZW50TW91c2VFdmVudHMiLCJidXR0b24iLCJzaG91bGREZXRlY3QiLCJidXR0b25zIiwibWF0Y2hUeXBlIiwidXBkYXRlUG9pbnRlciIsImRvRGV0ZWN0IiwidG91Y2hMaXN0IiwiZ2V0VG91Y2hMaXN0IiwidG91Y2hMaXN0TGVuZ3RoIiwidHJpZ2dlckNoYW5nZSIsInRyaWdnZXIiLCJjaGFuZ2VkTGVuZ3RoIiwiY2hhbmdlZFRvdWNoZXMiLCJzdGFydGVkIiwiZXZEYXRhIiwiY29sbGVjdEV2ZW50RGF0YSIsImlkZW50aWZpZXJzIiwiaWRlbnRpZmllciIsInBvaW50ZXJUeXBlIiwiRGF0ZSIsIm5vdyIsInNyY0V2ZW50IiwicHJldmVudE1hbmlwdWxhdGlvbiIsInN0b3BEZXRlY3QiLCJ0b3VjaGxpc3QiLCJwb2ludGVycyIsInBvaW50ZXIiLCJwb2ludGVyRXZlbnQiLCJwb2ludGVySWQiLCJwdCIsIk1TUE9JTlRFUl9UWVBFX01PVVNFIiwiTVNQT0lOVEVSX1RZUEVfVE9VQ0giLCJNU1BPSU5URVJfVFlQRV9QRU4iLCJyZXNldExpc3QiLCJkZXRlY3Rpb24iLCJzdGFydERldGVjdCIsImluc3QiLCJldmVudERhdGEiLCJzdG9wcGVkIiwiZXh0ZW5kRXZlbnREYXRhIiwiaW5zdE9wdGlvbnMiLCJ0cmlnZ2VyR2VzdHVyZSIsImVuYWJsZWQiLCJsYXN0RXZlbnQiLCJwcmV2aW91cyIsImdldENhbGN1bGF0ZWREYXRhIiwiY2VudGVyIiwiY3VyIiwicmVjYWxjIiwiY2FsY0V2IiwibGFzdENhbGNFdmVudCIsImNhbGNEYXRhIiwibGFzdENhbGNEYXRhIiwidGltZVN0YW1wIiwiZnV0dXJlQ2FsY0V2ZW50IiwidmVsb2NpdHkiLCJhbmdsZSIsInZlbG9jaXR5WCIsInZlbG9jaXR5WSIsImludGVyaW1BbmdsZSIsImludGVyaW1EaXJlY3Rpb24iLCJzdGFydEV2Iiwic3RhcnRFdmVudCIsImxhc3RFdiIsInNvcnQiLCJiIiwibGlzdGVuZXJPcHRpb25zIiwicGFzc2l2ZSIsImJlaGF2aW9yIiwiZXZlbnRTdGFydEhhbmRsZXIiLCJldmVudEhhbmRsZXJzIiwib25FdmVudCIsIm9mZkV2ZW50IiwidHJpZ2dlckV2ZW50Iiwic3RhdGUiLCJkaXNwb3NlIiwiZWgiLCJ0cmlnZ2VyZWQiLCJkcmFnR2VzdHVyZSIsImRyYWdNYXhUb3VjaGVzIiwiZHJhZ01pbkRpc3RhbmNlIiwic3RhcnRDZW50ZXIiLCJkcmFnRGlzdGFuY2VDb3JyZWN0aW9uIiwiZmFjdG9yIiwiZHJhZ0xvY2tUb0F4aXMiLCJkcmFnTG9ja01pbkRpc3RhbmNlIiwibGFzdERpcmVjdGlvbiIsImRyYWdCbG9ja1ZlcnRpY2FsIiwiZHJhZ0Jsb2NrSG9yaXpvbnRhbCIsIkRyYWciLCJHZXN0dXJlIiwicmVsZWFzZUdlc3R1cmUiLCJ0aW1lciIsImhvbGRHZXN0dXJlIiwiaG9sZFRpbWVvdXQiLCJob2xkVGhyZXNob2xkIiwiSG9sZCIsIlJlbGVhc2UiLCJJbmZpbml0eSIsIlN3aXBlIiwic3dpcGVHZXN0dXJlIiwic3dpcGVNaW5Ub3VjaGVzIiwic3dpcGVNYXhUb3VjaGVzIiwic3dpcGVWZWxvY2l0eVgiLCJzd2lwZVZlbG9jaXR5WSIsImhhc01vdmVkIiwidGFwR2VzdHVyZSIsInByZXYiLCJzaW5jZVByZXYiLCJkaWREb3VibGVUYXAiLCJ0YXBNYXhEaXN0YW5jZSIsInRhcE1heFRpbWUiLCJkb3VibGVUYXBJbnRlcnZhbCIsImRvdWJsZVRhcERpc3RhbmNlIiwidGFwQWx3YXlzIiwiVGFwIiwiVG91Y2giLCJ0b3VjaEdlc3R1cmUiLCJwcmV2ZW50TW91c2UiLCJ0cmFuc2Zvcm1HZXN0dXJlIiwic2NhbGVUaHJlc2hvbGQiLCJzY2FsZSIsInJvdGF0aW9uVGhyZXNob2xkIiwicm90YXRpb24iLCJ0cmFuc2Zvcm1NaW5TY2FsZSIsInRyYW5zZm9ybU1pblJvdGF0aW9uIiwiVHJhbnNmb3JtIiwicmVhZHlNYXAiLCJxdWV1ZU1hcCIsImlzQ29udGVudFJlYWR5Iiwic2V0Q29udGVudFJlYWR5IiwiYWRkQ2FsbGJhY2siLCJjb25zdW1lUXVldWUiLCJkZWxldGUiLCJjb250ZW50UmVhZHkiLCJXZWFrTWFwIiwib2JzZXJ2ZXIiLCJNdXRhdGlvbk9ic2VydmVyIiwib2JzZXJ2ZSIsImNoaWxkTGlzdCIsImNoYXJhY3RlckRhdGEiLCJUb2FzdFF1ZXVlIiwidGhlbiIsIl9zZXRBdHRyaWJ1dGVzIiwiX25vcm1hbGl6ZUFyZ3VtZW50cyIsIm1lc3NhZ2VIVE1MIiwiYnV0dG9uTGFiZWxzIiwiYnV0dG9uTGFiZWwiLCJpc0FycmF5IiwicGFyYW0iLCJub3RpZmljYXRpb24iLCJfY3JlYXRlQWxlcnREaWFsb2ciLCJpbnB1dFN0cmluZyIsImlzUHJvbXB0IiwiaW5wdXRUeXBlIiwicGxhY2Vob2xkZXIiLCJkZWZhdWx0VmFsdWUiLCJsYWJlbCIsInByaW1hcnlCdXR0b25JbmRleCIsIl9kZXN0cm95RGlhbG9nIiwiZGlhbG9nIiwib25EaWFsb2dDYW5jZWwiLCJkZXN0cm95IiwibWFza0NvbG9yIiwidGl0bGUiLCJzdWJtaXRPbkVudGVyIiwiaW5wdXQiLCJvbmtleXByZXNzIiwia2V5Q29kZSIsImhpZGUiLCJyZXNvbHZlVmFsdWUiLCJmb290ZXIiLCJidXR0b25FbGVtZW50Iiwib25jbGljayIsImNvbXBpbGUiLCJzaG93IiwiYXV0b2ZvY3VzIiwic3RyTGVuZ3RoIiwiZm9jdXMiLCJzZXRTZWxlY3Rpb25SYW5nZSIsImFsZXJ0IiwiY29uZmlybSIsInByb21wdCIsInRvYXN0IiwiZmluaXNoIiwiX3RvYXN0IiwiY2hlY2tPcHRpb25zIiwiZXJyIiwiaW5zdGFuY2VPZiIsImNiIiwiZCIsImFjdGlvblNoZWV0IiwiY2xhc3MiLCJjcmVhdGVEb2N1bWVudEZyYWdtZW50IiwiaXRlbSIsImJ1dHRvbk9wdGlvbnMiLCJkZXN0cnVjdGl2ZSIsImljb24iLCJNaWNyb0V2ZW50IiwiZmN0IiwiX2V2ZW50cyIsIl9mY3QiLCJtaXhpbiIsImRlc3RPYmplY3QiLCJfaXNQb3J0cmFpdCIsImlzUG9ydHJhaXQiLCJfb25PcmllbnRhdGlvbkNoYW5nZSIsIl9vblJlc2l6ZSIsImlubmVySGVpZ2h0IiwiaW5uZXJXaWR0aCIsIl9pbnN0YWxsSXNQb3J0cmFpdEltcGxlbWVudGF0aW9uIiwiZW1pdCIsIm9yaWVudGF0aW9uIiwibkl0ZXIiLCJpbnRlcnZhbCIsInNldEludGVydmFsIiwidyIsImgiLCJfaW5pdCIsIm1vZGlmaWVycyIsInNvZnR3YXJlS2V5Ym9hcmQiLCJfdmlzaWJsZSIsIm9uU2hvdyIsIm9uSGlkZSIsImJpbmRFdmVudHMiLCJLZXlib2FyZCIsIm9uc2hvdyIsIm9uaGlkZSIsInZpc2libGUiLCJpc1Zpc2libGUiLCJub1BsdWdpbkVycm9yIiwiZ2VuZXJhdGVJZCIsIkRvb3JMb2NrIiwiX2xvY2tMaXN0IiwiX3dhaXRMaXN0IiwiX2xvZyIsImxvZyIsInVubG9jayIsIl91bmxvY2siLCJfdHJ5VG9GcmVlV2FpdExpc3QiLCJpc0xvY2tlZCIsImxvYWRQYWdlIiwicGFnZUVsZW1lbnQiLCJ1bmxvYWRQYWdlIiwiX2Rlc3Ryb3kiLCJQYWdlTG9hZGVyIiwibG9hZGVyIiwidW5sb2FkZXIiLCJfbG9hZGVyIiwiX3VubG9hZGVyIiwiRWxlbWVudCIsImRlZmF1bHRQYWdlTG9hZGVyIiwiaW5zdGFudFBhZ2VMb2FkZXIiLCJvbnMiLCJzZWxlY3QiLCJsb2NhdGlvbiIsInNlYXJjaCIsIndhaXREZXZpY2VSZWFkeSIsInJlYWR5RXJyb3IiLCJhZnRlciIsImlzUmVhZHkiLCJfcmVhZHlMb2NrIiwicmVhZHkiLCJ3YWl0VW5sb2NrIiwic2V0RGVmYXVsdERldmljZUJhY2tCdXR0b25MaXN0ZW5lciIsImxpc3RlbmVyIiwiX2RlZmF1bHREZXZpY2VCYWNrQnV0dG9uSGFuZGxlciIsInNldExpc3RlbmVyIiwiZGlzYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyIiwiZGlzYWJsZSIsImVuYWJsZURldmljZUJhY2tCdXR0b25IYW5kbGVyIiwiZmlyZURldmljZUJhY2tCdXR0b25FdmVudCIsImVuYWJsZUF1dG9TdGF0dXNCYXJGaWxsIiwiZGlzYWJsZUF1dG9TdGF0dXNCYXJGaWxsIiwibW9ja1N0YXR1c0JhciIsIm1vY2siLCJkaXNhYmxlQW5pbWF0aW9ucyIsImVuYWJsZUFuaW1hdGlvbnMiLCJfZGlzYWJsZVdhcm5pbmdzIiwiX2VuYWJsZVdhcm5pbmdzIiwiZGlzYWJsZUF1dG9TdHlsaW5nIiwiZW5hYmxlQXV0b1N0eWxpbmciLCJkaXNhYmxlSWNvbkF1dG9QcmVmaXgiLCJJY29uIiwic2V0QXV0b1ByZWZpeCIsImZvcmNlUGxhdGZvcm1TdHlsaW5nIiwibmV3UGxhdGZvcm0iLCJfdXRpbCIsIl9wbGF0Zm9ybVVwZGF0ZSIsIl91cGRhdGVQb3NpdGlvbiIsInByZWxvYWQiLCJhbGwiLCJhcHBlbmQiLCJsaW5rIiwiY3JlYXRlUG9wb3ZlciIsImNyZWF0ZURpYWxvZyIsImNyZWF0ZUFsZXJ0RGlhbG9nIiwib3BlbkFjdGlvblNoZWV0IiwicmVzb2x2ZUxvYWRpbmdQbGFjZWhvbGRlciIsIl9yZXNvbHZlTG9hZGluZ1BsYWNlaG9sZGVyIiwiX3NldHVwTG9hZGluZ1BsYWNlSG9sZGVycyIsInJlbW92ZUNoaWxkIiwidW5sb2NrRGV2aWNlUmVhZHkiLCJsb2NrIiwiZ2V0Q1MiLCJjdXJyZW50U2NyaXB0Iiwic2NyaXB0cyIsImdldFNjcmlwdFBhZ2UiLCJGYXN0Q2xpY2siLCJsYXllciIsIm9sZE9uQ2xpY2siLCJ0cmFja2luZ0NsaWNrIiwidHJhY2tpbmdDbGlja1N0YXJ0IiwidG91Y2hTdGFydFgiLCJ0b3VjaFN0YXJ0WSIsImxhc3RUb3VjaElkZW50aWZpZXIiLCJ0b3VjaEJvdW5kYXJ5IiwidGFwRGVsYXkiLCJ0YXBUaW1lb3V0Iiwibm90TmVlZGVkIiwibWV0aG9kIiwibWV0aG9kcyIsImRldmljZUlzQW5kcm9pZCIsIm9uTW91c2UiLCJvbkNsaWNrIiwib25Ub3VjaFN0YXJ0Iiwib25Ub3VjaE1vdmUiLCJvblRvdWNoRW5kIiwib25Ub3VjaENhbmNlbCIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsInJtdiIsImhpamFja2VkIiwiYWR2IiwicHJvcGFnYXRpb25TdG9wcGVkIiwiZGV2aWNlSXNXaW5kb3dzUGhvbmUiLCJkZXZpY2VJc0lPUyIsImRldmljZUlzSU9TNCIsImRldmljZUlzSU9TV2l0aEJhZFRhcmdldCIsImRldmljZUlzQmxhY2tCZXJyeTEwIiwidGV4dEZpZWxkcyIsIm5lZWRzQ2xpY2siLCJkaXNhYmxlZCIsIm5lZWRzRm9jdXMiLCJyZWFkT25seSIsInNlbmRDbGljayIsImNsaWNrRXZlbnQiLCJhY3RpdmVFbGVtZW50IiwiYmx1ciIsImluaXRNb3VzZUV2ZW50IiwiZGV0ZXJtaW5lRXZlbnRUeXBlIiwic2NyZWVuWCIsInNjcmVlblkiLCJmb3J3YXJkZWRUb3VjaEV2ZW50IiwidXBkYXRlU2Nyb2xsUGFyZW50Iiwic2Nyb2xsUGFyZW50IiwiZmFzdENsaWNrU2Nyb2xsUGFyZW50Iiwic2Nyb2xsSGVpZ2h0IiwiZmFzdENsaWNrTGFzdFNjcm9sbFRvcCIsInNjcm9sbFRvcCIsImdldFRhcmdldEVsZW1lbnRGcm9tRXZlbnRUYXJnZXQiLCJldmVudFRhcmdldCIsIlRFWFRfTk9ERSIsImlzVGV4dEZpZWxkIiwidGFyZ2V0VG91Y2hlcyIsImlzQ29udGVudEVkaXRhYmxlIiwibGFzdENsaWNrVGltZSIsInRvdWNoSGFzTW92ZWQiLCJib3VuZGFyeSIsImZpbmRDb250cm9sIiwibGFiZWxFbGVtZW50IiwiY29udHJvbCIsImh0bWxGb3IiLCJmb3JFbGVtZW50IiwidGFyZ2V0VGFnTmFtZSIsImNhbmNlbE5leHRDbGljayIsImVsZW1lbnRGcm9tUG9pbnQiLCJwYWdlWE9mZnNldCIsInBhZ2VZT2Zmc2V0IiwidG9wIiwicGVybWl0dGVkIiwibWV0YVZpZXdwb3J0IiwiY2hyb21lVmVyc2lvbiIsImJsYWNrYmVycnlWZXJzaW9uIiwiZmlyZWZveFZlcnNpb24iLCJvbnRvdWNoc3RhcnQiLCJleGVjIiwic2Nyb2xsV2lkdGgiLCJvdXRlcldpZHRoIiwibXNUb3VjaEFjdGlvbiIsInRvdWNoQWN0aW9uIiwiYXR0YWNoIiwiZGVmaW5lIiwiYmFiZWxIZWxwZXJzLnR5cGVvZiIsImFtZCIsIm1vZHVsZSIsImV4cG9ydHMiLCJjdXN0b21FbGVtZW50cyIsImZvcmNlUG9seWZpbGwiLCJnbG9iYWwiLCJfX2ciLCJjb3JlIiwiX19lIiwiaXQiLCJpc09iamVjdCIsIlR5cGVFcnJvciIsInJlcXVpcmUkJDAiLCJpcyIsInJlcXVpcmUkJDEiLCJyZXF1aXJlJCQyIiwiUyIsInZhbCIsInZhbHVlT2YiLCJkUCIsIk8iLCJQIiwiQXR0cmlidXRlcyIsInRvUHJpbWl0aXZlIiwiSUU4X0RPTV9ERUZJTkUiLCJiaXRtYXAiLCJjcmVhdGVEZXNjIiwicHgiLCJyYW5kb20iLCJTUkMiLCJUT19TVFJJTkciLCIkdG9TdHJpbmciLCJUUEwiLCJpbnNwZWN0U291cmNlIiwic2FmZSIsImlzRnVuY3Rpb24iLCJTdHJpbmciLCJ0aGF0IiwiUFJPVE9UWVBFIiwiJGV4cG9ydCIsInNvdXJjZSIsIklTX0ZPUkNFRCIsIkYiLCJJU19HTE9CQUwiLCJHIiwiSVNfU1RBVElDIiwiSVNfUFJPVE8iLCJJU19CSU5EIiwiQiIsImV4cFByb3RvIiwib3duIiwib3V0IiwiZXhwIiwiY3R4IiwicmVkZWZpbmUiLCJVIiwiVyIsIlIiLCJwcm9wZXJ0eUlzRW51bWVyYWJsZSIsImNvZiIsIklPYmplY3QiLCJkZWZpbmVkIiwiZ09QRCIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInRvSU9iamVjdCIsInBJRSIsImNoZWNrIiwicHJvdG8iLCJzZXRQcm90b3R5cGVPZiIsImJ1Z2d5IiwiX19wcm90b19fIiwiU0hBUkVEIiwic3RvcmUiLCJTeW1ib2wiLCJVU0VfU1lNQk9MIiwiJGV4cG9ydHMiLCJ1aWQiLCJUQUciLCJBUkciLCJ0cnlHZXQiLCJUIiwiY2FsbGVlIiwiY2xhc3NvZiIsImNlaWwiLCJwb3MiLCJ0b0ludGVnZXIiLCJJU19JTkNMVURFUyIsIiR0aGlzIiwiZnJvbUluZGV4IiwidG9MZW5ndGgiLCJ0b0Fic29sdXRlSW5kZXgiLCJzaGFyZWQiLCJhcnJheUluZGV4T2YiLCJJRV9QUk9UTyIsIm5hbWVzIiwiJGtleXMiLCJlbnVtQnVnS2V5cyIsImRlZmluZVByb3BlcnRpZXMiLCJQcm9wZXJ0aWVzIiwiZ2V0S2V5cyIsIkVtcHR5IiwiY3JlYXRlRGljdCIsImlmcmFtZSIsImx0IiwiZ3QiLCJpZnJhbWVEb2N1bWVudCIsImNvbnRlbnRXaW5kb3ciLCJ3cml0ZSIsImNsb3NlIiwiYW5PYmplY3QiLCJkUHMiLCJkZWYiLCJ0YWciLCJzdGF0IiwiY29uZmlndXJhYmxlIiwiSXRlcmF0b3JQcm90b3R5cGUiLCJDb25zdHJ1Y3RvciIsIk5BTUUiLCJuZXh0IiwiZGVzY3JpcHRvciIsIk9iamVjdFByb3RvIiwiZ2V0UHJvdG90eXBlT2YiLCJ0b09iamVjdCIsImNvbnN0cnVjdG9yIiwiSVRFUkFUT1IiLCJCVUdHWSIsIkZGX0lURVJBVE9SIiwiS0VZUyIsIlZBTFVFUyIsInJldHVyblRoaXMiLCJCYXNlIiwiREVGQVVMVCIsIklTX1NFVCIsIkZPUkNFRCIsImdldE1ldGhvZCIsImtpbmQiLCJ2YWx1ZXMiLCJlbnRyaWVzIiwiREVGX1ZBTFVFUyIsIlZBTFVFU19CVUciLCIkbmF0aXZlIiwiJGRlZmF1bHQiLCIkZW50cmllcyIsIiRhbnlOYXRpdmUiLCJMSUJSQVJZIiwiJGF0IiwiaXRlcmF0ZWQiLCJfdCIsIl9pIiwicG9pbnQiLCJVTlNDT1BBQkxFUyIsIkFycmF5UHJvdG8iLCJfayIsIkl0ZXJhdG9ycyIsIkFyZ3VtZW50cyIsImFkZFRvVW5zY29wYWJsZXMiLCJ3a3MiLCJUT19TVFJJTkdfVEFHIiwiQXJyYXlWYWx1ZXMiLCJET01JdGVyYWJsZXMiLCJjb2xsZWN0aW9ucyIsImV4cGxpY2l0IiwiQ29sbGVjdGlvbiIsIiRpdGVyYXRvcnMiLCJmb3JiaWRkZW5GaWVsZCIsInJldCIsImdldEl0ZXJhdG9yTWV0aG9kIiwiQlJFQUsiLCJSRVRVUk4iLCJpdGVyYWJsZSIsIml0ZXJGbiIsImdldEl0ZXJGbiIsImlzQXJyYXlJdGVyIiwiU1BFQ0lFUyIsIktFWSIsIkMiLCJERVNDUklQVE9SUyIsIk1FVEEiLCJzZXREZXNjIiwiaXNFeHRlbnNpYmxlIiwiRlJFRVpFIiwicHJldmVudEV4dGVuc2lvbnMiLCJzZXRNZXRhIiwiZmFzdEtleSIsImdldFdlYWsiLCJvbkZyZWV6ZSIsIm1ldGEiLCJORUVEIiwiVFlQRSIsIlNJWkUiLCJnZXRFbnRyeSIsImVudHJ5IiwiX2YiLCJuIiwiSVNfTUFQIiwiQURERVIiLCJfbCIsImZvck9mIiwidmFsaWRhdGUiLCJkYXRhIiwiY2FsbGJhY2tmbiIsInYiLCJTQUZFX0NMT1NJTkciLCJyaXRlciIsInNraXBDbG9zaW5nIiwiYXJyIiwiaXRlciIsImNvbW1vbiIsIklTX1dFQUsiLCJmaXhNZXRob2QiLCJmYWlscyIsImdldENvbnN0cnVjdG9yIiwiaW5zdGFuY2UiLCJIQVNOVF9DSEFJTklORyIsIlRIUk9XU19PTl9QUklNSVRJVkVTIiwiQUNDRVBUX0lURVJBQkxFUyIsIiRpdGVyRGV0ZWN0IiwiQlVHR1lfWkVSTyIsIiRpbnN0YW5jZSIsImluaGVyaXRJZlJlcXVpcmVkIiwic2V0U3Ryb25nIiwiU0VUIiwiU2V0Iiwic3Ryb25nIiwidG9KU09OIiwiQ09MTEVDVElPTiIsIm9mIiwiQSIsIm1hcEZuIiwibWFwcGluZyIsImFGdW5jdGlvbiIsIm5leHRJdGVtIiwicmVxdWlyZSQkNyIsIk1BUCIsIk1hcCIsImFyZyIsIm9yaWdpbmFsIiwic3BlY2llc0NvbnN0cnVjdG9yIiwiJGNyZWF0ZSIsIklTX0ZJTFRFUiIsIklTX1NPTUUiLCJJU19FVkVSWSIsIklTX0ZJTkRfSU5ERVgiLCJOT19IT0xFUyIsImFzYyIsInJlcyIsImdldE93blByb3BlcnR5U3ltYm9scyIsIiRhc3NpZ24iLCJhc3NpZ24iLCJLIiwiYUxlbiIsImdldFN5bWJvbHMiLCJnT1BTIiwiaXNFbnVtIiwiYXJyYXlGaW5kIiwiY3JlYXRlQXJyYXlNZXRob2QiLCJhcnJheUZpbmRJbmRleCIsInVuY2F1Z2h0RnJvemVuU3RvcmUiLCJVbmNhdWdodEZyb3plblN0b3JlIiwiZmluZFVuY2F1Z2h0RnJvemVuIiwiJGhhcyIsIldFQUtfTUFQIiwid2VhayIsInVmc3RvcmUiLCJ0bXAiLCJJbnRlcm5hbE1hcCIsIiRXZWFrTWFwIiwiZnJlZXplIiwicmVxdWlyZSQkNSIsIiRkZWZpbmVQcm9wZXJ0eSIsIm1hcGZuIiwicmVzZXJ2ZWRUYWdMaXN0IiwiaXNWYWxpZEN1c3RvbUVsZW1lbnROYW1lIiwibG9jYWxOYW1lIiwicmVzZXJ2ZWQiLCJ2YWxpZEZvcm0iLCJpc0Nvbm5lY3RlZCIsIm5hdGl2ZVZhbHVlIiwiX19DRV9pc0ltcG9ydERvY3VtZW50IiwiRG9jdW1lbnQiLCJTaGFkb3dSb290IiwiaG9zdCIsIm5leHRTaWJsaW5nT3JBbmNlc3RvclNpYmxpbmciLCJyb290IiwibmV4dFNpYmxpbmciLCJuZXh0Tm9kZSIsIndhbGtEZWVwRGVzY2VuZGFudEVsZW1lbnRzIiwidmlzaXRlZEltcG9ydHMiLCJpbXBvcnQiLCJzaGFkb3dSb290IiwiX19DRV9zaGFkb3dSb290Iiwic2V0UHJvcGVydHlVbmNoZWNrZWQiLCJkZXN0aW5hdGlvbiIsIkN1c3RvbUVsZW1lbnRTdGF0ZSIsIkN1c3RvbUVsZW1lbnRJbnRlcm5hbHMiLCJfbG9jYWxOYW1lVG9EZWZpbml0aW9uIiwiX2NvbnN0cnVjdG9yVG9EZWZpbml0aW9uIiwiX3BhdGNoZXMiLCJfaGFzUGF0Y2hlcyIsImRlZmluaXRpb24iLCJwYXRjaCIsIl9fQ0VfcGF0Y2hlZCIsIl9fQ0Vfc3RhdGUiLCJDRVN0YXRlIiwiY3VzdG9tIiwiVXRpbGl0aWVzIiwiY29ubmVjdGVkQ2FsbGJhY2siLCJ1cGdyYWRlRWxlbWVudCIsImRpc2Nvbm5lY3RlZENhbGxiYWNrIiwiZ2F0aGVyRWxlbWVudHMiLCJfX0NFX2hhc1JlZ2lzdHJ5IiwiX19DRV9kb2N1bWVudExvYWRIYW5kbGVkIiwicGF0Y2hBbmRVcGdyYWRlVHJlZSIsImN1cnJlbnRTdGF0ZSIsImxvY2FsTmFtZVRvRGVmaW5pdGlvbiIsImNvbnN0cnVjdGlvblN0YWNrIiwicG9wIiwiZmFpbGVkIiwiX19DRV9kZWZpbml0aW9uIiwiYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrIiwib2JzZXJ2ZWRBdHRyaWJ1dGVzIiwiX19DRV9pc0Nvbm5lY3RlZENhbGxiYWNrQ2FsbGVkIiwib2xkVmFsdWUiLCJuZXdWYWx1ZSIsIm5hbWVzcGFjZSIsIkRvY3VtZW50Q29uc3RydWN0aW9uT2JzZXJ2ZXIiLCJpbnRlcm5hbHMiLCJkb2MiLCJfaW50ZXJuYWxzIiwiX2RvY3VtZW50IiwiX29ic2VydmVyIiwiX2hhbmRsZU11dGF0aW9ucyIsImRpc2Nvbm5lY3QiLCJtdXRhdGlvbnMiLCJhZGRlZE5vZGVzIiwiRGVmZXJyZWQiLCJfdmFsdWUiLCJfcmVzb2x2ZSIsIl9wcm9taXNlIiwiQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5IiwiX2VsZW1lbnREZWZpbml0aW9uSXNSdW5uaW5nIiwiX3doZW5EZWZpbmVkRGVmZXJyZWQiLCJfZmx1c2hDYWxsYmFjayIsIl9mbHVzaFBlbmRpbmciLCJfdW5mbHVzaGVkTG9jYWxOYW1lcyIsIl9kb2N1bWVudENvbnN0cnVjdGlvbk9ic2VydmVyIiwiU3ludGF4RXJyb3IiLCJhZG9wdGVkQ2FsbGJhY2siLCJnZXRDYWxsYmFjayIsImNhbGxiYWNrVmFsdWUiLCJzZXREZWZpbml0aW9uIiwiX2ZsdXNoIiwicHJpb3IiLCJ0b1Byb21pc2UiLCJvdXRlciIsImlubmVyIiwiZmx1c2giLCJ3aGVuRGVmaW5lZCIsInBvbHlmaWxsV3JhcEZsdXNoQ2FsbGJhY2siLCJjcmVhdGVFbGVtZW50TlMiLCJjbG9uZU5vZGUiLCJnZXRBdHRyaWJ1dGVOUyIsInNldEF0dHJpYnV0ZU5TIiwicmVtb3ZlQXR0cmlidXRlTlMiLCJBbHJlYWR5Q29uc3RydWN0ZWRNYXJrZXIiLCJjb25zdHJ1Y3RvclRvRGVmaW5pdGlvbiIsIk5hdGl2ZSIsIkRvY3VtZW50X2NyZWF0ZUVsZW1lbnQiLCJsYXN0SW5kZXgiLCJidWlsdEluIiwibm9kZXMiLCJjb25uZWN0ZWRCZWZvcmUiLCJwcmVwZW5kIiwiZGlzY29ubmVjdFRyZWUiLCJjb25uZWN0VHJlZSIsImNsb25lIiwiRG9jdW1lbnRfaW1wb3J0Tm9kZSIsInBhdGNoVHJlZSIsIk5TX0hUTUwiLCJEb2N1bWVudF9jcmVhdGVFbGVtZW50TlMiLCJEb2N1bWVudF9wcmVwZW5kIiwiRG9jdW1lbnRfYXBwZW5kIiwicmVmTm9kZSIsImluc2VydGVkTm9kZXMiLCJuYXRpdmVSZXN1bHQiLCJOb2RlX2luc2VydEJlZm9yZSIsIm5vZGVXYXNDb25uZWN0ZWQiLCJOb2RlX2FwcGVuZENoaWxkIiwiTm9kZV9jbG9uZU5vZGUiLCJvd25lckRvY3VtZW50IiwiTm9kZV9yZW1vdmVDaGlsZCIsIm5vZGVUb0luc2VydCIsIm5vZGVUb1JlbW92ZSIsIk5vZGVfcmVwbGFjZUNoaWxkIiwibm9kZVRvSW5zZXJ0V2FzQ29ubmVjdGVkIiwidGhpc0lzQ29ubmVjdGVkIiwicGF0Y2hfdGV4dENvbnRlbnQiLCJiYXNlRGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJhc3NpZ25lZFZhbHVlIiwicmVtb3ZlZE5vZGVzIiwiY2hpbGROb2Rlc0xlbmd0aCIsIk5vZGVfdGV4dENvbnRlbnQiLCJhZGRQYXRjaCIsInBhcnRzIiwiYmVmb3JlIiwid2FzQ29ubmVjdGVkIiwicmVwbGFjZVdpdGgiLCJFbGVtZW50X2F0dGFjaFNoYWRvdyIsImluaXQiLCJwYXRjaF9pbm5lckhUTUwiLCJodG1sU3RyaW5nIiwicmVtb3ZlZEVsZW1lbnRzIiwiRWxlbWVudF9pbm5lckhUTUwiLCJIVE1MRWxlbWVudF9pbm5lckhUTUwiLCJyYXdEaXYiLCJFbGVtZW50X3NldEF0dHJpYnV0ZSIsIkVsZW1lbnRfZ2V0QXR0cmlidXRlIiwiRWxlbWVudF9zZXRBdHRyaWJ1dGVOUyIsIkVsZW1lbnRfZ2V0QXR0cmlidXRlTlMiLCJFbGVtZW50X3JlbW92ZUF0dHJpYnV0ZSIsIkVsZW1lbnRfcmVtb3ZlQXR0cmlidXRlTlMiLCJwYXRjaF9pbnNlcnRBZGphY2VudEVsZW1lbnQiLCJiYXNlTWV0aG9kIiwid2hlcmUiLCJpbnNlcnRlZEVsZW1lbnQiLCJIVE1MRWxlbWVudF9pbnNlcnRBZGphY2VudEVsZW1lbnQiLCJFbGVtZW50X2luc2VydEFkamFjZW50RWxlbWVudCIsIkVsZW1lbnRfcHJlcGVuZCIsIkVsZW1lbnRfYXBwZW5kIiwiRWxlbWVudF9iZWZvcmUiLCJFbGVtZW50X2FmdGVyIiwiRWxlbWVudF9yZXBsYWNlV2l0aCIsIkVsZW1lbnRfcmVtb3ZlIiwicHJpb3JDdXN0b21FbGVtZW50cyIsIkpzTXV0YXRpb25PYnNlcnZlciIsInJlZ2lzdHJhdGlvbnNUYWJsZSIsInNldEltbWVkaWF0ZSIsInNldEltbWVkaWF0ZVF1ZXVlIiwic2VudGluZWwiLCJmdW5jIiwicG9zdE1lc3NhZ2UiLCJpc1NjaGVkdWxlZCIsInNjaGVkdWxlZE9ic2VydmVycyIsInNjaGVkdWxlQ2FsbGJhY2siLCJkaXNwYXRjaENhbGxiYWNrcyIsIndyYXBJZk5lZWRlZCIsIlNoYWRvd0RPTVBvbHlmaWxsIiwib2JzZXJ2ZXJzIiwibzEiLCJvMiIsInVpZF8iLCJhbnlOb25FbXB0eSIsInRha2VSZWNvcmRzIiwiY2FsbGJhY2tfIiwicmVtb3ZlVHJhbnNpZW50T2JzZXJ2ZXJzRm9yIiwibm9kZXNfIiwicmVnaXN0cmF0aW9ucyIsInJlZ2lzdHJhdGlvbiIsInJlbW92ZVRyYW5zaWVudE9ic2VydmVycyIsImZvckVhY2hBbmNlc3RvckFuZE9ic2VydmVyRW5xdWV1ZVJlY29yZCIsInN1YnRyZWUiLCJyZWNvcmQiLCJlbnF1ZXVlIiwidWlkQ291bnRlciIsInJlY29yZHNfIiwiYXR0cmlidXRlcyIsImF0dHJpYnV0ZU9sZFZhbHVlIiwiYXR0cmlidXRlRmlsdGVyIiwiY2hhcmFjdGVyRGF0YU9sZFZhbHVlIiwiUmVnaXN0cmF0aW9uIiwiYWRkTGlzdGVuZXJzIiwiY29weU9mUmVjb3JkcyIsIk11dGF0aW9uUmVjb3JkIiwicHJldmlvdXNTaWJsaW5nIiwiYXR0cmlidXRlTmFtZSIsImF0dHJpYnV0ZU5hbWVzcGFjZSIsImNvcHlNdXRhdGlvblJlY29yZCIsImN1cnJlbnRSZWNvcmQiLCJyZWNvcmRXaXRoT2xkVmFsdWUiLCJnZXRSZWNvcmQiLCJnZXRSZWNvcmRXaXRoT2xkVmFsdWUiLCJjbGVhclJlY29yZHMiLCJyZWNvcmRSZXByZXNlbnRzQ3VycmVudE11dGF0aW9uIiwic2VsZWN0UmVjb3JkIiwibGFzdFJlY29yZCIsIm5ld1JlY29yZCIsInRyYW5zaWVudE9ic2VydmVkTm9kZXMiLCJyZWNvcmRzIiwicmVjb3JkVG9SZXBsYWNlTGFzdCIsImFkZExpc3RlbmVyc18iLCJyZW1vdmVMaXN0ZW5lcnNfIiwiYXR0ck5hbWUiLCJyZWxhdGVkTm9kZSIsIm5hbWVzcGFjZVVSSSIsImF0dHJDaGFuZ2UiLCJNdXRhdGlvbkV2ZW50IiwiQURESVRJT04iLCJwcmV2VmFsdWUiLCJhZGRUcmFuc2llbnRPYnNlcnZlciIsImNoYW5nZWROb2RlIiwiX2lzUG9seWZpbGxlZCIsIm5leHRIYW5kbGUiLCJ0YXNrc0J5SGFuZGxlIiwiY3VycmVudGx5UnVubmluZ0FUYXNrIiwiYWRkRnJvbVNldEltbWVkaWF0ZUFyZ3VtZW50cyIsInBhcnRpYWxseUFwcGxpZWQiLCJydW5JZlByZXNlbnQiLCJoYW5kbGUiLCJ0YXNrIiwiY2xlYXJJbW1lZGlhdGUiLCJpbnN0YWxsTmV4dFRpY2tJbXBsZW1lbnRhdGlvbiIsIm5leHRUaWNrIiwiY2FuVXNlUG9zdE1lc3NhZ2UiLCJpbXBvcnRTY3JpcHRzIiwicG9zdE1lc3NhZ2VJc0FzeW5jaHJvbm91cyIsIm9sZE9uTWVzc2FnZSIsIm9ubWVzc2FnZSIsImluc3RhbGxQb3N0TWVzc2FnZUltcGxlbWVudGF0aW9uIiwibWVzc2FnZVByZWZpeCIsIm9uR2xvYmFsTWVzc2FnZSIsImF0dGFjaEV2ZW50IiwiaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24iLCJjaGFubmVsIiwiTWVzc2FnZUNoYW5uZWwiLCJwb3J0MSIsInBvcnQyIiwiaW5zdGFsbFJlYWR5U3RhdGVDaGFuZ2VJbXBsZW1lbnRhdGlvbiIsIm9ucmVhZHlzdGF0ZWNoYW5nZSIsImluc3RhbGxTZXRUaW1lb3V0SW1wbGVtZW50YXRpb24iLCJhdHRhY2hUbyIsInByb2Nlc3MiLCJERUZBVUxUX1ZJRVdQT1JUIiwiVmlld3BvcnQiLCJ2aWV3cG9ydEVsZW1lbnQiLCJoZWFkIiwiZW5zdXJlVmlld3BvcnRFbGVtZW50IiwiX29uc0xvYWRlZCIsImZhc3RDbGljayIsInN1cHBvcnRUb3VjaEFjdGlvbiIsIl9pbnRlcm5hbCIsImNyZWF0ZUhhbmRsZXIiLCJhcHAiLCJleGl0QXBwIiwiX2dlc3R1cmVEZXRlY3RvciIsImdldEVsZW1lbnRDbGFzcyIsIkJhc2VFbGVtZW50IiwiVGVtcGxhdGVFbGVtZW50Iiwib3V0ZXJIVE1MIiwiYnViYmxlcyIsIlRlbXBsYXRlIiwiSWZFbGVtZW50IiwiX2lzQWxsb3dlZFBsYXRmb3JtIiwiY29uZGl0aW9uYWxPcmllbnRhdGlvbiIsImN1cnJlbnRPcmllbnRhdGlvbiIsIklmIiwiQmFzZUFuaW1hdG9yIiwicHJvcGVydGllcyIsImV4dGVuZGVkQW5pbWF0b3IiLCJuZXdBbmltYXRvciIsImlQaG9uZVhQYXRjaCIsImlzSVBob25lWFBvcnRyYWl0UGF0Y2hBY3RpdmUiLCJpc0lQaG9uZVhMYW5kc2NhcGVQYXRjaEFjdGl2ZSIsImdldFNhZmVBcmVhTGVuZ3RocyIsInNhZmVBcmVhTGVuZ3RocyIsImdldFNhZmVBcmVhRE9NUmVjdCIsInNhZmVBcmVhUmVjdCIsIkFjdGlvblNoZWV0QW5pbWF0b3IiLCJNREFjdGlvblNoZWV0QW5pbWF0b3IiLCJtYXNrVGltaW5nIiwibWFza0R1cmF0aW9uIiwiYW5pbWl0IiwiX21hc2siLCJvcGFjaXR5IiwiX3NoZWV0IiwiZGVmYXVsdCIsInRyYW5zZm9ybSIsIklPU0FjdGlvblNoZWV0QW5pbWF0b3IiLCJsaWZ0QW1vdW50IiwiY2xpZW50SGVpZ2h0IiwiQmFzZURpYWxvZ0VsZW1lbnQiLCJzaG91bGRTaG93IiwiX2Rvb3JMb2NrIiwiX2NhbmNlbCIsIl9zZWxmQ2FtZWxOYW1lIiwiX2RlZmF1bHREQkIiLCJjYWxsUGFyZW50SGFuZGxlciIsIl9hbmltYXRvckZhY3RvcnkiLCJfdXBkYXRlQW5pbWF0b3JGYWN0b3J5IiwiX3J1bm5pbmciLCJfc2V0VmlzaWJsZSIsInBhcnNlQW5pbWF0aW9uT3B0aW9uc1N0cmluZyIsImNhbmNlbGVkIiwiX3RvZ2dsZVN0eWxlIiwiYmFja2dyb3VuZENvbG9yIiwib25EZXZpY2VCYWNrQnV0dG9uIiwiX2JhY2tCdXR0b25IYW5kbGVyIiwib25Nb2RpZmllckNoYW5nZWQiLCJfc2NoZW1lIiwiX3VwZGF0ZU1hc2siLCJfYW5pbWF0b3JEaWN0IiwiQWN0aW9uU2hlZXRFbGVtZW50IiwiX2NvbXBpbGUiLCJzaGVldCIsIl90aXRsZSIsIm1hc2siLCJpbml0TW9kaWZpZXIiLCJfdXBkYXRlVGl0bGUiLCJBY3Rpb25TaGVldCIsIkJhc2VCdXR0b25FbGVtZW50IiwiX2RlZmF1bHRDbGFzc05hbWUiLCJfaWNvbiIsIl91cGRhdGVSaXBwbGUiLCJfcmlwcGxlT3B0IiwiX3VwZGF0ZUljb24iLCJBY3Rpb25TaGVldEJ1dHRvbkVsZW1lbnQiLCJBY3Rpb25TaGVldEJ1dHRvbiIsIkFsZXJ0RGlhbG9nQW5pbWF0b3IiLCJBbmRyb2lkQWxlcnREaWFsb2dBbmltYXRvciIsIl9kaWFsb2ciLCJJT1NBbGVydERpYWxvZ0FuaW1hdG9yIiwiQWxlcnREaWFsb2dFbGVtZW50IiwiQWxlcnREaWFsb2ciLCJBbGVydERpYWxvZ0J1dHRvbkVsZW1lbnQiLCJBbGVydERpYWxvZ0J1dHRvbiIsImRlZmF1bHRDbGFzc05hbWUiLCJCYWNrQnV0dG9uRWxlbWVudCIsIl9vcHRpb25zIiwiX2JvdW5kT25DbGljayIsIl9vbkNsaWNrIiwibWRCYWNrQnV0dG9uSWNvbiIsImlvc0JhY2tCdXR0b25JY29uIiwicG9wUGFnZSIsIkJhY2tCdXR0b24iLCJCb3R0b21Ub29sYmFyRWxlbWVudCIsIkJvdHRvbVRvb2xiYXIiLCJCdXR0b25FbGVtZW50IiwiQnV0dG9uIiwiQ2FyZEVsZW1lbnQiLCJDYXJkIiwiQ2Fyb3VzZWxJdGVtRWxlbWVudCIsIkNhcm91c2VsSXRlbSIsImRpcmVjdGlvbk1hcCIsIlN3aXBlciIsIkZBTFNFIiwiZ2V0RWxlbWVudCIsInNjcm9sbEhvb2siLCJpdGVtU2l6ZSIsImdldEF1dG9TY3JvbGxSYXRpbyIsInJhdGlvIiwic2hvdWxkQmxvY2siLCJvbkRyYWdTdGFydCIsIm9uRHJhZyIsIm9uRHJhZ0VuZCIsIm9uUmVzaXplIiwiX3Nob3VsZEZpeFNjcm9sbCIsInN3aXBlYWJsZSIsImF1dG9SZWZyZXNoIiwiaW5pdGlhbGl6ZWQiLCJibG9ja2VyIiwiX211dGF0aW9uT2JzZXJ2ZXIiLCJ1cGRhdGVTd2lwZWFibGUiLCJ1cGRhdGVBdXRvUmVmcmVzaCIsIl9zY3JvbGwiLCJfb2Zmc2V0IiwiX2xhc3RBY3RpdmVJbmRleCIsIl91cGRhdGVMYXlvdXQiLCJfc2V0dXBJbml0aWFsSW5kZXgiLCJzZXR1cFJlc2l6ZSIsInRhcmdldFNpemUiLCJfcmVzZXQiLCJzZXRBY3RpdmVJbmRleCIsInJvdW5kIiwiTnVtYmVyIiwiZ2V0SW5pdGlhbEluZGV4IiwiaXRlbUNvdW50IiwiaXRlbU51bVNpemUiLCJfc2Nyb2xsVG8iLCJfc2V0U3dpcGluZyIsInNjcm9sbCIsIm1heFNjcm9sbCIsImFycmF5T2ZBcnJheSIsImNvbnRlbnRzIiwiX2NoYW5nZVRvIiwiY291bnQiLCJzaXplIiwic2hvdWxkVXBkYXRlIiwic2hvdWxkV2F0Y2giLCJuZXdTaXplIiwiYmxvY2siLCJwb2ludGVyRXZlbnRzIiwiaXNGaXJzdCIsImlzT3ZlclNjcm9sbGFibGUiLCJpc0xhc3QiLCJfaWdub3JlRHJhZyIsImNvbnN1bWVkIiwiY29uc3VtZSIsIl9jYW5Db25zdW1lR2VzdHVyZSIsInN0YXJ0WCIsImRpc3RGcm9tRWRnZSIsImdldEJ1YmJsZVdpZHRoIiwiX3N0YXJ0ZWQiLCJ0b2dnbGVCbG9ja2VyIiwiX2NvbnRpbnVlZCIsIl9nZXREZWx0YSIsInRocm90dGxlIiwibm9ybWFsaXplZFNjcm9sbCIsIl9ub3JtYWxpemVTY3JvbGwiLCJfc3RhcnRNb21lbnR1bVNjcm9sbCIsIl9raWxsT3ZlclNjcm9sbCIsIl9nZXRWZWxvY2l0eSIsIm1hdGNoZXNEaXJlY3Rpb24iLCJkTSIsImRpciIsIm5leHRTY3JvbGwiLCJfZ2V0QXV0b1Njcm9sbCIsInN3aXBlIiwia2lsbE92ZXJTY3JvbGwiLCJvdmVyU2Nyb2xsSG9vayIsImFjdGl2ZUluZGV4IiwiZ2V0QWN0aXZlSW5kZXgiLCJsYXN0QWN0aXZlSW5kZXgiLCJjaGFuZ2UiLCJwcmVDaGFuZ2VIb29rIiwicG9zdENoYW5nZUhvb2siLCJ0b0ZpeGVkIiwiX2dldFRyYW5zZm9ybSIsIm9mZnNldCIsImlzQXV0b1Njcm9sbGFibGUiLCJsYXN0U2Nyb2xsIiwic2Nyb2xsUmF0aW8iLCJfdGFyZ2V0U2l6ZSIsIl9pdGVtTnVtU2l6ZSIsInJlZnJlc2hIb29rIiwiYXhpcyIsInQzZCIsIm5leHRFbGVtZW50U2libGluZyIsImlzQ2VudGVyZWQiLCJfY2FsY3VsYXRlSXRlbVNpemUiLCJDYXJvdXNlbEVsZW1lbnQiLCJfc3dpcGVyIiwiYXV0b1Njcm9sbFJhdGlvIiwidmVydGljYWwiLCJvdmVyc2Nyb2xsYWJsZSIsImNlbnRlcmVkIiwiYXV0b1Njcm9sbCIsIl9vbk92ZXJTY3JvbGwiLCJfb25DaGFuZ2UiLCJfb25SZWZyZXNoIiwiX29uU3dpcGUiLCJ1cGRhdGVJdGVtU2l6ZSIsIndhaXRGb3JBY3Rpb24iLCJjYXJvdXNlbCIsIml0ZW1TaXplQXR0ciIsInBhcnNlRmxvYXQiLCJDYXJvdXNlbCIsIkNvbEVsZW1lbnQiLCJfdXBkYXRlV2lkdGgiLCJDb2wiLCJEaWFsb2dBbmltYXRvciIsIkFuZHJvaWREaWFsb2dBbmltYXRvciIsIklPU0RpYWxvZ0FuaW1hdG9yIiwiYm9keUhlaWdodCIsIlNsaWRlRGlhbG9nQW5pbWF0b3IiLCJEaWFsb2dFbGVtZW50IiwiRGlhbG9nIiwiRmFiRWxlbWVudCIsIl9oaWRlIiwiX3Nob3ciLCJfbWFudWFsbHlIaWRkZW4iLCJfdG9nZ2xlIiwiaXNCb3R0b20iLCJ0cmFuc2xhdGUiLCJmYWJPZmZzZXQiLCJGYWIiLCJHZXN0dXJlRGV0ZWN0b3JFbGVtZW50IiwiYXV0b1ByZWZpeCIsIkljb25FbGVtZW50IiwiX2NsZWFuQ2xhc3NBdHRyaWJ1dGUiLCJfdXBkYXRlIiwiX2J1aWxkQ2xhc3NBbmRTdHlsZSIsIl9wYXJzZUF0dHIiLCJhdHRyIiwibWQiLCJsYXN0SWNvbiIsImxhc3RNb2RpZmllciIsIl9wcmVmaXhJY29uIiwiY3VzdG9tUHJlZml4UkUiLCJpY29uTmFtZSIsInJlbW92ZVByb3BlcnR5IiwiZm9udFNpemUiLCJMYXp5UmVwZWF0RGVsZWdhdGUiLCJ1c2VyRGVsZWdhdGUiLCJ0ZW1wbGF0ZUVsZW1lbnQiLCJfdXNlckRlbGVnYXRlIiwiX3RlbXBsYXRlRWxlbWVudCIsIl9yZW5kZXIiLCJsb2FkSXRlbUVsZW1lbnQiLCJjcmVhdGVJdGVtQ29udGVudCIsImNvdW50SXRlbXMiLCJ1cGRhdGVJdGVtQ29udGVudCIsImNhbGN1bGF0ZUl0ZW1IZWlnaHQiLCJkZXN0cm95SXRlbSIsIml0ZW1IZWlnaHQiLCJMYXp5UmVwZWF0UHJvdmlkZXIiLCJ3cmFwcGVyRWxlbWVudCIsImRlbGVnYXRlIiwiX3dyYXBwZXJFbGVtZW50IiwiX2RlbGVnYXRlIiwiX2luc2VydEluZGV4IiwiX3BhZ2VDb250ZW50IiwiX2ZpbmRQYWdlQ29udGVudEVsZW1lbnQiLCJsYXN0U2Nyb2xsVG9wIiwicGFkZGluZyIsIl90b3BQb3NpdGlvbnMiLCJfcmVuZGVyZWRJdGVtcyIsIl91bmtub3duSXRlbUhlaWdodCIsIl9hZGRFdmVudExpc3RlbmVycyIsInBhZ2VDb250ZW50IiwiX2l0ZW1IZWlnaHQiLCJ2aXNpYmlsaXR5Iiwic3RhdGljSXRlbUhlaWdodCIsIl9nZXRJdGVtSGVpZ2h0IiwiZm9yY2VSZW5kZXIiLCJmb3JjZVNjcm9sbERvd24iLCJmaXJzdEl0ZW1JbmRleCIsIl9maXJzdEl0ZW1SZW5kZXJlZCIsIl9jYWxjdWxhdGVSZW5kZXJlZEhlaWdodCIsImZvcmNlRmlyc3RJbmRleCIsIl9yZW1vdmVBbGxFbGVtZW50cyIsImZvcmNlTGFzdEluZGV4IiwiX2NoZWNrSXRlbUhlaWdodCIsImlzU2Nyb2xsVXAiLCJrZWVwIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwiX2NvdW50SXRlbXMiLCJfY2FsY3VsYXRlU3RhcnRJbmRleCIsImhhc1JlbmRlckZ1bmN0aW9uIiwiX3JlbmRlckVsZW1lbnQiLCJfcmVtb3ZlRWxlbWVudCIsInVwZGF0ZUl0ZW0iLCJsYXN0SXRlbUluZGV4IiwiX2xhc3RJdGVtUmVuZGVyZWQiLCJfcmVjYWxjdWxhdGVUb3BQb3NpdGlvbnMiLCJtaWRkbGUiLCJpbW1lZGlhdGUiLCJjYWxsTm93IiwiX2RlYm91bmNlIiwiX2JvdW5kT25DaGFuZ2UiLCJfYm91bmREb3VibGVGaXJlT25Ub3VjaGVuZCIsIl9wYXJlbnRFbGVtZW50IiwiX3JlbW92ZUV2ZW50TGlzdGVuZXJzIiwicGFkZGluZ1RvcCIsIkxhenlSZXBlYXRFbGVtZW50IiwiX2xhenlSZXBlYXRQcm92aWRlciIsIkxhenlSZXBlYXQiLCJMaXN0SGVhZGVyRWxlbWVudCIsIkxpc3RIZWFkZXIiLCJMaXN0VGl0bGVFbGVtZW50IiwiTGlzdFRpdGxlIiwiTGlzdEl0ZW1BbmltYXRvciIsImxpc3RJdGVtIiwiU2xpZGVMaXN0SXRlbUFuaW1hdG9yIiwiX2FuaW1hdGVFeHBhbnNpb24iLCJzaG91bGRPcGVuIiwib2xkSGVpZ2h0IiwiZXhwYW5kYWJsZUNvbnRlbnQiLCJvbGREaXNwbGF5IiwiY29tcHV0ZWRTdHlsZSIsImV4cGFuc2lvbk9wZW5UcmFuc2l0aW9uIiwicGFkZGluZ0JvdHRvbSIsImljb25PcGVuVHJhbnNpdGlvbiIsInJldmVyc2UiLCJleHBhbmRDaGV2cm9uIiwiTGlzdEl0ZW1FbGVtZW50IiwidG9nZ2xlRXhwYW5zaW9uIiwiX3Nob3VsZElnbm9yZVRhcCIsInNob3dFeHBhbnNpb24iLCJoaWRlRXhwYW5zaW9uIiwidG9wQ29udGVudCIsImNlbnRlckNvbnRlbnQiLCJfdG9wIiwiY2hldnJvbiIsIl9leHBhbmRpbmciLCJleHBhbmRlZCIsIl9zZXR1cExpc3RlbmVycyIsIl9vcmlnaW5hbEJhY2tncm91bmRDb2xvciIsInRhcHBlZCIsIl9vblRvdWNoIiwiX29uUmVsZWFzZSIsIl9vbkRyYWciLCJ0b3VjaFN0eWxlIiwiYm94U2hhZG93IiwiTGlzdEl0ZW0iLCJMaXN0RWxlbWVudCIsIkxpc3QiLCJJTlBVVF9BVFRSSUJVVEVTIiwiQmFzZUlucHV0RWxlbWVudCIsIl9ib3VuZERlbGVnYXRlRXZlbnQiLCJfZGVsZWdhdGVFdmVudCIsIl90ZW1wbGF0ZSIsIl9zZXRJbnB1dElkIiwiX3VwZGF0ZUJvdW5kQXR0cmlidXRlcyIsIl9pbnB1dCIsInRvSVNPU3RyaW5nIiwiSW5wdXRFbGVtZW50IiwiX2JvdW5kT25JbnB1dCIsIl9ib3VuZE9uRm9jdXNpbiIsIl91cGRhdGVMYWJlbCIsIl91cGRhdGVMYWJlbENsYXNzIiwiX2hlbHBlciIsImlubmVyVGV4dCIsIklucHV0IiwiQmFzZUNoZWNrYm94RWxlbWVudCIsImNoZWNrZWQiLCJDaGVja2JveEVsZW1lbnQiLCJDaGVja2JveCIsIlJhZGlvRWxlbWVudCIsIlJhZGlvIiwiU2VhcmNoSW5wdXRFbGVtZW50IiwiU2VhcmNoSW5wdXQiLCJNb2RhbEFuaW1hdG9yIiwibW9kYWwiLCJGYWRlTW9kYWxBbmltYXRvciIsIkxpZnRNb2RhbEFuaW1hdG9yIiwiTW9kYWxFbGVtZW50IiwiTW9kYWwiLCJ3aWR0aFRvUHgiLCJvZmZzZXRXaWR0aCIsIlN3aXBlUmV2ZWFsIiwiZWxlbWVudEhhbmRsZXIiLCJnZXRUaHJlc2hvbGQiLCJnZXRTaWRlIiwiaGFuZGxlR2VzdHVyZSIsImdlc3R1cmVEZXRlY3RvciIsImlnbm9yZVN3aXBlIiwiX3dpZHRoIiwiX3N0YXJ0RGlzdGFuY2UiLCJfZGlzdGFuY2UiLCJpc0luaXRpYWxTdGF0ZSIsImRlbHRhIiwic3dpcGVNaWQiLCJpc1N3aXBlTWF4Iiwic3dpcGVNYXgiLCJzd2lwZU1pbiIsIk5hdmlnYXRvckFuaW1hdG9yIiwiZW50ZXJQYWdlIiwibGVhdmVQYWdlIiwiSU9TU3dpcGVOYXZpZ2F0b3JBbmltYXRvciIsImR1cmF0aW9uUmVzdG9yZSIsImR1cmF0aW9uU3dpcGUiLCJ0aW1pbmdTd2lwZSIsInJlc3QiLCJvcHRTd2lwZSIsIm9wdFJlc3RvcmUiLCJzd2lwZVNoYWRvdyIsImlzRHJhZ1N0YXJ0IiwidW5ibG9jayIsImJhY2tncm91bmRNYXNrIiwiZGVjb21wIiwiX2RlY29tcG9zZSIsImVudGVyIiwibGVhdmUiLCJfY2FsY3VsYXRlRGVsdGEiLCJzaG91bGRBbmltYXRlVG9vbGJhciIsIl9zaG91bGRBbmltYXRlVG9vbGJhciIsInRvb2xiYXIiLCJfc2F2ZVN0eWxlIiwib3ZlcmZsb3dFbGVtZW50IiwibWF4V2lkdGgiLCJpc1N3aXBpbmciLCJfZHJhZ1N0YXJ0U2V0dXAiLCJzd2lwZVJhdGlvIiwiYm90dG9tVG9vbGJhciIsImJhY2tncm91bmQiLCJ0b29sYmFyQ2VudGVyIiwiYmFja0J1dHRvbkxhYmVsIiwib3RoZXIiLCJfc2F2ZWRTdHlsZSIsInNhdmUiLCJyZXN0b3JlIiwiX3Jlc3RvcmVTdHlsZSIsInRyYW5zbGF0ZTNkIiwiSU9TU2xpZGVOYXZpZ2F0b3JBbmltYXRvciIsIl9nZXRUb29sYmFyRWxlbWVudCIsIl9nZXRUb29sYmFyTGVmdEl0ZW1zRWxlbWVudCIsIl9nZXRUb29sYmFyUmlnaHRJdGVtc0VsZW1lbnQiLCJleGNsdWRlQmFja0J1dHRvbiIsIl9nZXRUb29sYmFyQ2VudGVySXRlbXNFbGVtZW50IiwiX2dldFRvb2xiYXJCYWNrQnV0dG9uSWNvbkVsZW1lbnQiLCJfZ2V0VG9vbGJhckJhY2tCdXR0b25MYWJlbEVsZW1lbnQiLCJfZ2V0Q29udGVudEVsZW1lbnQiLCJfZ2V0QmFja2dyb3VuZEVsZW1lbnQiLCJfZ2V0Qm90dG9tVG9vbGJhckVsZW1lbnQiLCJ0b29sYmFycyIsImVudGVyVG9vbGJhciIsImxlYXZlVG9vbGJhciIsImlzU3RhdGljIiwiaXNNYXRlcmlhbCIsImlzVHJhbnNwYXJlbnQiLCJkZWNvbXBvc2l0aW9uIiwicGFnZVJlY3QiLCJsYWJlbFJlY3QiLCJiYWNrQnV0dG9uSWNvbiIsImVudGVyUGFnZVRhcmdldCIsImxlYXZlUGFnZVRhcmdldCIsImVudGVyUGFnZURlY29tcG9zaXRpb24iLCJsZWF2ZVBhZ2VEZWNvbXBvc2l0aW9uIiwicG9wU3dpcGUiLCJJT1NMaWZ0TmF2aWdhdG9yQW5pbWF0b3IiLCJJT1NGYWRlTmF2aWdhdG9yQW5pbWF0b3IiLCJNRFNsaWRlTmF2aWdhdG9yQW5pbWF0b3IiLCJibGFja01hc2tPcGFjaXR5IiwiTURMaWZ0TmF2aWdhdG9yQW5pbWF0b3IiLCJtYXNrQ2xlYXIiLCJNREZhZGVOYXZpZ2F0b3JBbmltYXRvciIsInRpbWluZ1BvcCIsIk5vbmVOYXZpZ2F0b3JBbmltYXRvciIsInJld3JpdGFibGVzIiwibmF2aWdhdG9yRWxlbWVudCIsInZlcmlmeVBhZ2VFbGVtZW50IiwiTmF2aWdhdG9yRWxlbWVudCIsIl9pc1J1bm5pbmciLCJfaW5pdGlhbGl6ZWQiLCJfcGFnZUxvYWRlciIsIl9wYWdlTWFwIiwiX3BhZ2UiLCJfb25EZXZpY2VCYWNrQnV0dG9uIiwic3dpcGVBbmltYXRvciIsIl9zd2lwZSIsInByZXZpb3VzRWxlbWVudFNpYmxpbmciLCJhcmVhIiwiaXNCQiIsInB1c2hlZE9wdGlvbnMiLCJhbmltYXRvckZhY3RvcnkiLCJsb2FkZWQiLCJfZ2V0UGFnZVRhcmdldCIsInB1c2hQYWdlIiwiX3VwZGF0ZUxhc3RQYWdlQmFja0J1dHRvbiIsInVwZGF0ZSIsIl9wcmVwYXJlUGFnZUFuZE9wdGlvbnMiLCJ0aW1lcyIsIl9yZW1vdmVQYWdlcyIsInBvcFVwZGF0ZSIsInVubG9hZCIsIl9wb3BQYWdlIiwiX2VtaXRQcmVQb3BFdmVudCIsInVwZGF0ZUJhY2tCdXR0b24iLCJwYWdlSFRNTCIsIl9wdXNoUGFnZSIsImxvYWQiLCJfZW1pdFByZVB1c2hFdmVudCIsInBhZ2VMZW5ndGgiLCJfcmVwbGFjZVBhZ2UiLCJyZXNvbHZlZFZhbHVlIiwiX25vcm1hbGl6ZUluZGV4IiwiaW5zZXJ0UGFnZSIsIm5ld1BhZ2UiLCJfbGFzdEluZGV4T2ZQYWdlIiwicGFnZU5hbWUiLCJpc0NhbmNlbGVkIiwiX2VtaXRQcmVFdmVudCIsInRlbXBsYXRlSFRNTCIsInBhZ2VMb2FkZXIiLCJsYXN0RWxlbWVudENoaWxkIiwiTmF2aWdhdG9yIiwiVG9vbGJhckVsZW1lbnQiLCJzaWJsaW5nQmFja2dyb3VuZCIsInNpYmxpbmdDb250ZW50Iiwic2V0VmlzaWJpbGl0eSIsIl9lbnN1cmVUb29sYmFySXRlbUVsZW1lbnRzIiwiX2Vuc3VyZVRvb2xiYXJFbGVtZW50IiwiVG9vbGJhciIsIlBhZ2VFbGVtZW50IiwiX2Rlcml2ZUhvb2tzIiwiX2JhY2tncm91bmRFbGVtZW50IiwiX2VsZW1lbnRTaG91bGRCZU1vdmVkIiwiX3RyeVRvRmlsbFN0YXR1c0JhciIsImZpeGVkRWxlbWVudHMiLCJvbkluaXQiLCJiYWNrQnV0dG9uIiwib3ZlckxpbWl0IiwiX2luZmluaXRlU2Nyb2xsTGltaXQiLCJfb25JbmZpbml0ZVNjcm9sbCIsIl9sb2FkaW5nQ29udGVudCIsIm9uSW5maW5pdGVTY3JvbGwiLCJvbkRlc3Ryb3kiLCJldmVudHMiLCJfYm91bmRPblNjcm9sbCIsIl9vblNjcm9sbCIsIlBhZ2UiLCJQb3BvdmVyQW5pbWF0b3IiLCJwb3BvdmVyIiwiYW5pbWF0aW9ucyIsIl9hbmltYXRlIiwiZmFkZSIsIk1ERmFkZVBvcG92ZXJBbmltYXRvciIsIl9hbmltYXRlQWxsIiwiaW4iLCJJT1NGYWRlUG9wb3ZlckFuaW1hdG9yIiwicG9zaXRpb25zIiwiUG9wb3ZlckVsZW1lbnQiLCJfY3VycmVudFRhcmdldCIsIl9wb3NpdGlvblBvcG92ZXIiLCJfY2xlYXJTdHlsZXMiLCJyYWRpdXMiLCJfcmFkaXVzIiwiY29udGVudEVsZW1lbnQiLCJfY29udGVudCIsIm1hcmdpbiIsIl9tYXJnaW4iLCJ0YXJnZXRSZWN0IiwiaXNNRCIsImNvdmVyIiwicGFyZW50RGltZW5zaW9ucyIsIm1heFBvc2l0aW9ucyIsImJvdHRvbSIsInRhcmdldERpc3RhbmNlIiwidGFyZ2V0Q2VudGVyRGlzdGFuY2VGcm9tIiwiX2NhbGN1bGF0ZURpcmVjdGlvbnMiLCJwcmltYXJ5RGlyZWN0aW9uIiwicHJpbWFyeSIsInNlY29uZGFyeURpcmVjdGlvbiIsInNlY29uZGFyeSIsIl9jdXJyZW50RGlyZWN0aW9uIiwic2l6ZU5hbWUiLCJjb250ZW50U2l6ZSIsInRhcmdldEFuZEFycm93TGVuZ3RoIiwicHJpbWFyeU9mZnNldCIsInNlY29uZGFyeU9mZnNldCIsIl9wb3BvdmVyIiwiX2Fycm93IiwiaGFzRGVmYXVsdENvbnRhaW5lciIsImFycm93IiwiUG9wb3ZlciIsIklOREVUIiwiUHJvZ3Jlc3NCYXJFbGVtZW50IiwiX2lzQ29tcGlsZWQiLCJfcHJpbWFyeSIsIl9zZWNvbmRhcnkiLCJfdXBkYXRlRGV0ZXJtaW5hdGUiLCJfdXBkYXRlVmFsdWUiLCJiYXJFbGVtZW50IiwiUHJvZ3Jlc3NCYXIiLCJQcm9ncmVzc0NpcmN1bGFyRWxlbWVudCIsInBlciIsInN2ZyIsIlByb2dyZXNzQ2lyY3VsYXIiLCJTVEFURV9JTklUSUFMIiwiU1RBVEVfUFJFQUNUSU9OIiwiU1RBVEVfQUNUSU9OIiwidGhyb3dUeXBlIiwiUHVsbEhvb2tFbGVtZW50IiwiX29uRHJhZ1N0YXJ0IiwiX29uRHJhZ0VuZCIsIl9zZXRTdGF0ZSIsImxpbmVIZWlnaHQiLCJfcGFnZUVsZW1lbnQiLCJ0YXBZIiwibWF4WSIsImRyYWdnYWJsZUFyZWFSYXRpbyIsIl9zdGFydFNjcm9sbCIsIl9jdXJyZW50VHJhbnNsYXRpb24iLCJ0aCIsInRocmVzaG9sZEhlaWdodCIsIl9maW5pc2giLCJfdHJhbnNsYXRlVG8iLCJhbmltYXRlIiwib25BY3Rpb24iLCJub0V2ZW50IiwibGFzdFN0YXRlIiwibWFyZ2luVG9wIiwiX29uUHVsbCIsInNjcm9sbEVsZW1lbnQiLCJfZHJhZ0xvY2tEaXNhYmxlZCIsInNjcm9sbFRvZ2dsZSIsImdkVG9nZ2xlIiwiX3NldFN0eWxlIiwiX29uQWN0aW9uIiwiUHVsbEhvb2siLCJhY3RpdmVDbGFzc1Rva2VuIiwiUmFuZ2VFbGVtZW50IiwiX29uTW91c2VEb3duIiwiX29uTW91c2VVcCIsIl9vblRvdWNoU3RhcnQiLCJfb25Ub3VjaEVuZCIsIl9vbklucHV0IiwiX29uRHJhZ3N0YXJ0IiwiX29uRHJhZ2VuZCIsIl91cGRhdGVEaXNhYmxlZCIsImZvY3VzUmluZyIsIl9mb2N1c1JpbmciLCJiYWNrZ3JvdW5kU2l6ZSIsIl9yYXRpbyIsIlJhbmdlIiwiQW5pbWF0b3JDU1MiLCJmaW5hbCIsImdldFRpbWUiLCJpbml0aWFsIiwidXBkYXRlU3R5bGVzIiwiY2xlYXJUaW1lb3V0IiwidHJhbnNpdGlvbkR1cmF0aW9uIiwic3RvcE5leHQiLCJuZXdEdXJhdGlvbiIsInBhc3NlZCIsInJlbWFpbmluZyIsInNwZWVkVXBUaW1lIiwic3RvcCIsIm1pbGxpc2Vjb25kcyIsInNwZWVkIiwidHJhbnNpdGlvblByb3BlcnR5IiwiX29uU3RvcEFuaW1hdGlvbnMiLCJfcXVldWUiLCJfaW5kZXgiLCJzdG9wQW5pbWF0aW9ucyIsIlJpcHBsZUVsZW1lbnQiLCJfb25UYXAiLCJfb25Ib2xkIiwiX2FuaW1hdG9yIiwiX3dhdmUiLCJnZXRFbGVtZW50c0J5Q2xhc3NOYW1lIiwiX2JhY2tncm91bmQiLCJzaXplcyIsIl9nZXRFZmZlY3RTaXplIiwiX2NlbnRlciIsIl9taW5SIiwiX2NhbGN1bGF0ZUNvb3JkcyIsInN0b3BBbGwiLCJyaXBwbGUiLCJfdXBkYXRlUGFyZW50IiwiX3JpcHBsZUFuaW1hdGlvbiIsIl9ob2xkaW5nIiwiX3BhcmVudE5vZGUiLCJwbiIsIlJpcHBsZSIsIlJvd0VsZW1lbnQiLCJSb3ciLCJTZWdtZW50RWxlbWVudCIsIl9zZWdtZW50SWQiLCJfdGFiYmFyIiwiX29uVGFiYmFyUHJlQ2hhbmdlIiwiZ2V0QWN0aXZlVGFiSW5kZXgiLCJnZXRBY3RpdmVCdXR0b25JbmRleCIsIl9zZXRDaGVja2VkIiwiZmlyc3RFbGVtZW50Q2hpbGQiLCJzZXRBY3RpdmVUYWIiLCJfcG9zdENoYW5nZSIsIlNlZ21lbnQiLCJTZWxlY3RFbGVtZW50IiwiX2Rlcml2ZUdldHRlcnMiLCJfc2VsZWN0Iiwic2VsIiwib3B0aW9uIiwiU2VsZWN0IiwiU3BlZWREaWFsSXRlbUVsZW1lbnQiLCJTcGVlZERpYWxJdGVtIiwiU3BlZWREaWFsRWxlbWVudCIsIl9pdGVtU2hvd24iLCJfdXBkYXRlRGlyZWN0aW9uIiwidG9nZ2xlSXRlbXMiLCJpbmxpbmUiLCJfZmFiIiwiaXRlbXMiLCJfZ2V0VHJhbnNsYXRlIiwiaGlkZUl0ZW1zIiwidG90YWxEZWxheSIsImlzT3BlbiIsInNob3dJdGVtcyIsIlNwZWVkRGlhbCIsIlNwbGl0dGVyQ29udGVudEVsZW1lbnQiLCJvbGRDb250ZW50IiwiU3BsaXR0ZXJDb250ZW50IiwiU3BsaXR0ZXJNYXNrRWxlbWVudCIsIl9zaWRlcyIsInNpZGUiLCJtb2RlIiwiU3BsaXR0ZXJNYXNrIiwiU3BsaXR0ZXJBbmltYXRvciIsInNpZGVFbGVtZW50Iiwic3BsaXR0ZXIiLCJfc2lkZSIsIl9vcHBvc2l0ZVNpZGUiLCJjbGVhck1hc2siLCJPdmVybGF5U3BsaXR0ZXJBbmltYXRvciIsIm1pbnVzIiwiUHVzaFNwbGl0dGVyQW5pbWF0b3IiLCJzbGlkaW5nRWxlbWVudHMiLCJfc2xpZGluZ0VsZW1lbnRzIiwiX2dldFNsaWRpbmdFbGVtZW50cyIsIlJldmVhbFNwbGl0dGVyQW5pbWF0b3IiLCJfc2V0U3R5bGVzIiwiX3Vuc2V0U3R5bGVzIiwiX2dlbmVyYXRlQmVoaW5kUGFnZVN0eWxlIiwiYmVoaW5kRGlzdGFuY2UiLCJiZWhpbmRUcmFuc2Zvcm0iLCJfZ2V0TWF4V2lkdGgiLCJtZW51U3R5bGUiLCJTcGxpdHRlckVsZW1lbnQiLCJfbGF5b3V0IiwiX2dldFNpZGUiLCJfb25Nb2RlQ2hhbmdlIiwiU3BsaXR0ZXIiLCJTUExJVF9NT0RFIiwiQ09MTEFQU0VfTU9ERSIsIkNMT1NFRF9TVEFURSIsIk9QRU5fU1RBVEUiLCJDSEFOR0lOR19TVEFURSIsInNwbGl0dGVyU2lkZUVsZW1lbnQiLCJDb2xsYXBzZURldGVjdGlvbiIsImNoYW5nZVRhcmdldCIsIl90YXJnZXQiLCJfb3JpZW50YXRpb24iLCJhY3RpdmF0ZSIsIl91cGRhdGVNb2RlIiwiX21hdGNoIiwiX3F1ZXJ5UmVzdWx0IiwibWF0Y2hNZWRpYSIsImFkZExpc3RlbmVyIiwicmVtb3ZlTGlzdGVuZXIiLCJTcGxpdHRlclNpZGVFbGVtZW50IiwiX3N0YXRlIiwiX2xvY2siLCJfY29sbGFwc2VEZXRlY3Rpb24iLCJfYW5pbWF0aW9uT3B0IiwiY2xvc2VkIiwidmFsaWREcmFnIiwiX21vZGUiLCJfaXNPdGhlclNpZGVPcGVuIiwiZGVhY3RpdmF0ZSIsInVwZGF0ZU9wdGlvbnMiLCJGSU5BTF9TVEFURSIsIl9lbWl0RXZlbnQiLCJfdXBkYXRlQW5pbWF0aW9uIiwiU3BsaXR0ZXJTaWRlIiwibG9jYXRpb25zIiwiU3dpdGNoRWxlbWVudCIsIl9sYXN0VGltZVN0YW1wIiwiX2xvY2F0aW9ucyIsIl9zdGFydFgiLCJfZW1pdENoYW5nZUV2ZW50IiwiZGVmYXVsdEVsZW1lbnRDbGFzcyIsIl9oYW5kbGUiLCJfZ2V0UG9zaXRpb24iLCJwcmV2aW91c1ZhbHVlIiwiY2xpY2siLCJTd2l0Y2giLCJ0YWJiYXJFbGVtZW50IiwibGVycCIsIngwIiwieDEiLCJ0IiwiVGFiYmFyRWxlbWVudCIsIl9sb2FkSW5hY3RpdmUiLCJfZ2V0QXV0b1Njcm9sbFJhdGlvIiwiX29uUHJlQ2hhbmdlIiwiX29uUG9zdENoYW5nZSIsIl90YWJiYXJCb3JkZXIiLCJfdGFiYmFyRWxlbWVudCIsIl90YWJzUmVjdCIsInRhYkl0ZW0iLCJ0YWJzIiwiX25vcm1hbGl6ZUV2ZW50IiwiY2FuY2VsIiwic2V0QWN0aXZlIiwicHJldlRhYiIsIl9hdXRvZ3JvdyIsInRhYiIsInRhYmJhciIsImNzIiwiZmlsbGVkIiwibmV4dEluZGV4IiwicHJldkluZGV4IiwibmV4dFRhYiIsInNldFRhYmJhclZpc2liaWxpdHkiLCJpc0FjdGl2ZSIsImlzVG9wIiwiX3RhcmdldEVsZW1lbnQiLCJUYWJiYXIiLCJUYWJFbGVtZW50IiwiX2J1dHRvbiIsIl91cGRhdGVCdXR0b25Db250ZW50IiwiaWNvbldyYXBwZXIiLCJmaXgiLCJhY3RpdmUiLCJfaGFzTG9hZGVkIiwiX2xvYWRlZFBhZ2UiLCJwYWdlVGFyZ2V0IiwicGFyZW50VGFyZ2V0IiwiZHVtbXlQYWdlIiwiX2xvYWRQYWdlRWxlbWVudCIsIlRhYiIsIlRvYXN0QW5pbWF0b3IiLCJGYWRlVG9hc3RBbmltYXRvciIsIkFzY2VuZFRvYXN0QW5pbWF0b3IiLCJtZXNzYWdlRGVsYXkiLCJhc2NlbnNpb24iLCJfZ2V0RmFicyIsImZhYiIsIkxpZnRUb2FzdEFuaW1hdG9yIiwiRmFsbFRvYXN0QW5pbWF0b3IiLCJmYWxsQW1vdW50IiwiY2xlYW5VcCIsImNvcnJlY3RUb3AiLCJUb2FzdEVsZW1lbnQiLCJtZXNzYWdlQ2xhc3NOYW1lIiwiYnV0dG9uQ2xhc3NOYW1lIiwiVG9hc3QiLCJUb29sYmFyQnV0dG9uRWxlbWVudCIsIlRvb2xiYXJCdXR0b24iLCJfc3VwZXJTZWNyZXRPbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUEsa0JBQWUsRUFBZjs7QUNBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFpQkEsQUFFQTs7Ozs7O0FBTUEsSUFBTUEsU0FBVSxZQUFXO01BQ25CQyxTQUFTQyxPQUFPQyxnQkFBUCxDQUF3QkMsU0FBU0MsZUFBakMsRUFBa0QsRUFBbEQsQ0FBZjtNQUNNTCxTQUFTLENBQUNNLE1BQU1DLFNBQU4sQ0FBZ0JDLEtBQWhCLENBQ2JDLElBRGEsQ0FDUlIsTUFEUSxFQUViUyxJQUZhLENBRVIsRUFGUSxFQUdiQyxLQUhhLENBR1AsbUJBSE8sS0FHa0JWLE9BQU9XLEtBQVAsS0FBaUIsRUFBakIsSUFBdUIsQ0FBQyxFQUFELEVBQUssR0FBTCxDQUgxQyxFQUliLENBSmEsQ0FBZjs7U0FNTyxVQUFTQyxJQUFULEVBQWU7V0FDYixNQUFNYixNQUFOLEdBQWUsR0FBZixHQUFxQmMsT0FBS0MsU0FBTCxDQUFlRixJQUFmLENBQTVCO0dBREY7Q0FSYSxFQUFmOzs7Ozs7Ozs7O0FBc0JBLElBQU1HLFNBQVMsU0FBVEEsTUFBUyxDQUFTQyxPQUFULEVBQWtCQyxLQUFsQixFQUF5QjtTQUMvQkMsSUFBUCxDQUFZRCxLQUFaLEVBQW1CRSxPQUFuQixDQUEyQixVQUFTQyxHQUFULEVBQWM7UUFDbkNBLE9BQU9KLFFBQVFDLEtBQW5CLEVBQTBCO2NBQ2hCQSxLQUFSLENBQWNH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
|