From a2c5397edc945dcd6729b6cd262e7a4245da1217 Mon Sep 17 00:00:00 2001 From: MrYsLab Date: Mon, 2 Oct 2023 15:35:21 -0400 Subject: [PATCH] Build for 858e63efd3b8aa3db3b00bcf0c9ec06d20d5bc7f --- lib.min.js | 2013 ++++++++++++++++++++++++++---------------------- lib.min.js.map | 2 +- 2 files changed, 1088 insertions(+), 927 deletions(-) diff --git a/lib.min.js b/lib.min.js index bb98a410..15c5ca36 100644 --- a/lib.min.js +++ b/lib.min.js @@ -36558,39 +36558,6 @@ module.exports = exports["default"]; //# sourceMappingURL=purify.js.map -/***/ }), - -/***/ "./node_modules/entities/maps/entities.json": -/*!**************************************************!*\ - !*** ./node_modules/entities/maps/entities.json ***! - \**************************************************/ -/*! exports provided: Aacute, aacute, Abreve, abreve, ac, acd, acE, Acirc, acirc, acute, Acy, acy, AElig, aelig, af, Afr, afr, Agrave, agrave, alefsym, aleph, Alpha, alpha, Amacr, amacr, amalg, amp, AMP, andand, And, and, andd, andslope, andv, ang, ange, angle, angmsdaa, angmsdab, angmsdac, angmsdad, angmsdae, angmsdaf, angmsdag, angmsdah, angmsd, angrt, angrtvb, angrtvbd, angsph, angst, angzarr, Aogon, aogon, Aopf, aopf, apacir, ap, apE, ape, apid, apos, ApplyFunction, approx, approxeq, Aring, aring, Ascr, ascr, Assign, ast, asymp, asympeq, Atilde, atilde, Auml, auml, awconint, awint, backcong, backepsilon, backprime, backsim, backsimeq, Backslash, Barv, barvee, barwed, Barwed, barwedge, bbrk, bbrktbrk, bcong, Bcy, bcy, bdquo, becaus, because, Because, bemptyv, bepsi, bernou, Bernoullis, Beta, beta, beth, between, Bfr, bfr, bigcap, bigcirc, bigcup, bigodot, bigoplus, bigotimes, bigsqcup, bigstar, bigtriangledown, bigtriangleup, biguplus, bigvee, bigwedge, bkarow, blacklozenge, blacksquare, blacktriangle, blacktriangledown, blacktriangleleft, blacktriangleright, blank, blk12, blk14, blk34, block, bne, bnequiv, bNot, bnot, Bopf, bopf, bot, bottom, bowtie, boxbox, boxdl, boxdL, boxDl, boxDL, boxdr, boxdR, boxDr, boxDR, boxh, boxH, boxhd, boxHd, boxhD, boxHD, boxhu, boxHu, boxhU, boxHU, boxminus, boxplus, boxtimes, boxul, boxuL, boxUl, boxUL, boxur, boxuR, boxUr, boxUR, boxv, boxV, boxvh, boxvH, boxVh, boxVH, boxvl, boxvL, boxVl, boxVL, boxvr, boxvR, boxVr, boxVR, bprime, breve, Breve, brvbar, bscr, Bscr, bsemi, bsim, bsime, bsolb, bsol, bsolhsub, bull, bullet, bump, bumpE, bumpe, Bumpeq, bumpeq, Cacute, cacute, capand, capbrcup, capcap, cap, Cap, capcup, capdot, CapitalDifferentialD, caps, caret, caron, Cayleys, ccaps, Ccaron, ccaron, Ccedil, ccedil, Ccirc, ccirc, Cconint, ccups, ccupssm, Cdot, cdot, cedil, Cedilla, cemptyv, cent, centerdot, CenterDot, cfr, Cfr, CHcy, chcy, check, checkmark, Chi, chi, circ, circeq, circlearrowleft, circlearrowright, circledast, circledcirc, circleddash, CircleDot, circledR, circledS, CircleMinus, CirclePlus, CircleTimes, cir, cirE, cire, cirfnint, cirmid, cirscir, ClockwiseContourIntegral, CloseCurlyDoubleQuote, CloseCurlyQuote, clubs, clubsuit, colon, Colon, Colone, colone, coloneq, comma, commat, comp, compfn, complement, complexes, cong, congdot, Congruent, conint, Conint, ContourIntegral, copf, Copf, coprod, Coproduct, copy, COPY, copysr, CounterClockwiseContourIntegral, crarr, cross, Cross, Cscr, cscr, csub, csube, csup, csupe, ctdot, cudarrl, cudarrr, cuepr, cuesc, cularr, cularrp, cupbrcap, cupcap, CupCap, cup, Cup, cupcup, cupdot, cupor, cups, curarr, curarrm, curlyeqprec, curlyeqsucc, curlyvee, curlywedge, curren, curvearrowleft, curvearrowright, cuvee, cuwed, cwconint, cwint, cylcty, dagger, Dagger, daleth, darr, Darr, dArr, dash, Dashv, dashv, dbkarow, dblac, Dcaron, dcaron, Dcy, dcy, ddagger, ddarr, DD, dd, DDotrahd, ddotseq, deg, Del, Delta, delta, demptyv, dfisht, Dfr, dfr, dHar, dharl, dharr, DiacriticalAcute, DiacriticalDot, DiacriticalDoubleAcute, DiacriticalGrave, DiacriticalTilde, diam, diamond, Diamond, diamondsuit, diams, die, DifferentialD, digamma, disin, div, divide, divideontimes, divonx, DJcy, djcy, dlcorn, dlcrop, dollar, Dopf, dopf, Dot, dot, DotDot, doteq, doteqdot, DotEqual, dotminus, dotplus, dotsquare, doublebarwedge, DoubleContourIntegral, DoubleDot, DoubleDownArrow, DoubleLeftArrow, DoubleLeftRightArrow, DoubleLeftTee, DoubleLongLeftArrow, DoubleLongLeftRightArrow, DoubleLongRightArrow, DoubleRightArrow, DoubleRightTee, DoubleUpArrow, DoubleUpDownArrow, DoubleVerticalBar, DownArrowBar, downarrow, DownArrow, Downarrow, DownArrowUpArrow, DownBreve, downdownarrows, downharpoonleft, downharpoonright, DownLeftRightVector, DownLeftTeeVector, DownLeftVectorBar, DownLeftVector, DownRightTeeVector, DownRightVectorBar, DownRightVector, DownTeeArrow, DownTee, drbkarow, drcorn, drcrop, Dscr, dscr, DScy, dscy, dsol, Dstrok, dstrok, dtdot, dtri, dtrif, duarr, duhar, dwangle, DZcy, dzcy, dzigrarr, Eacute, eacute, easter, Ecaron, ecaron, Ecirc, ecirc, ecir, ecolon, Ecy, ecy, eDDot, Edot, edot, eDot, ee, efDot, Efr, efr, eg, Egrave, egrave, egs, egsdot, el, Element, elinters, ell, els, elsdot, Emacr, emacr, empty, emptyset, EmptySmallSquare, emptyv, EmptyVerySmallSquare, emsp13, emsp14, emsp, ENG, eng, ensp, Eogon, eogon, Eopf, eopf, epar, eparsl, eplus, epsi, Epsilon, epsilon, epsiv, eqcirc, eqcolon, eqsim, eqslantgtr, eqslantless, Equal, equals, EqualTilde, equest, Equilibrium, equiv, equivDD, eqvparsl, erarr, erDot, escr, Escr, esdot, Esim, esim, Eta, eta, ETH, eth, Euml, euml, euro, excl, exist, Exists, expectation, exponentiale, ExponentialE, fallingdotseq, Fcy, fcy, female, ffilig, fflig, ffllig, Ffr, ffr, filig, FilledSmallSquare, FilledVerySmallSquare, fjlig, flat, fllig, fltns, fnof, Fopf, fopf, forall, ForAll, fork, forkv, Fouriertrf, fpartint, frac12, frac13, frac14, frac15, frac16, frac18, frac23, frac25, frac34, frac35, frac38, frac45, frac56, frac58, frac78, frasl, frown, fscr, Fscr, gacute, Gamma, gamma, Gammad, gammad, gap, Gbreve, gbreve, Gcedil, Gcirc, gcirc, Gcy, gcy, Gdot, gdot, ge, gE, gEl, gel, geq, geqq, geqslant, gescc, ges, gesdot, gesdoto, gesdotol, gesl, gesles, Gfr, gfr, gg, Gg, ggg, gimel, GJcy, gjcy, gla, gl, glE, glj, gnap, gnapprox, gne, gnE, gneq, gneqq, gnsim, Gopf, gopf, grave, GreaterEqual, GreaterEqualLess, GreaterFullEqual, GreaterGreater, GreaterLess, GreaterSlantEqual, GreaterTilde, Gscr, gscr, gsim, gsime, gsiml, gtcc, gtcir, gt, GT, Gt, gtdot, gtlPar, gtquest, gtrapprox, gtrarr, gtrdot, gtreqless, gtreqqless, gtrless, gtrsim, gvertneqq, gvnE, Hacek, hairsp, half, hamilt, HARDcy, hardcy, harrcir, harr, hArr, harrw, Hat, hbar, Hcirc, hcirc, hearts, heartsuit, hellip, hercon, hfr, Hfr, HilbertSpace, hksearow, hkswarow, hoarr, homtht, hookleftarrow, hookrightarrow, hopf, Hopf, horbar, HorizontalLine, hscr, Hscr, hslash, Hstrok, hstrok, HumpDownHump, HumpEqual, hybull, hyphen, Iacute, iacute, ic, Icirc, icirc, Icy, icy, Idot, IEcy, iecy, iexcl, iff, ifr, Ifr, Igrave, igrave, ii, iiiint, iiint, iinfin, iiota, IJlig, ijlig, Imacr, imacr, image, ImaginaryI, imagline, imagpart, imath, Im, imof, imped, Implies, incare, in, infin, infintie, inodot, intcal, int, Int, integers, Integral, intercal, Intersection, intlarhk, intprod, InvisibleComma, InvisibleTimes, IOcy, iocy, Iogon, iogon, Iopf, iopf, Iota, iota, iprod, iquest, iscr, Iscr, isin, isindot, isinE, isins, isinsv, isinv, it, Itilde, itilde, Iukcy, iukcy, Iuml, iuml, Jcirc, jcirc, Jcy, jcy, Jfr, jfr, jmath, Jopf, jopf, Jscr, jscr, Jsercy, jsercy, Jukcy, jukcy, Kappa, kappa, kappav, Kcedil, kcedil, Kcy, kcy, Kfr, kfr, kgreen, KHcy, khcy, KJcy, kjcy, Kopf, kopf, Kscr, kscr, lAarr, Lacute, lacute, laemptyv, lagran, Lambda, lambda, lang, Lang, langd, langle, lap, Laplacetrf, laquo, larrb, larrbfs, larr, Larr, lArr, larrfs, larrhk, larrlp, larrpl, larrsim, larrtl, latail, lAtail, lat, late, lates, lbarr, lBarr, lbbrk, lbrace, lbrack, lbrke, lbrksld, lbrkslu, Lcaron, lcaron, Lcedil, lcedil, lceil, lcub, Lcy, lcy, ldca, ldquo, ldquor, ldrdhar, ldrushar, ldsh, le, lE, LeftAngleBracket, LeftArrowBar, leftarrow, LeftArrow, Leftarrow, LeftArrowRightArrow, leftarrowtail, LeftCeiling, LeftDoubleBracket, LeftDownTeeVector, LeftDownVectorBar, LeftDownVector, LeftFloor, leftharpoondown, leftharpoonup, leftleftarrows, leftrightarrow, LeftRightArrow, Leftrightarrow, leftrightarrows, leftrightharpoons, leftrightsquigarrow, LeftRightVector, LeftTeeArrow, LeftTee, LeftTeeVector, leftthreetimes, LeftTriangleBar, LeftTriangle, LeftTriangleEqual, LeftUpDownVector, LeftUpTeeVector, LeftUpVectorBar, LeftUpVector, LeftVectorBar, LeftVector, lEg, leg, leq, leqq, leqslant, lescc, les, lesdot, lesdoto, lesdotor, lesg, lesges, lessapprox, lessdot, lesseqgtr, lesseqqgtr, LessEqualGreater, LessFullEqual, LessGreater, lessgtr, LessLess, lesssim, LessSlantEqual, LessTilde, lfisht, lfloor, Lfr, lfr, lg, lgE, lHar, lhard, lharu, lharul, lhblk, LJcy, ljcy, llarr, ll, Ll, llcorner, Lleftarrow, llhard, lltri, Lmidot, lmidot, lmoustache, lmoust, lnap, lnapprox, lne, lnE, lneq, lneqq, lnsim, loang, loarr, lobrk, longleftarrow, LongLeftArrow, Longleftarrow, longleftrightarrow, LongLeftRightArrow, Longleftrightarrow, longmapsto, longrightarrow, LongRightArrow, Longrightarrow, looparrowleft, looparrowright, lopar, Lopf, lopf, loplus, lotimes, lowast, lowbar, LowerLeftArrow, LowerRightArrow, loz, lozenge, lozf, lpar, lparlt, lrarr, lrcorner, lrhar, lrhard, lrm, lrtri, lsaquo, lscr, Lscr, lsh, Lsh, lsim, lsime, lsimg, lsqb, lsquo, lsquor, Lstrok, lstrok, ltcc, ltcir, lt, LT, Lt, ltdot, lthree, ltimes, ltlarr, ltquest, ltri, ltrie, ltrif, ltrPar, lurdshar, luruhar, lvertneqq, lvnE, macr, male, malt, maltese, Map, map, mapsto, mapstodown, mapstoleft, mapstoup, marker, mcomma, Mcy, mcy, mdash, mDDot, measuredangle, MediumSpace, Mellintrf, Mfr, mfr, mho, micro, midast, midcir, mid, middot, minusb, minus, minusd, minusdu, MinusPlus, mlcp, mldr, mnplus, models, Mopf, mopf, mp, mscr, Mscr, mstpos, Mu, mu, multimap, mumap, nabla, Nacute, nacute, nang, nap, napE, napid, napos, napprox, natural, naturals, natur, nbsp, nbump, nbumpe, ncap, Ncaron, ncaron, Ncedil, ncedil, ncong, ncongdot, ncup, Ncy, ncy, ndash, nearhk, nearr, neArr, nearrow, ne, nedot, NegativeMediumSpace, NegativeThickSpace, NegativeThinSpace, NegativeVeryThinSpace, nequiv, nesear, nesim, NestedGreaterGreater, NestedLessLess, NewLine, nexist, nexists, Nfr, nfr, ngE, nge, ngeq, ngeqq, ngeqslant, nges, nGg, ngsim, nGt, ngt, ngtr, nGtv, nharr, nhArr, nhpar, ni, nis, nisd, niv, NJcy, njcy, nlarr, nlArr, nldr, nlE, nle, nleftarrow, nLeftarrow, nleftrightarrow, nLeftrightarrow, nleq, nleqq, nleqslant, nles, nless, nLl, nlsim, nLt, nlt, nltri, nltrie, nLtv, nmid, NoBreak, NonBreakingSpace, nopf, Nopf, Not, not, NotCongruent, NotCupCap, NotDoubleVerticalBar, NotElement, NotEqual, NotEqualTilde, NotExists, NotGreater, NotGreaterEqual, NotGreaterFullEqual, NotGreaterGreater, NotGreaterLess, NotGreaterSlantEqual, NotGreaterTilde, NotHumpDownHump, NotHumpEqual, notin, notindot, notinE, notinva, notinvb, notinvc, NotLeftTriangleBar, NotLeftTriangle, NotLeftTriangleEqual, NotLess, NotLessEqual, NotLessGreater, NotLessLess, NotLessSlantEqual, NotLessTilde, NotNestedGreaterGreater, NotNestedLessLess, notni, notniva, notnivb, notnivc, NotPrecedes, NotPrecedesEqual, NotPrecedesSlantEqual, NotReverseElement, NotRightTriangleBar, NotRightTriangle, NotRightTriangleEqual, NotSquareSubset, NotSquareSubsetEqual, NotSquareSuperset, NotSquareSupersetEqual, NotSubset, NotSubsetEqual, NotSucceeds, NotSucceedsEqual, NotSucceedsSlantEqual, NotSucceedsTilde, NotSuperset, NotSupersetEqual, NotTilde, NotTildeEqual, NotTildeFullEqual, NotTildeTilde, NotVerticalBar, nparallel, npar, nparsl, npart, npolint, npr, nprcue, nprec, npreceq, npre, nrarrc, nrarr, nrArr, nrarrw, nrightarrow, nRightarrow, nrtri, nrtrie, nsc, nsccue, nsce, Nscr, nscr, nshortmid, nshortparallel, nsim, nsime, nsimeq, nsmid, nspar, nsqsube, nsqsupe, nsub, nsubE, nsube, nsubset, nsubseteq, nsubseteqq, nsucc, nsucceq, nsup, nsupE, nsupe, nsupset, nsupseteq, nsupseteqq, ntgl, Ntilde, ntilde, ntlg, ntriangleleft, ntrianglelefteq, ntriangleright, ntrianglerighteq, Nu, nu, num, numero, numsp, nvap, nvdash, nvDash, nVdash, nVDash, nvge, nvgt, nvHarr, nvinfin, nvlArr, nvle, nvlt, nvltrie, nvrArr, nvrtrie, nvsim, nwarhk, nwarr, nwArr, nwarrow, nwnear, Oacute, oacute, oast, Ocirc, ocirc, ocir, Ocy, ocy, odash, Odblac, odblac, odiv, odot, odsold, OElig, oelig, ofcir, Ofr, ofr, ogon, Ograve, ograve, ogt, ohbar, ohm, oint, olarr, olcir, olcross, oline, olt, Omacr, omacr, Omega, omega, Omicron, omicron, omid, ominus, Oopf, oopf, opar, OpenCurlyDoubleQuote, OpenCurlyQuote, operp, oplus, orarr, Or, or, ord, order, orderof, ordf, ordm, origof, oror, orslope, orv, oS, Oscr, oscr, Oslash, oslash, osol, Otilde, otilde, otimesas, Otimes, otimes, Ouml, ouml, ovbar, OverBar, OverBrace, OverBracket, OverParenthesis, para, parallel, par, parsim, parsl, part, PartialD, Pcy, pcy, percnt, period, permil, perp, pertenk, Pfr, pfr, Phi, phi, phiv, phmmat, phone, Pi, pi, pitchfork, piv, planck, planckh, plankv, plusacir, plusb, pluscir, plus, plusdo, plusdu, pluse, PlusMinus, plusmn, plussim, plustwo, pm, Poincareplane, pointint, popf, Popf, pound, prap, Pr, pr, prcue, precapprox, prec, preccurlyeq, Precedes, PrecedesEqual, PrecedesSlantEqual, PrecedesTilde, preceq, precnapprox, precneqq, precnsim, pre, prE, precsim, prime, Prime, primes, prnap, prnE, prnsim, prod, Product, profalar, profline, profsurf, prop, Proportional, Proportion, propto, prsim, prurel, Pscr, pscr, Psi, psi, puncsp, Qfr, qfr, qint, qopf, Qopf, qprime, Qscr, qscr, quaternions, quatint, quest, questeq, quot, QUOT, rAarr, race, Racute, racute, radic, raemptyv, rang, Rang, rangd, range, rangle, raquo, rarrap, rarrb, rarrbfs, rarrc, rarr, Rarr, rArr, rarrfs, rarrhk, rarrlp, rarrpl, rarrsim, Rarrtl, rarrtl, rarrw, ratail, rAtail, ratio, rationals, rbarr, rBarr, RBarr, rbbrk, rbrace, rbrack, rbrke, rbrksld, rbrkslu, Rcaron, rcaron, Rcedil, rcedil, rceil, rcub, Rcy, rcy, rdca, rdldhar, rdquo, rdquor, rdsh, real, realine, realpart, reals, Re, rect, reg, REG, ReverseElement, ReverseEquilibrium, ReverseUpEquilibrium, rfisht, rfloor, rfr, Rfr, rHar, rhard, rharu, rharul, Rho, rho, rhov, RightAngleBracket, RightArrowBar, rightarrow, RightArrow, Rightarrow, RightArrowLeftArrow, rightarrowtail, RightCeiling, RightDoubleBracket, RightDownTeeVector, RightDownVectorBar, RightDownVector, RightFloor, rightharpoondown, rightharpoonup, rightleftarrows, rightleftharpoons, rightrightarrows, rightsquigarrow, RightTeeArrow, RightTee, RightTeeVector, rightthreetimes, RightTriangleBar, RightTriangle, RightTriangleEqual, RightUpDownVector, RightUpTeeVector, RightUpVectorBar, RightUpVector, RightVectorBar, RightVector, ring, risingdotseq, rlarr, rlhar, rlm, rmoustache, rmoust, rnmid, roang, roarr, robrk, ropar, ropf, Ropf, roplus, rotimes, RoundImplies, rpar, rpargt, rppolint, rrarr, Rrightarrow, rsaquo, rscr, Rscr, rsh, Rsh, rsqb, rsquo, rsquor, rthree, rtimes, rtri, rtrie, rtrif, rtriltri, RuleDelayed, ruluhar, rx, Sacute, sacute, sbquo, scap, Scaron, scaron, Sc, sc, sccue, sce, scE, Scedil, scedil, Scirc, scirc, scnap, scnE, scnsim, scpolint, scsim, Scy, scy, sdotb, sdot, sdote, searhk, searr, seArr, searrow, sect, semi, seswar, setminus, setmn, sext, Sfr, sfr, sfrown, sharp, SHCHcy, shchcy, SHcy, shcy, ShortDownArrow, ShortLeftArrow, shortmid, shortparallel, ShortRightArrow, ShortUpArrow, shy, Sigma, sigma, sigmaf, sigmav, sim, simdot, sime, simeq, simg, simgE, siml, simlE, simne, simplus, simrarr, slarr, SmallCircle, smallsetminus, smashp, smeparsl, smid, smile, smt, smte, smtes, SOFTcy, softcy, solbar, solb, sol, Sopf, sopf, spades, spadesuit, spar, sqcap, sqcaps, sqcup, sqcups, Sqrt, sqsub, sqsube, sqsubset, sqsubseteq, sqsup, sqsupe, sqsupset, sqsupseteq, square, Square, SquareIntersection, SquareSubset, SquareSubsetEqual, SquareSuperset, SquareSupersetEqual, SquareUnion, squarf, squ, squf, srarr, Sscr, sscr, ssetmn, ssmile, sstarf, Star, star, starf, straightepsilon, straightphi, strns, sub, Sub, subdot, subE, sube, subedot, submult, subnE, subne, subplus, subrarr, subset, Subset, subseteq, subseteqq, SubsetEqual, subsetneq, subsetneqq, subsim, subsub, subsup, succapprox, succ, succcurlyeq, Succeeds, SucceedsEqual, SucceedsSlantEqual, SucceedsTilde, succeq, succnapprox, succneqq, succnsim, succsim, SuchThat, sum, Sum, sung, sup1, sup2, sup3, sup, Sup, supdot, supdsub, supE, supe, supedot, Superset, SupersetEqual, suphsol, suphsub, suplarr, supmult, supnE, supne, supplus, supset, Supset, supseteq, supseteqq, supsetneq, supsetneqq, supsim, supsub, supsup, swarhk, swarr, swArr, swarrow, swnwar, szlig, Tab, target, Tau, tau, tbrk, Tcaron, tcaron, Tcedil, tcedil, Tcy, tcy, tdot, telrec, Tfr, tfr, there4, therefore, Therefore, Theta, theta, thetasym, thetav, thickapprox, thicksim, ThickSpace, ThinSpace, thinsp, thkap, thksim, THORN, thorn, tilde, Tilde, TildeEqual, TildeFullEqual, TildeTilde, timesbar, timesb, times, timesd, tint, toea, topbot, topcir, top, Topf, topf, topfork, tosa, tprime, trade, TRADE, triangle, triangledown, triangleleft, trianglelefteq, triangleq, triangleright, trianglerighteq, tridot, trie, triminus, TripleDot, triplus, trisb, tritime, trpezium, Tscr, tscr, TScy, tscy, TSHcy, tshcy, Tstrok, tstrok, twixt, twoheadleftarrow, twoheadrightarrow, Uacute, uacute, uarr, Uarr, uArr, Uarrocir, Ubrcy, ubrcy, Ubreve, ubreve, Ucirc, ucirc, Ucy, ucy, udarr, Udblac, udblac, udhar, ufisht, Ufr, ufr, Ugrave, ugrave, uHar, uharl, uharr, uhblk, ulcorn, ulcorner, ulcrop, ultri, Umacr, umacr, uml, UnderBar, UnderBrace, UnderBracket, UnderParenthesis, Union, UnionPlus, Uogon, uogon, Uopf, uopf, UpArrowBar, uparrow, UpArrow, Uparrow, UpArrowDownArrow, updownarrow, UpDownArrow, Updownarrow, UpEquilibrium, upharpoonleft, upharpoonright, uplus, UpperLeftArrow, UpperRightArrow, upsi, Upsi, upsih, Upsilon, upsilon, UpTeeArrow, UpTee, upuparrows, urcorn, urcorner, urcrop, Uring, uring, urtri, Uscr, uscr, utdot, Utilde, utilde, utri, utrif, uuarr, Uuml, uuml, uwangle, vangrt, varepsilon, varkappa, varnothing, varphi, varpi, varpropto, varr, vArr, varrho, varsigma, varsubsetneq, varsubsetneqq, varsupsetneq, varsupsetneqq, vartheta, vartriangleleft, vartriangleright, vBar, Vbar, vBarv, Vcy, vcy, vdash, vDash, Vdash, VDash, Vdashl, veebar, vee, Vee, veeeq, vellip, verbar, Verbar, vert, Vert, VerticalBar, VerticalLine, VerticalSeparator, VerticalTilde, VeryThinSpace, Vfr, vfr, vltri, vnsub, vnsup, Vopf, vopf, vprop, vrtri, Vscr, vscr, vsubnE, vsubne, vsupnE, vsupne, Vvdash, vzigzag, Wcirc, wcirc, wedbar, wedge, Wedge, wedgeq, weierp, Wfr, wfr, Wopf, wopf, wp, wr, wreath, Wscr, wscr, xcap, xcirc, xcup, xdtri, Xfr, xfr, xharr, xhArr, Xi, xi, xlarr, xlArr, xmap, xnis, xodot, Xopf, xopf, xoplus, xotime, xrarr, xrArr, Xscr, xscr, xsqcup, xuplus, xutri, xvee, xwedge, Yacute, yacute, YAcy, yacy, Ycirc, ycirc, Ycy, ycy, yen, Yfr, yfr, YIcy, yicy, Yopf, yopf, Yscr, yscr, YUcy, yucy, yuml, Yuml, Zacute, zacute, Zcaron, zcaron, Zcy, zcy, Zdot, zdot, zeetrf, ZeroWidthSpace, Zeta, zeta, zfr, Zfr, ZHcy, zhcy, zigrarr, zopf, Zopf, Zscr, zscr, zwj, zwnj, default */ -/***/ (function(module) { - -module.exports = JSON.parse("{\"Aacute\":\"Á\",\"aacute\":\"á\",\"Abreve\":\"Ă\",\"abreve\":\"ă\",\"ac\":\"∾\",\"acd\":\"∿\",\"acE\":\"∾̳\",\"Acirc\":\"Â\",\"acirc\":\"â\",\"acute\":\"´\",\"Acy\":\"А\",\"acy\":\"а\",\"AElig\":\"Æ\",\"aelig\":\"æ\",\"af\":\"⁡\",\"Afr\":\"𝔄\",\"afr\":\"𝔞\",\"Agrave\":\"À\",\"agrave\":\"à\",\"alefsym\":\"ℵ\",\"aleph\":\"ℵ\",\"Alpha\":\"Α\",\"alpha\":\"α\",\"Amacr\":\"Ā\",\"amacr\":\"ā\",\"amalg\":\"⨿\",\"amp\":\"&\",\"AMP\":\"&\",\"andand\":\"⩕\",\"And\":\"⩓\",\"and\":\"∧\",\"andd\":\"⩜\",\"andslope\":\"⩘\",\"andv\":\"⩚\",\"ang\":\"∠\",\"ange\":\"⦤\",\"angle\":\"∠\",\"angmsdaa\":\"⦨\",\"angmsdab\":\"⦩\",\"angmsdac\":\"⦪\",\"angmsdad\":\"⦫\",\"angmsdae\":\"⦬\",\"angmsdaf\":\"⦭\",\"angmsdag\":\"⦮\",\"angmsdah\":\"⦯\",\"angmsd\":\"∡\",\"angrt\":\"∟\",\"angrtvb\":\"⊾\",\"angrtvbd\":\"⦝\",\"angsph\":\"∢\",\"angst\":\"Å\",\"angzarr\":\"⍼\",\"Aogon\":\"Ą\",\"aogon\":\"ą\",\"Aopf\":\"𝔸\",\"aopf\":\"𝕒\",\"apacir\":\"⩯\",\"ap\":\"≈\",\"apE\":\"⩰\",\"ape\":\"≊\",\"apid\":\"≋\",\"apos\":\"'\",\"ApplyFunction\":\"⁡\",\"approx\":\"≈\",\"approxeq\":\"≊\",\"Aring\":\"Å\",\"aring\":\"å\",\"Ascr\":\"𝒜\",\"ascr\":\"𝒶\",\"Assign\":\"≔\",\"ast\":\"*\",\"asymp\":\"≈\",\"asympeq\":\"≍\",\"Atilde\":\"Ã\",\"atilde\":\"ã\",\"Auml\":\"Ä\",\"auml\":\"ä\",\"awconint\":\"∳\",\"awint\":\"⨑\",\"backcong\":\"≌\",\"backepsilon\":\"϶\",\"backprime\":\"‵\",\"backsim\":\"∽\",\"backsimeq\":\"⋍\",\"Backslash\":\"∖\",\"Barv\":\"⫧\",\"barvee\":\"⊽\",\"barwed\":\"⌅\",\"Barwed\":\"⌆\",\"barwedge\":\"⌅\",\"bbrk\":\"⎵\",\"bbrktbrk\":\"⎶\",\"bcong\":\"≌\",\"Bcy\":\"Б\",\"bcy\":\"б\",\"bdquo\":\"„\",\"becaus\":\"∵\",\"because\":\"∵\",\"Because\":\"∵\",\"bemptyv\":\"⦰\",\"bepsi\":\"϶\",\"bernou\":\"ℬ\",\"Bernoullis\":\"ℬ\",\"Beta\":\"Β\",\"beta\":\"β\",\"beth\":\"ℶ\",\"between\":\"≬\",\"Bfr\":\"𝔅\",\"bfr\":\"𝔟\",\"bigcap\":\"⋂\",\"bigcirc\":\"◯\",\"bigcup\":\"⋃\",\"bigodot\":\"⨀\",\"bigoplus\":\"⨁\",\"bigotimes\":\"⨂\",\"bigsqcup\":\"⨆\",\"bigstar\":\"★\",\"bigtriangledown\":\"▽\",\"bigtriangleup\":\"△\",\"biguplus\":\"⨄\",\"bigvee\":\"⋁\",\"bigwedge\":\"⋀\",\"bkarow\":\"⤍\",\"blacklozenge\":\"⧫\",\"blacksquare\":\"▪\",\"blacktriangle\":\"▴\",\"blacktriangledown\":\"▾\",\"blacktriangleleft\":\"◂\",\"blacktriangleright\":\"▸\",\"blank\":\"␣\",\"blk12\":\"▒\",\"blk14\":\"░\",\"blk34\":\"▓\",\"block\":\"█\",\"bne\":\"=⃥\",\"bnequiv\":\"≡⃥\",\"bNot\":\"⫭\",\"bnot\":\"⌐\",\"Bopf\":\"𝔹\",\"bopf\":\"𝕓\",\"bot\":\"⊥\",\"bottom\":\"⊥\",\"bowtie\":\"⋈\",\"boxbox\":\"⧉\",\"boxdl\":\"┐\",\"boxdL\":\"╕\",\"boxDl\":\"╖\",\"boxDL\":\"╗\",\"boxdr\":\"┌\",\"boxdR\":\"╒\",\"boxDr\":\"╓\",\"boxDR\":\"╔\",\"boxh\":\"─\",\"boxH\":\"═\",\"boxhd\":\"┬\",\"boxHd\":\"╤\",\"boxhD\":\"╥\",\"boxHD\":\"╦\",\"boxhu\":\"┴\",\"boxHu\":\"╧\",\"boxhU\":\"╨\",\"boxHU\":\"╩\",\"boxminus\":\"⊟\",\"boxplus\":\"⊞\",\"boxtimes\":\"⊠\",\"boxul\":\"┘\",\"boxuL\":\"╛\",\"boxUl\":\"╜\",\"boxUL\":\"╝\",\"boxur\":\"└\",\"boxuR\":\"╘\",\"boxUr\":\"╙\",\"boxUR\":\"╚\",\"boxv\":\"│\",\"boxV\":\"║\",\"boxvh\":\"┼\",\"boxvH\":\"╪\",\"boxVh\":\"╫\",\"boxVH\":\"╬\",\"boxvl\":\"┤\",\"boxvL\":\"╡\",\"boxVl\":\"╢\",\"boxVL\":\"╣\",\"boxvr\":\"├\",\"boxvR\":\"╞\",\"boxVr\":\"╟\",\"boxVR\":\"╠\",\"bprime\":\"‵\",\"breve\":\"˘\",\"Breve\":\"˘\",\"brvbar\":\"¦\",\"bscr\":\"𝒷\",\"Bscr\":\"ℬ\",\"bsemi\":\"⁏\",\"bsim\":\"∽\",\"bsime\":\"⋍\",\"bsolb\":\"⧅\",\"bsol\":\"\\\\\",\"bsolhsub\":\"⟈\",\"bull\":\"•\",\"bullet\":\"•\",\"bump\":\"≎\",\"bumpE\":\"⪮\",\"bumpe\":\"≏\",\"Bumpeq\":\"≎\",\"bumpeq\":\"≏\",\"Cacute\":\"Ć\",\"cacute\":\"ć\",\"capand\":\"⩄\",\"capbrcup\":\"⩉\",\"capcap\":\"⩋\",\"cap\":\"∩\",\"Cap\":\"⋒\",\"capcup\":\"⩇\",\"capdot\":\"⩀\",\"CapitalDifferentialD\":\"ⅅ\",\"caps\":\"∩︀\",\"caret\":\"⁁\",\"caron\":\"ˇ\",\"Cayleys\":\"ℭ\",\"ccaps\":\"⩍\",\"Ccaron\":\"Č\",\"ccaron\":\"č\",\"Ccedil\":\"Ç\",\"ccedil\":\"ç\",\"Ccirc\":\"Ĉ\",\"ccirc\":\"ĉ\",\"Cconint\":\"∰\",\"ccups\":\"⩌\",\"ccupssm\":\"⩐\",\"Cdot\":\"Ċ\",\"cdot\":\"ċ\",\"cedil\":\"¸\",\"Cedilla\":\"¸\",\"cemptyv\":\"⦲\",\"cent\":\"¢\",\"centerdot\":\"·\",\"CenterDot\":\"·\",\"cfr\":\"𝔠\",\"Cfr\":\"ℭ\",\"CHcy\":\"Ч\",\"chcy\":\"ч\",\"check\":\"✓\",\"checkmark\":\"✓\",\"Chi\":\"Χ\",\"chi\":\"χ\",\"circ\":\"ˆ\",\"circeq\":\"≗\",\"circlearrowleft\":\"↺\",\"circlearrowright\":\"↻\",\"circledast\":\"⊛\",\"circledcirc\":\"⊚\",\"circleddash\":\"⊝\",\"CircleDot\":\"⊙\",\"circledR\":\"®\",\"circledS\":\"Ⓢ\",\"CircleMinus\":\"⊖\",\"CirclePlus\":\"⊕\",\"CircleTimes\":\"⊗\",\"cir\":\"○\",\"cirE\":\"⧃\",\"cire\":\"≗\",\"cirfnint\":\"⨐\",\"cirmid\":\"⫯\",\"cirscir\":\"⧂\",\"ClockwiseContourIntegral\":\"∲\",\"CloseCurlyDoubleQuote\":\"”\",\"CloseCurlyQuote\":\"’\",\"clubs\":\"♣\",\"clubsuit\":\"♣\",\"colon\":\":\",\"Colon\":\"∷\",\"Colone\":\"⩴\",\"colone\":\"≔\",\"coloneq\":\"≔\",\"comma\":\",\",\"commat\":\"@\",\"comp\":\"∁\",\"compfn\":\"∘\",\"complement\":\"∁\",\"complexes\":\"ℂ\",\"cong\":\"≅\",\"congdot\":\"⩭\",\"Congruent\":\"≡\",\"conint\":\"∮\",\"Conint\":\"∯\",\"ContourIntegral\":\"∮\",\"copf\":\"𝕔\",\"Copf\":\"ℂ\",\"coprod\":\"∐\",\"Coproduct\":\"∐\",\"copy\":\"©\",\"COPY\":\"©\",\"copysr\":\"℗\",\"CounterClockwiseContourIntegral\":\"∳\",\"crarr\":\"↵\",\"cross\":\"✗\",\"Cross\":\"⨯\",\"Cscr\":\"𝒞\",\"cscr\":\"𝒸\",\"csub\":\"⫏\",\"csube\":\"⫑\",\"csup\":\"⫐\",\"csupe\":\"⫒\",\"ctdot\":\"⋯\",\"cudarrl\":\"⤸\",\"cudarrr\":\"⤵\",\"cuepr\":\"⋞\",\"cuesc\":\"⋟\",\"cularr\":\"↶\",\"cularrp\":\"⤽\",\"cupbrcap\":\"⩈\",\"cupcap\":\"⩆\",\"CupCap\":\"≍\",\"cup\":\"∪\",\"Cup\":\"⋓\",\"cupcup\":\"⩊\",\"cupdot\":\"⊍\",\"cupor\":\"⩅\",\"cups\":\"∪︀\",\"curarr\":\"↷\",\"curarrm\":\"⤼\",\"curlyeqprec\":\"⋞\",\"curlyeqsucc\":\"⋟\",\"curlyvee\":\"⋎\",\"curlywedge\":\"⋏\",\"curren\":\"¤\",\"curvearrowleft\":\"↶\",\"curvearrowright\":\"↷\",\"cuvee\":\"⋎\",\"cuwed\":\"⋏\",\"cwconint\":\"∲\",\"cwint\":\"∱\",\"cylcty\":\"⌭\",\"dagger\":\"†\",\"Dagger\":\"‡\",\"daleth\":\"ℸ\",\"darr\":\"↓\",\"Darr\":\"↡\",\"dArr\":\"⇓\",\"dash\":\"‐\",\"Dashv\":\"⫤\",\"dashv\":\"⊣\",\"dbkarow\":\"⤏\",\"dblac\":\"˝\",\"Dcaron\":\"Ď\",\"dcaron\":\"ď\",\"Dcy\":\"Д\",\"dcy\":\"д\",\"ddagger\":\"‡\",\"ddarr\":\"⇊\",\"DD\":\"ⅅ\",\"dd\":\"ⅆ\",\"DDotrahd\":\"⤑\",\"ddotseq\":\"⩷\",\"deg\":\"°\",\"Del\":\"∇\",\"Delta\":\"Δ\",\"delta\":\"δ\",\"demptyv\":\"⦱\",\"dfisht\":\"⥿\",\"Dfr\":\"𝔇\",\"dfr\":\"𝔡\",\"dHar\":\"⥥\",\"dharl\":\"⇃\",\"dharr\":\"⇂\",\"DiacriticalAcute\":\"´\",\"DiacriticalDot\":\"˙\",\"DiacriticalDoubleAcute\":\"˝\",\"DiacriticalGrave\":\"`\",\"DiacriticalTilde\":\"˜\",\"diam\":\"⋄\",\"diamond\":\"⋄\",\"Diamond\":\"⋄\",\"diamondsuit\":\"♦\",\"diams\":\"♦\",\"die\":\"¨\",\"DifferentialD\":\"ⅆ\",\"digamma\":\"ϝ\",\"disin\":\"⋲\",\"div\":\"÷\",\"divide\":\"÷\",\"divideontimes\":\"⋇\",\"divonx\":\"⋇\",\"DJcy\":\"Ђ\",\"djcy\":\"ђ\",\"dlcorn\":\"⌞\",\"dlcrop\":\"⌍\",\"dollar\":\"$\",\"Dopf\":\"𝔻\",\"dopf\":\"𝕕\",\"Dot\":\"¨\",\"dot\":\"˙\",\"DotDot\":\"⃜\",\"doteq\":\"≐\",\"doteqdot\":\"≑\",\"DotEqual\":\"≐\",\"dotminus\":\"∸\",\"dotplus\":\"∔\",\"dotsquare\":\"⊡\",\"doublebarwedge\":\"⌆\",\"DoubleContourIntegral\":\"∯\",\"DoubleDot\":\"¨\",\"DoubleDownArrow\":\"⇓\",\"DoubleLeftArrow\":\"⇐\",\"DoubleLeftRightArrow\":\"⇔\",\"DoubleLeftTee\":\"⫤\",\"DoubleLongLeftArrow\":\"⟸\",\"DoubleLongLeftRightArrow\":\"⟺\",\"DoubleLongRightArrow\":\"⟹\",\"DoubleRightArrow\":\"⇒\",\"DoubleRightTee\":\"⊨\",\"DoubleUpArrow\":\"⇑\",\"DoubleUpDownArrow\":\"⇕\",\"DoubleVerticalBar\":\"∥\",\"DownArrowBar\":\"⤓\",\"downarrow\":\"↓\",\"DownArrow\":\"↓\",\"Downarrow\":\"⇓\",\"DownArrowUpArrow\":\"⇵\",\"DownBreve\":\"̑\",\"downdownarrows\":\"⇊\",\"downharpoonleft\":\"⇃\",\"downharpoonright\":\"⇂\",\"DownLeftRightVector\":\"⥐\",\"DownLeftTeeVector\":\"⥞\",\"DownLeftVectorBar\":\"⥖\",\"DownLeftVector\":\"↽\",\"DownRightTeeVector\":\"⥟\",\"DownRightVectorBar\":\"⥗\",\"DownRightVector\":\"⇁\",\"DownTeeArrow\":\"↧\",\"DownTee\":\"⊤\",\"drbkarow\":\"⤐\",\"drcorn\":\"⌟\",\"drcrop\":\"⌌\",\"Dscr\":\"𝒟\",\"dscr\":\"𝒹\",\"DScy\":\"Ѕ\",\"dscy\":\"ѕ\",\"dsol\":\"⧶\",\"Dstrok\":\"Đ\",\"dstrok\":\"đ\",\"dtdot\":\"⋱\",\"dtri\":\"▿\",\"dtrif\":\"▾\",\"duarr\":\"⇵\",\"duhar\":\"⥯\",\"dwangle\":\"⦦\",\"DZcy\":\"Џ\",\"dzcy\":\"џ\",\"dzigrarr\":\"⟿\",\"Eacute\":\"É\",\"eacute\":\"é\",\"easter\":\"⩮\",\"Ecaron\":\"Ě\",\"ecaron\":\"ě\",\"Ecirc\":\"Ê\",\"ecirc\":\"ê\",\"ecir\":\"≖\",\"ecolon\":\"≕\",\"Ecy\":\"Э\",\"ecy\":\"э\",\"eDDot\":\"⩷\",\"Edot\":\"Ė\",\"edot\":\"ė\",\"eDot\":\"≑\",\"ee\":\"ⅇ\",\"efDot\":\"≒\",\"Efr\":\"𝔈\",\"efr\":\"𝔢\",\"eg\":\"⪚\",\"Egrave\":\"È\",\"egrave\":\"è\",\"egs\":\"⪖\",\"egsdot\":\"⪘\",\"el\":\"⪙\",\"Element\":\"∈\",\"elinters\":\"⏧\",\"ell\":\"ℓ\",\"els\":\"⪕\",\"elsdot\":\"⪗\",\"Emacr\":\"Ē\",\"emacr\":\"ē\",\"empty\":\"∅\",\"emptyset\":\"∅\",\"EmptySmallSquare\":\"◻\",\"emptyv\":\"∅\",\"EmptyVerySmallSquare\":\"▫\",\"emsp13\":\" \",\"emsp14\":\" \",\"emsp\":\" \",\"ENG\":\"Ŋ\",\"eng\":\"ŋ\",\"ensp\":\" \",\"Eogon\":\"Ę\",\"eogon\":\"ę\",\"Eopf\":\"𝔼\",\"eopf\":\"𝕖\",\"epar\":\"⋕\",\"eparsl\":\"⧣\",\"eplus\":\"⩱\",\"epsi\":\"ε\",\"Epsilon\":\"Ε\",\"epsilon\":\"ε\",\"epsiv\":\"ϵ\",\"eqcirc\":\"≖\",\"eqcolon\":\"≕\",\"eqsim\":\"≂\",\"eqslantgtr\":\"⪖\",\"eqslantless\":\"⪕\",\"Equal\":\"⩵\",\"equals\":\"=\",\"EqualTilde\":\"≂\",\"equest\":\"≟\",\"Equilibrium\":\"⇌\",\"equiv\":\"≡\",\"equivDD\":\"⩸\",\"eqvparsl\":\"⧥\",\"erarr\":\"⥱\",\"erDot\":\"≓\",\"escr\":\"ℯ\",\"Escr\":\"ℰ\",\"esdot\":\"≐\",\"Esim\":\"⩳\",\"esim\":\"≂\",\"Eta\":\"Η\",\"eta\":\"η\",\"ETH\":\"Ð\",\"eth\":\"ð\",\"Euml\":\"Ë\",\"euml\":\"ë\",\"euro\":\"€\",\"excl\":\"!\",\"exist\":\"∃\",\"Exists\":\"∃\",\"expectation\":\"ℰ\",\"exponentiale\":\"ⅇ\",\"ExponentialE\":\"ⅇ\",\"fallingdotseq\":\"≒\",\"Fcy\":\"Ф\",\"fcy\":\"ф\",\"female\":\"♀\",\"ffilig\":\"ffi\",\"fflig\":\"ff\",\"ffllig\":\"ffl\",\"Ffr\":\"𝔉\",\"ffr\":\"𝔣\",\"filig\":\"fi\",\"FilledSmallSquare\":\"◼\",\"FilledVerySmallSquare\":\"▪\",\"fjlig\":\"fj\",\"flat\":\"♭\",\"fllig\":\"fl\",\"fltns\":\"▱\",\"fnof\":\"ƒ\",\"Fopf\":\"𝔽\",\"fopf\":\"𝕗\",\"forall\":\"∀\",\"ForAll\":\"∀\",\"fork\":\"⋔\",\"forkv\":\"⫙\",\"Fouriertrf\":\"ℱ\",\"fpartint\":\"⨍\",\"frac12\":\"½\",\"frac13\":\"⅓\",\"frac14\":\"¼\",\"frac15\":\"⅕\",\"frac16\":\"⅙\",\"frac18\":\"⅛\",\"frac23\":\"⅔\",\"frac25\":\"⅖\",\"frac34\":\"¾\",\"frac35\":\"⅗\",\"frac38\":\"⅜\",\"frac45\":\"⅘\",\"frac56\":\"⅚\",\"frac58\":\"⅝\",\"frac78\":\"⅞\",\"frasl\":\"⁄\",\"frown\":\"⌢\",\"fscr\":\"𝒻\",\"Fscr\":\"ℱ\",\"gacute\":\"ǵ\",\"Gamma\":\"Γ\",\"gamma\":\"γ\",\"Gammad\":\"Ϝ\",\"gammad\":\"ϝ\",\"gap\":\"⪆\",\"Gbreve\":\"Ğ\",\"gbreve\":\"ğ\",\"Gcedil\":\"Ģ\",\"Gcirc\":\"Ĝ\",\"gcirc\":\"ĝ\",\"Gcy\":\"Г\",\"gcy\":\"г\",\"Gdot\":\"Ġ\",\"gdot\":\"ġ\",\"ge\":\"≥\",\"gE\":\"≧\",\"gEl\":\"⪌\",\"gel\":\"⋛\",\"geq\":\"≥\",\"geqq\":\"≧\",\"geqslant\":\"⩾\",\"gescc\":\"⪩\",\"ges\":\"⩾\",\"gesdot\":\"⪀\",\"gesdoto\":\"⪂\",\"gesdotol\":\"⪄\",\"gesl\":\"⋛︀\",\"gesles\":\"⪔\",\"Gfr\":\"𝔊\",\"gfr\":\"𝔤\",\"gg\":\"≫\",\"Gg\":\"⋙\",\"ggg\":\"⋙\",\"gimel\":\"ℷ\",\"GJcy\":\"Ѓ\",\"gjcy\":\"ѓ\",\"gla\":\"⪥\",\"gl\":\"≷\",\"glE\":\"⪒\",\"glj\":\"⪤\",\"gnap\":\"⪊\",\"gnapprox\":\"⪊\",\"gne\":\"⪈\",\"gnE\":\"≩\",\"gneq\":\"⪈\",\"gneqq\":\"≩\",\"gnsim\":\"⋧\",\"Gopf\":\"𝔾\",\"gopf\":\"𝕘\",\"grave\":\"`\",\"GreaterEqual\":\"≥\",\"GreaterEqualLess\":\"⋛\",\"GreaterFullEqual\":\"≧\",\"GreaterGreater\":\"⪢\",\"GreaterLess\":\"≷\",\"GreaterSlantEqual\":\"⩾\",\"GreaterTilde\":\"≳\",\"Gscr\":\"𝒢\",\"gscr\":\"ℊ\",\"gsim\":\"≳\",\"gsime\":\"⪎\",\"gsiml\":\"⪐\",\"gtcc\":\"⪧\",\"gtcir\":\"⩺\",\"gt\":\">\",\"GT\":\">\",\"Gt\":\"≫\",\"gtdot\":\"⋗\",\"gtlPar\":\"⦕\",\"gtquest\":\"⩼\",\"gtrapprox\":\"⪆\",\"gtrarr\":\"⥸\",\"gtrdot\":\"⋗\",\"gtreqless\":\"⋛\",\"gtreqqless\":\"⪌\",\"gtrless\":\"≷\",\"gtrsim\":\"≳\",\"gvertneqq\":\"≩︀\",\"gvnE\":\"≩︀\",\"Hacek\":\"ˇ\",\"hairsp\":\" \",\"half\":\"½\",\"hamilt\":\"ℋ\",\"HARDcy\":\"Ъ\",\"hardcy\":\"ъ\",\"harrcir\":\"⥈\",\"harr\":\"↔\",\"hArr\":\"⇔\",\"harrw\":\"↭\",\"Hat\":\"^\",\"hbar\":\"ℏ\",\"Hcirc\":\"Ĥ\",\"hcirc\":\"ĥ\",\"hearts\":\"♥\",\"heartsuit\":\"♥\",\"hellip\":\"…\",\"hercon\":\"⊹\",\"hfr\":\"𝔥\",\"Hfr\":\"ℌ\",\"HilbertSpace\":\"ℋ\",\"hksearow\":\"⤥\",\"hkswarow\":\"⤦\",\"hoarr\":\"⇿\",\"homtht\":\"∻\",\"hookleftarrow\":\"↩\",\"hookrightarrow\":\"↪\",\"hopf\":\"𝕙\",\"Hopf\":\"ℍ\",\"horbar\":\"―\",\"HorizontalLine\":\"─\",\"hscr\":\"𝒽\",\"Hscr\":\"ℋ\",\"hslash\":\"ℏ\",\"Hstrok\":\"Ħ\",\"hstrok\":\"ħ\",\"HumpDownHump\":\"≎\",\"HumpEqual\":\"≏\",\"hybull\":\"⁃\",\"hyphen\":\"‐\",\"Iacute\":\"Í\",\"iacute\":\"í\",\"ic\":\"⁣\",\"Icirc\":\"Î\",\"icirc\":\"î\",\"Icy\":\"И\",\"icy\":\"и\",\"Idot\":\"İ\",\"IEcy\":\"Е\",\"iecy\":\"е\",\"iexcl\":\"¡\",\"iff\":\"⇔\",\"ifr\":\"𝔦\",\"Ifr\":\"ℑ\",\"Igrave\":\"Ì\",\"igrave\":\"ì\",\"ii\":\"ⅈ\",\"iiiint\":\"⨌\",\"iiint\":\"∭\",\"iinfin\":\"⧜\",\"iiota\":\"℩\",\"IJlig\":\"IJ\",\"ijlig\":\"ij\",\"Imacr\":\"Ī\",\"imacr\":\"ī\",\"image\":\"ℑ\",\"ImaginaryI\":\"ⅈ\",\"imagline\":\"ℐ\",\"imagpart\":\"ℑ\",\"imath\":\"ı\",\"Im\":\"ℑ\",\"imof\":\"⊷\",\"imped\":\"Ƶ\",\"Implies\":\"⇒\",\"incare\":\"℅\",\"in\":\"∈\",\"infin\":\"∞\",\"infintie\":\"⧝\",\"inodot\":\"ı\",\"intcal\":\"⊺\",\"int\":\"∫\",\"Int\":\"∬\",\"integers\":\"ℤ\",\"Integral\":\"∫\",\"intercal\":\"⊺\",\"Intersection\":\"⋂\",\"intlarhk\":\"⨗\",\"intprod\":\"⨼\",\"InvisibleComma\":\"⁣\",\"InvisibleTimes\":\"⁢\",\"IOcy\":\"Ё\",\"iocy\":\"ё\",\"Iogon\":\"Į\",\"iogon\":\"į\",\"Iopf\":\"𝕀\",\"iopf\":\"𝕚\",\"Iota\":\"Ι\",\"iota\":\"ι\",\"iprod\":\"⨼\",\"iquest\":\"¿\",\"iscr\":\"𝒾\",\"Iscr\":\"ℐ\",\"isin\":\"∈\",\"isindot\":\"⋵\",\"isinE\":\"⋹\",\"isins\":\"⋴\",\"isinsv\":\"⋳\",\"isinv\":\"∈\",\"it\":\"⁢\",\"Itilde\":\"Ĩ\",\"itilde\":\"ĩ\",\"Iukcy\":\"І\",\"iukcy\":\"і\",\"Iuml\":\"Ï\",\"iuml\":\"ï\",\"Jcirc\":\"Ĵ\",\"jcirc\":\"ĵ\",\"Jcy\":\"Й\",\"jcy\":\"й\",\"Jfr\":\"𝔍\",\"jfr\":\"𝔧\",\"jmath\":\"ȷ\",\"Jopf\":\"𝕁\",\"jopf\":\"𝕛\",\"Jscr\":\"𝒥\",\"jscr\":\"𝒿\",\"Jsercy\":\"Ј\",\"jsercy\":\"ј\",\"Jukcy\":\"Є\",\"jukcy\":\"є\",\"Kappa\":\"Κ\",\"kappa\":\"κ\",\"kappav\":\"ϰ\",\"Kcedil\":\"Ķ\",\"kcedil\":\"ķ\",\"Kcy\":\"К\",\"kcy\":\"к\",\"Kfr\":\"𝔎\",\"kfr\":\"𝔨\",\"kgreen\":\"ĸ\",\"KHcy\":\"Х\",\"khcy\":\"х\",\"KJcy\":\"Ќ\",\"kjcy\":\"ќ\",\"Kopf\":\"𝕂\",\"kopf\":\"𝕜\",\"Kscr\":\"𝒦\",\"kscr\":\"𝓀\",\"lAarr\":\"⇚\",\"Lacute\":\"Ĺ\",\"lacute\":\"ĺ\",\"laemptyv\":\"⦴\",\"lagran\":\"ℒ\",\"Lambda\":\"Λ\",\"lambda\":\"λ\",\"lang\":\"⟨\",\"Lang\":\"⟪\",\"langd\":\"⦑\",\"langle\":\"⟨\",\"lap\":\"⪅\",\"Laplacetrf\":\"ℒ\",\"laquo\":\"«\",\"larrb\":\"⇤\",\"larrbfs\":\"⤟\",\"larr\":\"←\",\"Larr\":\"↞\",\"lArr\":\"⇐\",\"larrfs\":\"⤝\",\"larrhk\":\"↩\",\"larrlp\":\"↫\",\"larrpl\":\"⤹\",\"larrsim\":\"⥳\",\"larrtl\":\"↢\",\"latail\":\"⤙\",\"lAtail\":\"⤛\",\"lat\":\"⪫\",\"late\":\"⪭\",\"lates\":\"⪭︀\",\"lbarr\":\"⤌\",\"lBarr\":\"⤎\",\"lbbrk\":\"❲\",\"lbrace\":\"{\",\"lbrack\":\"[\",\"lbrke\":\"⦋\",\"lbrksld\":\"⦏\",\"lbrkslu\":\"⦍\",\"Lcaron\":\"Ľ\",\"lcaron\":\"ľ\",\"Lcedil\":\"Ļ\",\"lcedil\":\"ļ\",\"lceil\":\"⌈\",\"lcub\":\"{\",\"Lcy\":\"Л\",\"lcy\":\"л\",\"ldca\":\"⤶\",\"ldquo\":\"“\",\"ldquor\":\"„\",\"ldrdhar\":\"⥧\",\"ldrushar\":\"⥋\",\"ldsh\":\"↲\",\"le\":\"≤\",\"lE\":\"≦\",\"LeftAngleBracket\":\"⟨\",\"LeftArrowBar\":\"⇤\",\"leftarrow\":\"←\",\"LeftArrow\":\"←\",\"Leftarrow\":\"⇐\",\"LeftArrowRightArrow\":\"⇆\",\"leftarrowtail\":\"↢\",\"LeftCeiling\":\"⌈\",\"LeftDoubleBracket\":\"⟦\",\"LeftDownTeeVector\":\"⥡\",\"LeftDownVectorBar\":\"⥙\",\"LeftDownVector\":\"⇃\",\"LeftFloor\":\"⌊\",\"leftharpoondown\":\"↽\",\"leftharpoonup\":\"↼\",\"leftleftarrows\":\"⇇\",\"leftrightarrow\":\"↔\",\"LeftRightArrow\":\"↔\",\"Leftrightarrow\":\"⇔\",\"leftrightarrows\":\"⇆\",\"leftrightharpoons\":\"⇋\",\"leftrightsquigarrow\":\"↭\",\"LeftRightVector\":\"⥎\",\"LeftTeeArrow\":\"↤\",\"LeftTee\":\"⊣\",\"LeftTeeVector\":\"⥚\",\"leftthreetimes\":\"⋋\",\"LeftTriangleBar\":\"⧏\",\"LeftTriangle\":\"⊲\",\"LeftTriangleEqual\":\"⊴\",\"LeftUpDownVector\":\"⥑\",\"LeftUpTeeVector\":\"⥠\",\"LeftUpVectorBar\":\"⥘\",\"LeftUpVector\":\"↿\",\"LeftVectorBar\":\"⥒\",\"LeftVector\":\"↼\",\"lEg\":\"⪋\",\"leg\":\"⋚\",\"leq\":\"≤\",\"leqq\":\"≦\",\"leqslant\":\"⩽\",\"lescc\":\"⪨\",\"les\":\"⩽\",\"lesdot\":\"⩿\",\"lesdoto\":\"⪁\",\"lesdotor\":\"⪃\",\"lesg\":\"⋚︀\",\"lesges\":\"⪓\",\"lessapprox\":\"⪅\",\"lessdot\":\"⋖\",\"lesseqgtr\":\"⋚\",\"lesseqqgtr\":\"⪋\",\"LessEqualGreater\":\"⋚\",\"LessFullEqual\":\"≦\",\"LessGreater\":\"≶\",\"lessgtr\":\"≶\",\"LessLess\":\"⪡\",\"lesssim\":\"≲\",\"LessSlantEqual\":\"⩽\",\"LessTilde\":\"≲\",\"lfisht\":\"⥼\",\"lfloor\":\"⌊\",\"Lfr\":\"𝔏\",\"lfr\":\"𝔩\",\"lg\":\"≶\",\"lgE\":\"⪑\",\"lHar\":\"⥢\",\"lhard\":\"↽\",\"lharu\":\"↼\",\"lharul\":\"⥪\",\"lhblk\":\"▄\",\"LJcy\":\"Љ\",\"ljcy\":\"љ\",\"llarr\":\"⇇\",\"ll\":\"≪\",\"Ll\":\"⋘\",\"llcorner\":\"⌞\",\"Lleftarrow\":\"⇚\",\"llhard\":\"⥫\",\"lltri\":\"◺\",\"Lmidot\":\"Ŀ\",\"lmidot\":\"ŀ\",\"lmoustache\":\"⎰\",\"lmoust\":\"⎰\",\"lnap\":\"⪉\",\"lnapprox\":\"⪉\",\"lne\":\"⪇\",\"lnE\":\"≨\",\"lneq\":\"⪇\",\"lneqq\":\"≨\",\"lnsim\":\"⋦\",\"loang\":\"⟬\",\"loarr\":\"⇽\",\"lobrk\":\"⟦\",\"longleftarrow\":\"⟵\",\"LongLeftArrow\":\"⟵\",\"Longleftarrow\":\"⟸\",\"longleftrightarrow\":\"⟷\",\"LongLeftRightArrow\":\"⟷\",\"Longleftrightarrow\":\"⟺\",\"longmapsto\":\"⟼\",\"longrightarrow\":\"⟶\",\"LongRightArrow\":\"⟶\",\"Longrightarrow\":\"⟹\",\"looparrowleft\":\"↫\",\"looparrowright\":\"↬\",\"lopar\":\"⦅\",\"Lopf\":\"𝕃\",\"lopf\":\"𝕝\",\"loplus\":\"⨭\",\"lotimes\":\"⨴\",\"lowast\":\"∗\",\"lowbar\":\"_\",\"LowerLeftArrow\":\"↙\",\"LowerRightArrow\":\"↘\",\"loz\":\"◊\",\"lozenge\":\"◊\",\"lozf\":\"⧫\",\"lpar\":\"(\",\"lparlt\":\"⦓\",\"lrarr\":\"⇆\",\"lrcorner\":\"⌟\",\"lrhar\":\"⇋\",\"lrhard\":\"⥭\",\"lrm\":\"‎\",\"lrtri\":\"⊿\",\"lsaquo\":\"‹\",\"lscr\":\"𝓁\",\"Lscr\":\"ℒ\",\"lsh\":\"↰\",\"Lsh\":\"↰\",\"lsim\":\"≲\",\"lsime\":\"⪍\",\"lsimg\":\"⪏\",\"lsqb\":\"[\",\"lsquo\":\"‘\",\"lsquor\":\"‚\",\"Lstrok\":\"Ł\",\"lstrok\":\"ł\",\"ltcc\":\"⪦\",\"ltcir\":\"⩹\",\"lt\":\"<\",\"LT\":\"<\",\"Lt\":\"≪\",\"ltdot\":\"⋖\",\"lthree\":\"⋋\",\"ltimes\":\"⋉\",\"ltlarr\":\"⥶\",\"ltquest\":\"⩻\",\"ltri\":\"◃\",\"ltrie\":\"⊴\",\"ltrif\":\"◂\",\"ltrPar\":\"⦖\",\"lurdshar\":\"⥊\",\"luruhar\":\"⥦\",\"lvertneqq\":\"≨︀\",\"lvnE\":\"≨︀\",\"macr\":\"¯\",\"male\":\"♂\",\"malt\":\"✠\",\"maltese\":\"✠\",\"Map\":\"⤅\",\"map\":\"↦\",\"mapsto\":\"↦\",\"mapstodown\":\"↧\",\"mapstoleft\":\"↤\",\"mapstoup\":\"↥\",\"marker\":\"▮\",\"mcomma\":\"⨩\",\"Mcy\":\"М\",\"mcy\":\"м\",\"mdash\":\"—\",\"mDDot\":\"∺\",\"measuredangle\":\"∡\",\"MediumSpace\":\" \",\"Mellintrf\":\"ℳ\",\"Mfr\":\"𝔐\",\"mfr\":\"𝔪\",\"mho\":\"℧\",\"micro\":\"µ\",\"midast\":\"*\",\"midcir\":\"⫰\",\"mid\":\"∣\",\"middot\":\"·\",\"minusb\":\"⊟\",\"minus\":\"−\",\"minusd\":\"∸\",\"minusdu\":\"⨪\",\"MinusPlus\":\"∓\",\"mlcp\":\"⫛\",\"mldr\":\"…\",\"mnplus\":\"∓\",\"models\":\"⊧\",\"Mopf\":\"𝕄\",\"mopf\":\"𝕞\",\"mp\":\"∓\",\"mscr\":\"𝓂\",\"Mscr\":\"ℳ\",\"mstpos\":\"∾\",\"Mu\":\"Μ\",\"mu\":\"μ\",\"multimap\":\"⊸\",\"mumap\":\"⊸\",\"nabla\":\"∇\",\"Nacute\":\"Ń\",\"nacute\":\"ń\",\"nang\":\"∠⃒\",\"nap\":\"≉\",\"napE\":\"⩰̸\",\"napid\":\"≋̸\",\"napos\":\"ʼn\",\"napprox\":\"≉\",\"natural\":\"♮\",\"naturals\":\"ℕ\",\"natur\":\"♮\",\"nbsp\":\" \",\"nbump\":\"≎̸\",\"nbumpe\":\"≏̸\",\"ncap\":\"⩃\",\"Ncaron\":\"Ň\",\"ncaron\":\"ň\",\"Ncedil\":\"Ņ\",\"ncedil\":\"ņ\",\"ncong\":\"≇\",\"ncongdot\":\"⩭̸\",\"ncup\":\"⩂\",\"Ncy\":\"Н\",\"ncy\":\"н\",\"ndash\":\"–\",\"nearhk\":\"⤤\",\"nearr\":\"↗\",\"neArr\":\"⇗\",\"nearrow\":\"↗\",\"ne\":\"≠\",\"nedot\":\"≐̸\",\"NegativeMediumSpace\":\"​\",\"NegativeThickSpace\":\"​\",\"NegativeThinSpace\":\"​\",\"NegativeVeryThinSpace\":\"​\",\"nequiv\":\"≢\",\"nesear\":\"⤨\",\"nesim\":\"≂̸\",\"NestedGreaterGreater\":\"≫\",\"NestedLessLess\":\"≪\",\"NewLine\":\"\\n\",\"nexist\":\"∄\",\"nexists\":\"∄\",\"Nfr\":\"𝔑\",\"nfr\":\"𝔫\",\"ngE\":\"≧̸\",\"nge\":\"≱\",\"ngeq\":\"≱\",\"ngeqq\":\"≧̸\",\"ngeqslant\":\"⩾̸\",\"nges\":\"⩾̸\",\"nGg\":\"⋙̸\",\"ngsim\":\"≵\",\"nGt\":\"≫⃒\",\"ngt\":\"≯\",\"ngtr\":\"≯\",\"nGtv\":\"≫̸\",\"nharr\":\"↮\",\"nhArr\":\"⇎\",\"nhpar\":\"⫲\",\"ni\":\"∋\",\"nis\":\"⋼\",\"nisd\":\"⋺\",\"niv\":\"∋\",\"NJcy\":\"Њ\",\"njcy\":\"њ\",\"nlarr\":\"↚\",\"nlArr\":\"⇍\",\"nldr\":\"‥\",\"nlE\":\"≦̸\",\"nle\":\"≰\",\"nleftarrow\":\"↚\",\"nLeftarrow\":\"⇍\",\"nleftrightarrow\":\"↮\",\"nLeftrightarrow\":\"⇎\",\"nleq\":\"≰\",\"nleqq\":\"≦̸\",\"nleqslant\":\"⩽̸\",\"nles\":\"⩽̸\",\"nless\":\"≮\",\"nLl\":\"⋘̸\",\"nlsim\":\"≴\",\"nLt\":\"≪⃒\",\"nlt\":\"≮\",\"nltri\":\"⋪\",\"nltrie\":\"⋬\",\"nLtv\":\"≪̸\",\"nmid\":\"∤\",\"NoBreak\":\"⁠\",\"NonBreakingSpace\":\" \",\"nopf\":\"𝕟\",\"Nopf\":\"ℕ\",\"Not\":\"⫬\",\"not\":\"¬\",\"NotCongruent\":\"≢\",\"NotCupCap\":\"≭\",\"NotDoubleVerticalBar\":\"∦\",\"NotElement\":\"∉\",\"NotEqual\":\"≠\",\"NotEqualTilde\":\"≂̸\",\"NotExists\":\"∄\",\"NotGreater\":\"≯\",\"NotGreaterEqual\":\"≱\",\"NotGreaterFullEqual\":\"≧̸\",\"NotGreaterGreater\":\"≫̸\",\"NotGreaterLess\":\"≹\",\"NotGreaterSlantEqual\":\"⩾̸\",\"NotGreaterTilde\":\"≵\",\"NotHumpDownHump\":\"≎̸\",\"NotHumpEqual\":\"≏̸\",\"notin\":\"∉\",\"notindot\":\"⋵̸\",\"notinE\":\"⋹̸\",\"notinva\":\"∉\",\"notinvb\":\"⋷\",\"notinvc\":\"⋶\",\"NotLeftTriangleBar\":\"⧏̸\",\"NotLeftTriangle\":\"⋪\",\"NotLeftTriangleEqual\":\"⋬\",\"NotLess\":\"≮\",\"NotLessEqual\":\"≰\",\"NotLessGreater\":\"≸\",\"NotLessLess\":\"≪̸\",\"NotLessSlantEqual\":\"⩽̸\",\"NotLessTilde\":\"≴\",\"NotNestedGreaterGreater\":\"⪢̸\",\"NotNestedLessLess\":\"⪡̸\",\"notni\":\"∌\",\"notniva\":\"∌\",\"notnivb\":\"⋾\",\"notnivc\":\"⋽\",\"NotPrecedes\":\"⊀\",\"NotPrecedesEqual\":\"⪯̸\",\"NotPrecedesSlantEqual\":\"⋠\",\"NotReverseElement\":\"∌\",\"NotRightTriangleBar\":\"⧐̸\",\"NotRightTriangle\":\"⋫\",\"NotRightTriangleEqual\":\"⋭\",\"NotSquareSubset\":\"⊏̸\",\"NotSquareSubsetEqual\":\"⋢\",\"NotSquareSuperset\":\"⊐̸\",\"NotSquareSupersetEqual\":\"⋣\",\"NotSubset\":\"⊂⃒\",\"NotSubsetEqual\":\"⊈\",\"NotSucceeds\":\"⊁\",\"NotSucceedsEqual\":\"⪰̸\",\"NotSucceedsSlantEqual\":\"⋡\",\"NotSucceedsTilde\":\"≿̸\",\"NotSuperset\":\"⊃⃒\",\"NotSupersetEqual\":\"⊉\",\"NotTilde\":\"≁\",\"NotTildeEqual\":\"≄\",\"NotTildeFullEqual\":\"≇\",\"NotTildeTilde\":\"≉\",\"NotVerticalBar\":\"∤\",\"nparallel\":\"∦\",\"npar\":\"∦\",\"nparsl\":\"⫽⃥\",\"npart\":\"∂̸\",\"npolint\":\"⨔\",\"npr\":\"⊀\",\"nprcue\":\"⋠\",\"nprec\":\"⊀\",\"npreceq\":\"⪯̸\",\"npre\":\"⪯̸\",\"nrarrc\":\"⤳̸\",\"nrarr\":\"↛\",\"nrArr\":\"⇏\",\"nrarrw\":\"↝̸\",\"nrightarrow\":\"↛\",\"nRightarrow\":\"⇏\",\"nrtri\":\"⋫\",\"nrtrie\":\"⋭\",\"nsc\":\"⊁\",\"nsccue\":\"⋡\",\"nsce\":\"⪰̸\",\"Nscr\":\"𝒩\",\"nscr\":\"𝓃\",\"nshortmid\":\"∤\",\"nshortparallel\":\"∦\",\"nsim\":\"≁\",\"nsime\":\"≄\",\"nsimeq\":\"≄\",\"nsmid\":\"∤\",\"nspar\":\"∦\",\"nsqsube\":\"⋢\",\"nsqsupe\":\"⋣\",\"nsub\":\"⊄\",\"nsubE\":\"⫅̸\",\"nsube\":\"⊈\",\"nsubset\":\"⊂⃒\",\"nsubseteq\":\"⊈\",\"nsubseteqq\":\"⫅̸\",\"nsucc\":\"⊁\",\"nsucceq\":\"⪰̸\",\"nsup\":\"⊅\",\"nsupE\":\"⫆̸\",\"nsupe\":\"⊉\",\"nsupset\":\"⊃⃒\",\"nsupseteq\":\"⊉\",\"nsupseteqq\":\"⫆̸\",\"ntgl\":\"≹\",\"Ntilde\":\"Ñ\",\"ntilde\":\"ñ\",\"ntlg\":\"≸\",\"ntriangleleft\":\"⋪\",\"ntrianglelefteq\":\"⋬\",\"ntriangleright\":\"⋫\",\"ntrianglerighteq\":\"⋭\",\"Nu\":\"Ν\",\"nu\":\"ν\",\"num\":\"#\",\"numero\":\"№\",\"numsp\":\" \",\"nvap\":\"≍⃒\",\"nvdash\":\"⊬\",\"nvDash\":\"⊭\",\"nVdash\":\"⊮\",\"nVDash\":\"⊯\",\"nvge\":\"≥⃒\",\"nvgt\":\">⃒\",\"nvHarr\":\"⤄\",\"nvinfin\":\"⧞\",\"nvlArr\":\"⤂\",\"nvle\":\"≤⃒\",\"nvlt\":\"<⃒\",\"nvltrie\":\"⊴⃒\",\"nvrArr\":\"⤃\",\"nvrtrie\":\"⊵⃒\",\"nvsim\":\"∼⃒\",\"nwarhk\":\"⤣\",\"nwarr\":\"↖\",\"nwArr\":\"⇖\",\"nwarrow\":\"↖\",\"nwnear\":\"⤧\",\"Oacute\":\"Ó\",\"oacute\":\"ó\",\"oast\":\"⊛\",\"Ocirc\":\"Ô\",\"ocirc\":\"ô\",\"ocir\":\"⊚\",\"Ocy\":\"О\",\"ocy\":\"о\",\"odash\":\"⊝\",\"Odblac\":\"Ő\",\"odblac\":\"ő\",\"odiv\":\"⨸\",\"odot\":\"⊙\",\"odsold\":\"⦼\",\"OElig\":\"Œ\",\"oelig\":\"œ\",\"ofcir\":\"⦿\",\"Ofr\":\"𝔒\",\"ofr\":\"𝔬\",\"ogon\":\"˛\",\"Ograve\":\"Ò\",\"ograve\":\"ò\",\"ogt\":\"⧁\",\"ohbar\":\"⦵\",\"ohm\":\"Ω\",\"oint\":\"∮\",\"olarr\":\"↺\",\"olcir\":\"⦾\",\"olcross\":\"⦻\",\"oline\":\"‾\",\"olt\":\"⧀\",\"Omacr\":\"Ō\",\"omacr\":\"ō\",\"Omega\":\"Ω\",\"omega\":\"ω\",\"Omicron\":\"Ο\",\"omicron\":\"ο\",\"omid\":\"⦶\",\"ominus\":\"⊖\",\"Oopf\":\"𝕆\",\"oopf\":\"𝕠\",\"opar\":\"⦷\",\"OpenCurlyDoubleQuote\":\"“\",\"OpenCurlyQuote\":\"‘\",\"operp\":\"⦹\",\"oplus\":\"⊕\",\"orarr\":\"↻\",\"Or\":\"⩔\",\"or\":\"∨\",\"ord\":\"⩝\",\"order\":\"ℴ\",\"orderof\":\"ℴ\",\"ordf\":\"ª\",\"ordm\":\"º\",\"origof\":\"⊶\",\"oror\":\"⩖\",\"orslope\":\"⩗\",\"orv\":\"⩛\",\"oS\":\"Ⓢ\",\"Oscr\":\"𝒪\",\"oscr\":\"ℴ\",\"Oslash\":\"Ø\",\"oslash\":\"ø\",\"osol\":\"⊘\",\"Otilde\":\"Õ\",\"otilde\":\"õ\",\"otimesas\":\"⨶\",\"Otimes\":\"⨷\",\"otimes\":\"⊗\",\"Ouml\":\"Ö\",\"ouml\":\"ö\",\"ovbar\":\"⌽\",\"OverBar\":\"‾\",\"OverBrace\":\"⏞\",\"OverBracket\":\"⎴\",\"OverParenthesis\":\"⏜\",\"para\":\"¶\",\"parallel\":\"∥\",\"par\":\"∥\",\"parsim\":\"⫳\",\"parsl\":\"⫽\",\"part\":\"∂\",\"PartialD\":\"∂\",\"Pcy\":\"П\",\"pcy\":\"п\",\"percnt\":\"%\",\"period\":\".\",\"permil\":\"‰\",\"perp\":\"⊥\",\"pertenk\":\"‱\",\"Pfr\":\"𝔓\",\"pfr\":\"𝔭\",\"Phi\":\"Φ\",\"phi\":\"φ\",\"phiv\":\"ϕ\",\"phmmat\":\"ℳ\",\"phone\":\"☎\",\"Pi\":\"Π\",\"pi\":\"π\",\"pitchfork\":\"⋔\",\"piv\":\"ϖ\",\"planck\":\"ℏ\",\"planckh\":\"ℎ\",\"plankv\":\"ℏ\",\"plusacir\":\"⨣\",\"plusb\":\"⊞\",\"pluscir\":\"⨢\",\"plus\":\"+\",\"plusdo\":\"∔\",\"plusdu\":\"⨥\",\"pluse\":\"⩲\",\"PlusMinus\":\"±\",\"plusmn\":\"±\",\"plussim\":\"⨦\",\"plustwo\":\"⨧\",\"pm\":\"±\",\"Poincareplane\":\"ℌ\",\"pointint\":\"⨕\",\"popf\":\"𝕡\",\"Popf\":\"ℙ\",\"pound\":\"£\",\"prap\":\"⪷\",\"Pr\":\"⪻\",\"pr\":\"≺\",\"prcue\":\"≼\",\"precapprox\":\"⪷\",\"prec\":\"≺\",\"preccurlyeq\":\"≼\",\"Precedes\":\"≺\",\"PrecedesEqual\":\"⪯\",\"PrecedesSlantEqual\":\"≼\",\"PrecedesTilde\":\"≾\",\"preceq\":\"⪯\",\"precnapprox\":\"⪹\",\"precneqq\":\"⪵\",\"precnsim\":\"⋨\",\"pre\":\"⪯\",\"prE\":\"⪳\",\"precsim\":\"≾\",\"prime\":\"′\",\"Prime\":\"″\",\"primes\":\"ℙ\",\"prnap\":\"⪹\",\"prnE\":\"⪵\",\"prnsim\":\"⋨\",\"prod\":\"∏\",\"Product\":\"∏\",\"profalar\":\"⌮\",\"profline\":\"⌒\",\"profsurf\":\"⌓\",\"prop\":\"∝\",\"Proportional\":\"∝\",\"Proportion\":\"∷\",\"propto\":\"∝\",\"prsim\":\"≾\",\"prurel\":\"⊰\",\"Pscr\":\"𝒫\",\"pscr\":\"𝓅\",\"Psi\":\"Ψ\",\"psi\":\"ψ\",\"puncsp\":\" \",\"Qfr\":\"𝔔\",\"qfr\":\"𝔮\",\"qint\":\"⨌\",\"qopf\":\"𝕢\",\"Qopf\":\"ℚ\",\"qprime\":\"⁗\",\"Qscr\":\"𝒬\",\"qscr\":\"𝓆\",\"quaternions\":\"ℍ\",\"quatint\":\"⨖\",\"quest\":\"?\",\"questeq\":\"≟\",\"quot\":\"\\\"\",\"QUOT\":\"\\\"\",\"rAarr\":\"⇛\",\"race\":\"∽̱\",\"Racute\":\"Ŕ\",\"racute\":\"ŕ\",\"radic\":\"√\",\"raemptyv\":\"⦳\",\"rang\":\"⟩\",\"Rang\":\"⟫\",\"rangd\":\"⦒\",\"range\":\"⦥\",\"rangle\":\"⟩\",\"raquo\":\"»\",\"rarrap\":\"⥵\",\"rarrb\":\"⇥\",\"rarrbfs\":\"⤠\",\"rarrc\":\"⤳\",\"rarr\":\"→\",\"Rarr\":\"↠\",\"rArr\":\"⇒\",\"rarrfs\":\"⤞\",\"rarrhk\":\"↪\",\"rarrlp\":\"↬\",\"rarrpl\":\"⥅\",\"rarrsim\":\"⥴\",\"Rarrtl\":\"⤖\",\"rarrtl\":\"↣\",\"rarrw\":\"↝\",\"ratail\":\"⤚\",\"rAtail\":\"⤜\",\"ratio\":\"∶\",\"rationals\":\"ℚ\",\"rbarr\":\"⤍\",\"rBarr\":\"⤏\",\"RBarr\":\"⤐\",\"rbbrk\":\"❳\",\"rbrace\":\"}\",\"rbrack\":\"]\",\"rbrke\":\"⦌\",\"rbrksld\":\"⦎\",\"rbrkslu\":\"⦐\",\"Rcaron\":\"Ř\",\"rcaron\":\"ř\",\"Rcedil\":\"Ŗ\",\"rcedil\":\"ŗ\",\"rceil\":\"⌉\",\"rcub\":\"}\",\"Rcy\":\"Р\",\"rcy\":\"р\",\"rdca\":\"⤷\",\"rdldhar\":\"⥩\",\"rdquo\":\"”\",\"rdquor\":\"”\",\"rdsh\":\"↳\",\"real\":\"ℜ\",\"realine\":\"ℛ\",\"realpart\":\"ℜ\",\"reals\":\"ℝ\",\"Re\":\"ℜ\",\"rect\":\"▭\",\"reg\":\"®\",\"REG\":\"®\",\"ReverseElement\":\"∋\",\"ReverseEquilibrium\":\"⇋\",\"ReverseUpEquilibrium\":\"⥯\",\"rfisht\":\"⥽\",\"rfloor\":\"⌋\",\"rfr\":\"𝔯\",\"Rfr\":\"ℜ\",\"rHar\":\"⥤\",\"rhard\":\"⇁\",\"rharu\":\"⇀\",\"rharul\":\"⥬\",\"Rho\":\"Ρ\",\"rho\":\"ρ\",\"rhov\":\"ϱ\",\"RightAngleBracket\":\"⟩\",\"RightArrowBar\":\"⇥\",\"rightarrow\":\"→\",\"RightArrow\":\"→\",\"Rightarrow\":\"⇒\",\"RightArrowLeftArrow\":\"⇄\",\"rightarrowtail\":\"↣\",\"RightCeiling\":\"⌉\",\"RightDoubleBracket\":\"⟧\",\"RightDownTeeVector\":\"⥝\",\"RightDownVectorBar\":\"⥕\",\"RightDownVector\":\"⇂\",\"RightFloor\":\"⌋\",\"rightharpoondown\":\"⇁\",\"rightharpoonup\":\"⇀\",\"rightleftarrows\":\"⇄\",\"rightleftharpoons\":\"⇌\",\"rightrightarrows\":\"⇉\",\"rightsquigarrow\":\"↝\",\"RightTeeArrow\":\"↦\",\"RightTee\":\"⊢\",\"RightTeeVector\":\"⥛\",\"rightthreetimes\":\"⋌\",\"RightTriangleBar\":\"⧐\",\"RightTriangle\":\"⊳\",\"RightTriangleEqual\":\"⊵\",\"RightUpDownVector\":\"⥏\",\"RightUpTeeVector\":\"⥜\",\"RightUpVectorBar\":\"⥔\",\"RightUpVector\":\"↾\",\"RightVectorBar\":\"⥓\",\"RightVector\":\"⇀\",\"ring\":\"˚\",\"risingdotseq\":\"≓\",\"rlarr\":\"⇄\",\"rlhar\":\"⇌\",\"rlm\":\"‏\",\"rmoustache\":\"⎱\",\"rmoust\":\"⎱\",\"rnmid\":\"⫮\",\"roang\":\"⟭\",\"roarr\":\"⇾\",\"robrk\":\"⟧\",\"ropar\":\"⦆\",\"ropf\":\"𝕣\",\"Ropf\":\"ℝ\",\"roplus\":\"⨮\",\"rotimes\":\"⨵\",\"RoundImplies\":\"⥰\",\"rpar\":\")\",\"rpargt\":\"⦔\",\"rppolint\":\"⨒\",\"rrarr\":\"⇉\",\"Rrightarrow\":\"⇛\",\"rsaquo\":\"›\",\"rscr\":\"𝓇\",\"Rscr\":\"ℛ\",\"rsh\":\"↱\",\"Rsh\":\"↱\",\"rsqb\":\"]\",\"rsquo\":\"’\",\"rsquor\":\"’\",\"rthree\":\"⋌\",\"rtimes\":\"⋊\",\"rtri\":\"▹\",\"rtrie\":\"⊵\",\"rtrif\":\"▸\",\"rtriltri\":\"⧎\",\"RuleDelayed\":\"⧴\",\"ruluhar\":\"⥨\",\"rx\":\"℞\",\"Sacute\":\"Ś\",\"sacute\":\"ś\",\"sbquo\":\"‚\",\"scap\":\"⪸\",\"Scaron\":\"Š\",\"scaron\":\"š\",\"Sc\":\"⪼\",\"sc\":\"≻\",\"sccue\":\"≽\",\"sce\":\"⪰\",\"scE\":\"⪴\",\"Scedil\":\"Ş\",\"scedil\":\"ş\",\"Scirc\":\"Ŝ\",\"scirc\":\"ŝ\",\"scnap\":\"⪺\",\"scnE\":\"⪶\",\"scnsim\":\"⋩\",\"scpolint\":\"⨓\",\"scsim\":\"≿\",\"Scy\":\"С\",\"scy\":\"с\",\"sdotb\":\"⊡\",\"sdot\":\"⋅\",\"sdote\":\"⩦\",\"searhk\":\"⤥\",\"searr\":\"↘\",\"seArr\":\"⇘\",\"searrow\":\"↘\",\"sect\":\"§\",\"semi\":\";\",\"seswar\":\"⤩\",\"setminus\":\"∖\",\"setmn\":\"∖\",\"sext\":\"✶\",\"Sfr\":\"𝔖\",\"sfr\":\"𝔰\",\"sfrown\":\"⌢\",\"sharp\":\"♯\",\"SHCHcy\":\"Щ\",\"shchcy\":\"щ\",\"SHcy\":\"Ш\",\"shcy\":\"ш\",\"ShortDownArrow\":\"↓\",\"ShortLeftArrow\":\"←\",\"shortmid\":\"∣\",\"shortparallel\":\"∥\",\"ShortRightArrow\":\"→\",\"ShortUpArrow\":\"↑\",\"shy\":\"­\",\"Sigma\":\"Σ\",\"sigma\":\"σ\",\"sigmaf\":\"ς\",\"sigmav\":\"ς\",\"sim\":\"∼\",\"simdot\":\"⩪\",\"sime\":\"≃\",\"simeq\":\"≃\",\"simg\":\"⪞\",\"simgE\":\"⪠\",\"siml\":\"⪝\",\"simlE\":\"⪟\",\"simne\":\"≆\",\"simplus\":\"⨤\",\"simrarr\":\"⥲\",\"slarr\":\"←\",\"SmallCircle\":\"∘\",\"smallsetminus\":\"∖\",\"smashp\":\"⨳\",\"smeparsl\":\"⧤\",\"smid\":\"∣\",\"smile\":\"⌣\",\"smt\":\"⪪\",\"smte\":\"⪬\",\"smtes\":\"⪬︀\",\"SOFTcy\":\"Ь\",\"softcy\":\"ь\",\"solbar\":\"⌿\",\"solb\":\"⧄\",\"sol\":\"/\",\"Sopf\":\"𝕊\",\"sopf\":\"𝕤\",\"spades\":\"♠\",\"spadesuit\":\"♠\",\"spar\":\"∥\",\"sqcap\":\"⊓\",\"sqcaps\":\"⊓︀\",\"sqcup\":\"⊔\",\"sqcups\":\"⊔︀\",\"Sqrt\":\"√\",\"sqsub\":\"⊏\",\"sqsube\":\"⊑\",\"sqsubset\":\"⊏\",\"sqsubseteq\":\"⊑\",\"sqsup\":\"⊐\",\"sqsupe\":\"⊒\",\"sqsupset\":\"⊐\",\"sqsupseteq\":\"⊒\",\"square\":\"□\",\"Square\":\"□\",\"SquareIntersection\":\"⊓\",\"SquareSubset\":\"⊏\",\"SquareSubsetEqual\":\"⊑\",\"SquareSuperset\":\"⊐\",\"SquareSupersetEqual\":\"⊒\",\"SquareUnion\":\"⊔\",\"squarf\":\"▪\",\"squ\":\"□\",\"squf\":\"▪\",\"srarr\":\"→\",\"Sscr\":\"𝒮\",\"sscr\":\"𝓈\",\"ssetmn\":\"∖\",\"ssmile\":\"⌣\",\"sstarf\":\"⋆\",\"Star\":\"⋆\",\"star\":\"☆\",\"starf\":\"★\",\"straightepsilon\":\"ϵ\",\"straightphi\":\"ϕ\",\"strns\":\"¯\",\"sub\":\"⊂\",\"Sub\":\"⋐\",\"subdot\":\"⪽\",\"subE\":\"⫅\",\"sube\":\"⊆\",\"subedot\":\"⫃\",\"submult\":\"⫁\",\"subnE\":\"⫋\",\"subne\":\"⊊\",\"subplus\":\"⪿\",\"subrarr\":\"⥹\",\"subset\":\"⊂\",\"Subset\":\"⋐\",\"subseteq\":\"⊆\",\"subseteqq\":\"⫅\",\"SubsetEqual\":\"⊆\",\"subsetneq\":\"⊊\",\"subsetneqq\":\"⫋\",\"subsim\":\"⫇\",\"subsub\":\"⫕\",\"subsup\":\"⫓\",\"succapprox\":\"⪸\",\"succ\":\"≻\",\"succcurlyeq\":\"≽\",\"Succeeds\":\"≻\",\"SucceedsEqual\":\"⪰\",\"SucceedsSlantEqual\":\"≽\",\"SucceedsTilde\":\"≿\",\"succeq\":\"⪰\",\"succnapprox\":\"⪺\",\"succneqq\":\"⪶\",\"succnsim\":\"⋩\",\"succsim\":\"≿\",\"SuchThat\":\"∋\",\"sum\":\"∑\",\"Sum\":\"∑\",\"sung\":\"♪\",\"sup1\":\"¹\",\"sup2\":\"²\",\"sup3\":\"³\",\"sup\":\"⊃\",\"Sup\":\"⋑\",\"supdot\":\"⪾\",\"supdsub\":\"⫘\",\"supE\":\"⫆\",\"supe\":\"⊇\",\"supedot\":\"⫄\",\"Superset\":\"⊃\",\"SupersetEqual\":\"⊇\",\"suphsol\":\"⟉\",\"suphsub\":\"⫗\",\"suplarr\":\"⥻\",\"supmult\":\"⫂\",\"supnE\":\"⫌\",\"supne\":\"⊋\",\"supplus\":\"⫀\",\"supset\":\"⊃\",\"Supset\":\"⋑\",\"supseteq\":\"⊇\",\"supseteqq\":\"⫆\",\"supsetneq\":\"⊋\",\"supsetneqq\":\"⫌\",\"supsim\":\"⫈\",\"supsub\":\"⫔\",\"supsup\":\"⫖\",\"swarhk\":\"⤦\",\"swarr\":\"↙\",\"swArr\":\"⇙\",\"swarrow\":\"↙\",\"swnwar\":\"⤪\",\"szlig\":\"ß\",\"Tab\":\"\\t\",\"target\":\"⌖\",\"Tau\":\"Τ\",\"tau\":\"τ\",\"tbrk\":\"⎴\",\"Tcaron\":\"Ť\",\"tcaron\":\"ť\",\"Tcedil\":\"Ţ\",\"tcedil\":\"ţ\",\"Tcy\":\"Т\",\"tcy\":\"т\",\"tdot\":\"⃛\",\"telrec\":\"⌕\",\"Tfr\":\"𝔗\",\"tfr\":\"𝔱\",\"there4\":\"∴\",\"therefore\":\"∴\",\"Therefore\":\"∴\",\"Theta\":\"Θ\",\"theta\":\"θ\",\"thetasym\":\"ϑ\",\"thetav\":\"ϑ\",\"thickapprox\":\"≈\",\"thicksim\":\"∼\",\"ThickSpace\":\"  \",\"ThinSpace\":\" \",\"thinsp\":\" \",\"thkap\":\"≈\",\"thksim\":\"∼\",\"THORN\":\"Þ\",\"thorn\":\"þ\",\"tilde\":\"˜\",\"Tilde\":\"∼\",\"TildeEqual\":\"≃\",\"TildeFullEqual\":\"≅\",\"TildeTilde\":\"≈\",\"timesbar\":\"⨱\",\"timesb\":\"⊠\",\"times\":\"×\",\"timesd\":\"⨰\",\"tint\":\"∭\",\"toea\":\"⤨\",\"topbot\":\"⌶\",\"topcir\":\"⫱\",\"top\":\"⊤\",\"Topf\":\"𝕋\",\"topf\":\"𝕥\",\"topfork\":\"⫚\",\"tosa\":\"⤩\",\"tprime\":\"‴\",\"trade\":\"™\",\"TRADE\":\"™\",\"triangle\":\"▵\",\"triangledown\":\"▿\",\"triangleleft\":\"◃\",\"trianglelefteq\":\"⊴\",\"triangleq\":\"≜\",\"triangleright\":\"▹\",\"trianglerighteq\":\"⊵\",\"tridot\":\"◬\",\"trie\":\"≜\",\"triminus\":\"⨺\",\"TripleDot\":\"⃛\",\"triplus\":\"⨹\",\"trisb\":\"⧍\",\"tritime\":\"⨻\",\"trpezium\":\"⏢\",\"Tscr\":\"𝒯\",\"tscr\":\"𝓉\",\"TScy\":\"Ц\",\"tscy\":\"ц\",\"TSHcy\":\"Ћ\",\"tshcy\":\"ћ\",\"Tstrok\":\"Ŧ\",\"tstrok\":\"ŧ\",\"twixt\":\"≬\",\"twoheadleftarrow\":\"↞\",\"twoheadrightarrow\":\"↠\",\"Uacute\":\"Ú\",\"uacute\":\"ú\",\"uarr\":\"↑\",\"Uarr\":\"↟\",\"uArr\":\"⇑\",\"Uarrocir\":\"⥉\",\"Ubrcy\":\"Ў\",\"ubrcy\":\"ў\",\"Ubreve\":\"Ŭ\",\"ubreve\":\"ŭ\",\"Ucirc\":\"Û\",\"ucirc\":\"û\",\"Ucy\":\"У\",\"ucy\":\"у\",\"udarr\":\"⇅\",\"Udblac\":\"Ű\",\"udblac\":\"ű\",\"udhar\":\"⥮\",\"ufisht\":\"⥾\",\"Ufr\":\"𝔘\",\"ufr\":\"𝔲\",\"Ugrave\":\"Ù\",\"ugrave\":\"ù\",\"uHar\":\"⥣\",\"uharl\":\"↿\",\"uharr\":\"↾\",\"uhblk\":\"▀\",\"ulcorn\":\"⌜\",\"ulcorner\":\"⌜\",\"ulcrop\":\"⌏\",\"ultri\":\"◸\",\"Umacr\":\"Ū\",\"umacr\":\"ū\",\"uml\":\"¨\",\"UnderBar\":\"_\",\"UnderBrace\":\"⏟\",\"UnderBracket\":\"⎵\",\"UnderParenthesis\":\"⏝\",\"Union\":\"⋃\",\"UnionPlus\":\"⊎\",\"Uogon\":\"Ų\",\"uogon\":\"ų\",\"Uopf\":\"𝕌\",\"uopf\":\"𝕦\",\"UpArrowBar\":\"⤒\",\"uparrow\":\"↑\",\"UpArrow\":\"↑\",\"Uparrow\":\"⇑\",\"UpArrowDownArrow\":\"⇅\",\"updownarrow\":\"↕\",\"UpDownArrow\":\"↕\",\"Updownarrow\":\"⇕\",\"UpEquilibrium\":\"⥮\",\"upharpoonleft\":\"↿\",\"upharpoonright\":\"↾\",\"uplus\":\"⊎\",\"UpperLeftArrow\":\"↖\",\"UpperRightArrow\":\"↗\",\"upsi\":\"υ\",\"Upsi\":\"ϒ\",\"upsih\":\"ϒ\",\"Upsilon\":\"Υ\",\"upsilon\":\"υ\",\"UpTeeArrow\":\"↥\",\"UpTee\":\"⊥\",\"upuparrows\":\"⇈\",\"urcorn\":\"⌝\",\"urcorner\":\"⌝\",\"urcrop\":\"⌎\",\"Uring\":\"Ů\",\"uring\":\"ů\",\"urtri\":\"◹\",\"Uscr\":\"𝒰\",\"uscr\":\"𝓊\",\"utdot\":\"⋰\",\"Utilde\":\"Ũ\",\"utilde\":\"ũ\",\"utri\":\"▵\",\"utrif\":\"▴\",\"uuarr\":\"⇈\",\"Uuml\":\"Ü\",\"uuml\":\"ü\",\"uwangle\":\"⦧\",\"vangrt\":\"⦜\",\"varepsilon\":\"ϵ\",\"varkappa\":\"ϰ\",\"varnothing\":\"∅\",\"varphi\":\"ϕ\",\"varpi\":\"ϖ\",\"varpropto\":\"∝\",\"varr\":\"↕\",\"vArr\":\"⇕\",\"varrho\":\"ϱ\",\"varsigma\":\"ς\",\"varsubsetneq\":\"⊊︀\",\"varsubsetneqq\":\"⫋︀\",\"varsupsetneq\":\"⊋︀\",\"varsupsetneqq\":\"⫌︀\",\"vartheta\":\"ϑ\",\"vartriangleleft\":\"⊲\",\"vartriangleright\":\"⊳\",\"vBar\":\"⫨\",\"Vbar\":\"⫫\",\"vBarv\":\"⫩\",\"Vcy\":\"В\",\"vcy\":\"в\",\"vdash\":\"⊢\",\"vDash\":\"⊨\",\"Vdash\":\"⊩\",\"VDash\":\"⊫\",\"Vdashl\":\"⫦\",\"veebar\":\"⊻\",\"vee\":\"∨\",\"Vee\":\"⋁\",\"veeeq\":\"≚\",\"vellip\":\"⋮\",\"verbar\":\"|\",\"Verbar\":\"‖\",\"vert\":\"|\",\"Vert\":\"‖\",\"VerticalBar\":\"∣\",\"VerticalLine\":\"|\",\"VerticalSeparator\":\"❘\",\"VerticalTilde\":\"≀\",\"VeryThinSpace\":\" \",\"Vfr\":\"𝔙\",\"vfr\":\"𝔳\",\"vltri\":\"⊲\",\"vnsub\":\"⊂⃒\",\"vnsup\":\"⊃⃒\",\"Vopf\":\"𝕍\",\"vopf\":\"𝕧\",\"vprop\":\"∝\",\"vrtri\":\"⊳\",\"Vscr\":\"𝒱\",\"vscr\":\"𝓋\",\"vsubnE\":\"⫋︀\",\"vsubne\":\"⊊︀\",\"vsupnE\":\"⫌︀\",\"vsupne\":\"⊋︀\",\"Vvdash\":\"⊪\",\"vzigzag\":\"⦚\",\"Wcirc\":\"Ŵ\",\"wcirc\":\"ŵ\",\"wedbar\":\"⩟\",\"wedge\":\"∧\",\"Wedge\":\"⋀\",\"wedgeq\":\"≙\",\"weierp\":\"℘\",\"Wfr\":\"𝔚\",\"wfr\":\"𝔴\",\"Wopf\":\"𝕎\",\"wopf\":\"𝕨\",\"wp\":\"℘\",\"wr\":\"≀\",\"wreath\":\"≀\",\"Wscr\":\"𝒲\",\"wscr\":\"𝓌\",\"xcap\":\"⋂\",\"xcirc\":\"◯\",\"xcup\":\"⋃\",\"xdtri\":\"▽\",\"Xfr\":\"𝔛\",\"xfr\":\"𝔵\",\"xharr\":\"⟷\",\"xhArr\":\"⟺\",\"Xi\":\"Ξ\",\"xi\":\"ξ\",\"xlarr\":\"⟵\",\"xlArr\":\"⟸\",\"xmap\":\"⟼\",\"xnis\":\"⋻\",\"xodot\":\"⨀\",\"Xopf\":\"𝕏\",\"xopf\":\"𝕩\",\"xoplus\":\"⨁\",\"xotime\":\"⨂\",\"xrarr\":\"⟶\",\"xrArr\":\"⟹\",\"Xscr\":\"𝒳\",\"xscr\":\"𝓍\",\"xsqcup\":\"⨆\",\"xuplus\":\"⨄\",\"xutri\":\"△\",\"xvee\":\"⋁\",\"xwedge\":\"⋀\",\"Yacute\":\"Ý\",\"yacute\":\"ý\",\"YAcy\":\"Я\",\"yacy\":\"я\",\"Ycirc\":\"Ŷ\",\"ycirc\":\"ŷ\",\"Ycy\":\"Ы\",\"ycy\":\"ы\",\"yen\":\"¥\",\"Yfr\":\"𝔜\",\"yfr\":\"𝔶\",\"YIcy\":\"Ї\",\"yicy\":\"ї\",\"Yopf\":\"𝕐\",\"yopf\":\"𝕪\",\"Yscr\":\"𝒴\",\"yscr\":\"𝓎\",\"YUcy\":\"Ю\",\"yucy\":\"ю\",\"yuml\":\"ÿ\",\"Yuml\":\"Ÿ\",\"Zacute\":\"Ź\",\"zacute\":\"ź\",\"Zcaron\":\"Ž\",\"zcaron\":\"ž\",\"Zcy\":\"З\",\"zcy\":\"з\",\"Zdot\":\"Ż\",\"zdot\":\"ż\",\"zeetrf\":\"ℨ\",\"ZeroWidthSpace\":\"​\",\"Zeta\":\"Ζ\",\"zeta\":\"ζ\",\"zfr\":\"𝔷\",\"Zfr\":\"ℨ\",\"ZHcy\":\"Ж\",\"zhcy\":\"ж\",\"zigrarr\":\"⇝\",\"zopf\":\"𝕫\",\"Zopf\":\"ℤ\",\"Zscr\":\"𝒵\",\"zscr\":\"𝓏\",\"zwj\":\"‍\",\"zwnj\":\"‌\"}"); - -/***/ }), - -/***/ "./node_modules/entities/maps/legacy.json": -/*!************************************************!*\ - !*** ./node_modules/entities/maps/legacy.json ***! - \************************************************/ -/*! exports provided: Aacute, aacute, Acirc, acirc, acute, AElig, aelig, Agrave, agrave, amp, AMP, Aring, aring, Atilde, atilde, Auml, auml, brvbar, Ccedil, ccedil, cedil, cent, copy, COPY, curren, deg, divide, Eacute, eacute, Ecirc, ecirc, Egrave, egrave, ETH, eth, Euml, euml, frac12, frac14, frac34, gt, GT, Iacute, iacute, Icirc, icirc, iexcl, Igrave, igrave, iquest, Iuml, iuml, laquo, lt, LT, macr, micro, middot, nbsp, not, Ntilde, ntilde, Oacute, oacute, Ocirc, ocirc, Ograve, ograve, ordf, ordm, Oslash, oslash, Otilde, otilde, Ouml, ouml, para, plusmn, pound, quot, QUOT, raquo, reg, REG, sect, shy, sup1, sup2, sup3, szlig, THORN, thorn, times, Uacute, uacute, Ucirc, ucirc, Ugrave, ugrave, uml, Uuml, uuml, Yacute, yacute, yen, yuml, default */ -/***/ (function(module) { - -module.exports = JSON.parse("{\"Aacute\":\"Á\",\"aacute\":\"á\",\"Acirc\":\"Â\",\"acirc\":\"â\",\"acute\":\"´\",\"AElig\":\"Æ\",\"aelig\":\"æ\",\"Agrave\":\"À\",\"agrave\":\"à\",\"amp\":\"&\",\"AMP\":\"&\",\"Aring\":\"Å\",\"aring\":\"å\",\"Atilde\":\"Ã\",\"atilde\":\"ã\",\"Auml\":\"Ä\",\"auml\":\"ä\",\"brvbar\":\"¦\",\"Ccedil\":\"Ç\",\"ccedil\":\"ç\",\"cedil\":\"¸\",\"cent\":\"¢\",\"copy\":\"©\",\"COPY\":\"©\",\"curren\":\"¤\",\"deg\":\"°\",\"divide\":\"÷\",\"Eacute\":\"É\",\"eacute\":\"é\",\"Ecirc\":\"Ê\",\"ecirc\":\"ê\",\"Egrave\":\"È\",\"egrave\":\"è\",\"ETH\":\"Ð\",\"eth\":\"ð\",\"Euml\":\"Ë\",\"euml\":\"ë\",\"frac12\":\"½\",\"frac14\":\"¼\",\"frac34\":\"¾\",\"gt\":\">\",\"GT\":\">\",\"Iacute\":\"Í\",\"iacute\":\"í\",\"Icirc\":\"Î\",\"icirc\":\"î\",\"iexcl\":\"¡\",\"Igrave\":\"Ì\",\"igrave\":\"ì\",\"iquest\":\"¿\",\"Iuml\":\"Ï\",\"iuml\":\"ï\",\"laquo\":\"«\",\"lt\":\"<\",\"LT\":\"<\",\"macr\":\"¯\",\"micro\":\"µ\",\"middot\":\"·\",\"nbsp\":\" \",\"not\":\"¬\",\"Ntilde\":\"Ñ\",\"ntilde\":\"ñ\",\"Oacute\":\"Ó\",\"oacute\":\"ó\",\"Ocirc\":\"Ô\",\"ocirc\":\"ô\",\"Ograve\":\"Ò\",\"ograve\":\"ò\",\"ordf\":\"ª\",\"ordm\":\"º\",\"Oslash\":\"Ø\",\"oslash\":\"ø\",\"Otilde\":\"Õ\",\"otilde\":\"õ\",\"Ouml\":\"Ö\",\"ouml\":\"ö\",\"para\":\"¶\",\"plusmn\":\"±\",\"pound\":\"£\",\"quot\":\"\\\"\",\"QUOT\":\"\\\"\",\"raquo\":\"»\",\"reg\":\"®\",\"REG\":\"®\",\"sect\":\"§\",\"shy\":\"­\",\"sup1\":\"¹\",\"sup2\":\"²\",\"sup3\":\"³\",\"szlig\":\"ß\",\"THORN\":\"Þ\",\"thorn\":\"þ\",\"times\":\"×\",\"Uacute\":\"Ú\",\"uacute\":\"ú\",\"Ucirc\":\"Û\",\"ucirc\":\"û\",\"Ugrave\":\"Ù\",\"ugrave\":\"ù\",\"uml\":\"¨\",\"Uuml\":\"Ü\",\"uuml\":\"ü\",\"Yacute\":\"Ý\",\"yacute\":\"ý\",\"yen\":\"¥\",\"yuml\":\"ÿ\"}"); - -/***/ }), - -/***/ "./node_modules/entities/maps/xml.json": -/*!*********************************************!*\ - !*** ./node_modules/entities/maps/xml.json ***! - \*********************************************/ -/*! exports provided: amp, apos, gt, lt, quot, default */ -/***/ (function(module) { - -module.exports = JSON.parse("{\"amp\":\"&\",\"apos\":\"'\",\"gt\":\">\",\"lt\":\"<\",\"quot\":\"\\\"\"}"); - /***/ }), /***/ "./node_modules/es6-object-assign/auto.js": @@ -219505,485 +219472,6 @@ if (HTMLCanvasElement && (!canvas_proto.toBlob || !canvas_proto.toBlobHD)) { }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/fn/set-immediate.js": -/*!**********************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/fn/set-immediate.js ***! - \**********************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -__webpack_require__(/*! ../modules/web.immediate */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/web.immediate.js"); -module.exports = __webpack_require__(/*! ../modules/_core */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_core.js").setImmediate; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_a-function.js": -/*!*************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_a-function.js ***! - \*************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -module.exports = function(it){ - if(typeof it != 'function')throw TypeError(it + ' is not a function!'); - return it; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_an-object.js": -/*!************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_an-object.js ***! - \************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_is-object.js"); -module.exports = function(it){ - if(!isObject(it))throw TypeError(it + ' is not an object!'); - return it; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_cof.js": -/*!******************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_cof.js ***! - \******************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -var toString = {}.toString; - -module.exports = function(it){ - return toString.call(it).slice(8, -1); -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_core.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_core.js ***! - \*******************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -var core = module.exports = {version: '2.3.0'}; -if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_ctx.js": -/*!******************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_ctx.js ***! - \******************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -// optional / simple context binding -var aFunction = __webpack_require__(/*! ./_a-function */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_a-function.js"); -module.exports = function(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); - }; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_descriptors.js": -/*!**************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_descriptors.js ***! - \**************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -// Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(/*! ./_fails */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_fails.js")(function(){ - return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; -}); - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_dom-create.js": -/*!*************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_dom-create.js ***! - \*************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_is-object.js") - , document = __webpack_require__(/*! ./_global */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_global.js").document - // in old IE typeof document.createElement is 'object' - , is = isObject(document) && isObject(document.createElement); -module.exports = function(it){ - return is ? document.createElement(it) : {}; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_export.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_export.js ***! - \*********************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var global = __webpack_require__(/*! ./_global */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_global.js") - , core = __webpack_require__(/*! ./_core */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_core.js") - , ctx = __webpack_require__(/*! ./_ctx */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_ctx.js") - , hide = __webpack_require__(/*! ./_hide */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_hide.js") - , PROTOTYPE = 'prototype'; - -var $export = function(type, name, source){ - var IS_FORCED = type & $export.F - , IS_GLOBAL = type & $export.G - , IS_STATIC = type & $export.S - , IS_PROTO = type & $export.P - , IS_BIND = type & $export.B - , IS_WRAP = type & $export.W - , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) - , expProto = exports[PROTOTYPE] - , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] - , key, own, out; - if(IS_GLOBAL)source = name; - for(key in source){ - // contains in native - own = !IS_FORCED && target && target[key] !== undefined; - if(own && key in exports)continue; - // export native or passed - out = own ? target[key] : source[key]; - // prevent global pollution for namespaces - exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] - // bind timers to global for call from export context - : IS_BIND && own ? ctx(out, global) - // wrap global constructors for prevent change them in library - : IS_WRAP && target[key] == out ? (function(C){ - var F = function(a, b, c){ - if(this instanceof C){ - switch(arguments.length){ - case 0: return new C; - case 1: return new C(a); - case 2: return new C(a, b); - } return new C(a, b, c); - } return C.apply(this, arguments); - }; - F[PROTOTYPE] = C[PROTOTYPE]; - return F; - // make static versions for prototype methods - })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; - // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% - if(IS_PROTO){ - (exports.virtual || (exports.virtual = {}))[key] = out; - // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% - if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out); - } - } -}; -// 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` -module.exports = $export; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_fails.js": -/*!********************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_fails.js ***! - \********************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -module.exports = function(exec){ - try { - return !!exec(); - } catch(e){ - return true; - } -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_global.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_global.js ***! - \*********************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -// 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 : Function('return this')(); -if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_hide.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_hide.js ***! - \*******************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var dP = __webpack_require__(/*! ./_object-dp */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_object-dp.js") - , createDesc = __webpack_require__(/*! ./_property-desc */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_property-desc.js"); -module.exports = __webpack_require__(/*! ./_descriptors */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_descriptors.js") ? function(object, key, value){ - return dP.f(object, key, createDesc(1, value)); -} : function(object, key, value){ - object[key] = value; - return object; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_html.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_html.js ***! - \*******************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = __webpack_require__(/*! ./_global */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_global.js").document && document.documentElement; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_ie8-dom-define.js": -/*!*****************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_ie8-dom-define.js ***! - \*****************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = !__webpack_require__(/*! ./_descriptors */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_descriptors.js") && !__webpack_require__(/*! ./_fails */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_fails.js")(function(){ - return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_dom-create.js")('div'), 'a', {get: function(){ return 7; }}).a != 7; -}); - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_invoke.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_invoke.js ***! - \*********************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -// fast apply, http://jsperf.lnkit.com/fast-apply/5 -module.exports = function(fn, args, that){ - var un = that === undefined; - switch(args.length){ - case 0: return un ? fn() - : fn.call(that); - case 1: return un ? fn(args[0]) - : fn.call(that, args[0]); - case 2: return un ? fn(args[0], args[1]) - : fn.call(that, args[0], args[1]); - case 3: return un ? fn(args[0], args[1], args[2]) - : fn.call(that, args[0], args[1], args[2]); - case 4: return un ? fn(args[0], args[1], args[2], args[3]) - : fn.call(that, args[0], args[1], args[2], args[3]); - } return fn.apply(that, args); -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_is-object.js": -/*!************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_is-object.js ***! - \************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -module.exports = function(it){ - return typeof it === 'object' ? it !== null : typeof it === 'function'; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_object-dp.js": -/*!************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_object-dp.js ***! - \************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var anObject = __webpack_require__(/*! ./_an-object */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_an-object.js") - , IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_ie8-dom-define.js") - , toPrimitive = __webpack_require__(/*! ./_to-primitive */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_to-primitive.js") - , dP = Object.defineProperty; - -exports.f = __webpack_require__(/*! ./_descriptors */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_descriptors.js") ? Object.defineProperty : function defineProperty(O, P, Attributes){ - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if(IE8_DOM_DEFINE)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; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_property-desc.js": -/*!****************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_property-desc.js ***! - \****************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -module.exports = function(bitmap, value){ - return { - enumerable : !(bitmap & 1), - configurable: !(bitmap & 2), - writable : !(bitmap & 4), - value : value - }; -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_task.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_task.js ***! - \*******************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var ctx = __webpack_require__(/*! ./_ctx */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_ctx.js") - , invoke = __webpack_require__(/*! ./_invoke */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_invoke.js") - , html = __webpack_require__(/*! ./_html */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_html.js") - , cel = __webpack_require__(/*! ./_dom-create */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_dom-create.js") - , global = __webpack_require__(/*! ./_global */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_global.js") - , process = global.process - , setTask = global.setImmediate - , clearTask = global.clearImmediate - , MessageChannel = global.MessageChannel - , counter = 0 - , queue = {} - , ONREADYSTATECHANGE = 'onreadystatechange' - , defer, channel, port; -var run = function(){ - var id = +this; - if(queue.hasOwnProperty(id)){ - var fn = queue[id]; - delete queue[id]; - fn(); - } -}; -var listener = function(event){ - run.call(event.data); -}; -// Node.js 0.9+ & IE10+ has setImmediate, otherwise: -if(!setTask || !clearTask){ - setTask = function setImmediate(fn){ - var args = [], i = 1; - while(arguments.length > i)args.push(arguments[i++]); - queue[++counter] = function(){ - invoke(typeof fn == 'function' ? fn : Function(fn), args); - }; - defer(counter); - return counter; - }; - clearTask = function clearImmediate(id){ - delete queue[id]; - }; - // Node.js 0.8- - if(__webpack_require__(/*! ./_cof */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_cof.js")(process) == 'process'){ - defer = function(id){ - process.nextTick(ctx(run, id, 1)); - }; - // Browsers with MessageChannel, includes WebWorkers - } else if(MessageChannel){ - channel = new MessageChannel; - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); - // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ - defer = function(id){ - global.postMessage(id + '', '*'); - }; - global.addEventListener('message', listener, false); - // IE8- - } else if(ONREADYSTATECHANGE in cel('script')){ - defer = function(id){ - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ - html.removeChild(this); - run.call(id); - }; - }; - // Rest old browsers - } else { - defer = function(id){ - setTimeout(ctx(run, id, 1), 0); - }; - } -} -module.exports = { - set: setTask, - clear: clearTask -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_to-primitive.js": -/*!***************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/_to-primitive.js ***! - \***************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -// 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(/*! ./_is-object */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_is-object.js"); -// instead of the ES6 spec version, we didn't implement @@toPrimitive case -// and the second argument - flag - preferred type is a string -module.exports = function(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"); -}; - -/***/ }), - -/***/ "./node_modules/scratch-vm/node_modules/core-js/library/modules/web.immediate.js": -/*!***************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/core-js/library/modules/web.immediate.js ***! - \***************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var $export = __webpack_require__(/*! ./_export */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_export.js") - , $task = __webpack_require__(/*! ./_task */ "./node_modules/scratch-vm/node_modules/core-js/library/modules/_task.js"); -$export($export.G + $export.B, { - setImmediate: $task.set, - clearImmediate: $task.clear -}); - /***/ }), /***/ "./node_modules/scratch-vm/node_modules/decode-html/index.js": @@ -220041,8 +219529,8 @@ module.exports = JSON.parse("{\"elementNames\":{\"altglyph\":\"altGlyph\",\"altg /* Module dependencies */ -var ElementType = __webpack_require__(/*! domelementtype */ "./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/domelementtype/lib/index.js"); -var entities = __webpack_require__(/*! entities */ "./node_modules/scratch-vm/node_modules/entities/lib/index.js"); +var ElementType = __webpack_require__(/*! domelementtype */ "./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/domelementtype/lib/esm/index.js"); +var entities = __webpack_require__(/*! entities */ "./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/entities/lib/index.js"); /* mixed-case SVG and MathML tags & attributes recognized by the HTML parser, see @@ -220225,37 +219713,446 @@ function renderComment(elem) { /***/ }), -/***/ "./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/domelementtype/lib/index.js": -/*!******************************************************************************************************!*\ - !*** ./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/domelementtype/lib/index.js ***! - \******************************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { +/***/ "./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/domelementtype/lib/esm/index.js": +/*!**********************************************************************************************************!*\ + !*** ./node_modules/scratch-vm/node_modules/dom-serializer/node_modules/domelementtype/lib/esm/index.js ***! + \**********************************************************************************************************/ +/*! exports provided: ElementType, isTag, Root, Text, Directive, Comment, Script, Style, Tag, CDATA, Doctype */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ElementType", function() { return ElementType; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isTag", function() { return isTag; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Root", function() { return Root; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Text", function() { return Text; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Directive", function() { return Directive; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Comment", function() { return Comment; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Script", function() { return Script; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Style", function() { return Style; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tag", function() { return Tag; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CDATA", function() { return CDATA; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Doctype", function() { return Doctype; }); +/** Types of elements found in htmlparser2's DOM */ +var ElementType; +(function (ElementType) { + /** Type for the root element of a document */ + ElementType["Root"] = "root"; + /** Type for Text */ + ElementType["Text"] = "text"; + /** Type for */ + ElementType["Directive"] = "directive"; + /** Type for */ + ElementType["Comment"] = "comment"; + /** Type for ');\n\n return svgString;\n};\n","/**\n * @fileOverview Convert 2.0 fonts to 3.0 fonts.\n */\n\n/**\n * Given an SVG, replace Scratch 2.0 fonts with new 3.0 fonts. Add defaults where there are none.\n * @param {SVGElement} svgTag The SVG dom object\n * @return {void}\n */\nconst convertFonts = function (svgTag) {\n // Collect all text elements into a list.\n const textElements = [];\n const collectText = domElement => {\n if (domElement.localName === 'text') {\n textElements.push(domElement);\n }\n for (let i = 0; i < domElement.childNodes.length; i++) {\n collectText(domElement.childNodes[i]);\n }\n };\n collectText(svgTag);\n // If there's an old font-family, switch to the new one.\n for (const textElement of textElements) {\n // If there's no font-family provided, provide one.\n if (!textElement.getAttribute('font-family') ||\n textElement.getAttribute('font-family') === 'Helvetica') {\n textElement.setAttribute('font-family', 'Sans Serif');\n } else if (textElement.getAttribute('font-family') === 'Mystery') {\n textElement.setAttribute('font-family', 'Curly');\n } else if (textElement.getAttribute('font-family') === 'Gloria') {\n textElement.setAttribute('font-family', 'Handwriting');\n } else if (textElement.getAttribute('font-family') === 'Donegal') {\n textElement.setAttribute('font-family', 'Serif');\n }\n }\n};\n\nmodule.exports = convertFonts;\n","/**\n * @fileOverview Import bitmap data into Scratch 3.0, resizing image as necessary.\n */\nconst {FONTS} = require('scratch-render-fonts');\n\n/**\n * Given SVG data, inline the fonts. This allows them to be rendered correctly when set\n * as the source of an HTMLImageElement. Here is a note from tmickel:\n * // Inject fonts that are needed.\n * // It would be nice if there were another way to get the SVG-in-canvas\n * // to render the correct font family, but I couldn't find any other way.\n * // Other things I tried:\n * // Just injecting the font-family into the document: no effect.\n * // External stylesheet linked to by SVG: no effect.\n * // Using a or to link to font-family\n * // injected into the document: no effect.\n * @param {string} svgString The string representation of the svg to modify\n * @return {string} The svg with any needed fonts inlined\n */\nconst inlineSvgFonts = function (svgString) {\n // Make it clear that this function only operates on strings.\n // If we don't explicitly throw this here, the function silently fails.\n if (typeof svgString !== 'string') {\n throw new Error('SVG to be inlined is not a string');\n }\n\n // Collect fonts that need injection.\n const fontsNeeded = new Set();\n const fontRegex = /font-family=\"([^\"]*)\"/g;\n let matches = fontRegex.exec(svgString);\n while (matches) {\n fontsNeeded.add(matches[1]);\n matches = fontRegex.exec(svgString);\n }\n if (fontsNeeded.size > 0) {\n let str = '';\n svgString = svgString.replace(/]*>/, `$&${str}`);\n return svgString;\n }\n return svgString;\n};\n\nmodule.exports = inlineSvgFonts;\n","const SVGRenderer = require('./svg-renderer');\nconst BitmapAdapter = require('./bitmap-adapter');\nconst inlineSvgFonts = require('./font-inliner');\nconst SvgElement = require('./svg-element');\nconst convertFonts = require('./font-converter');\n// /**\n// * Export for NPM & Node.js\n// * @type {RenderWebGL}\n// */\nmodule.exports = {\n BitmapAdapter: BitmapAdapter,\n convertFonts: convertFonts,\n inlineSvgFonts: inlineSvgFonts,\n SvgElement: SvgElement,\n SVGRenderer: SVGRenderer\n};\n","/* Adapted from\n * Paper.js - The Swiss Army Knife of Vector Graphics Scripting.\n * http://paperjs.org/\n *\n * Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey\n * http://scratchdisk.com/ & http://jonathanpuckey.com/\n *\n * Distributed under the MIT license. See LICENSE file for details.\n *\n * All rights reserved.\n */\n\n/**\n * @name SvgElement\n * @namespace\n * @private\n */\nclass SvgElement {\n // SVG related namespaces\n static get svg () {\n return 'http://www.w3.org/2000/svg';\n }\n static get xmlns () {\n return 'http://www.w3.org/2000/xmlns';\n }\n static get xlink () {\n return 'http://www.w3.org/1999/xlink';\n }\n\n // Mapping of attribute names to required namespaces:\n static attributeNamespace () {\n return {\n 'href': SvgElement.xlink,\n 'xlink': SvgElement.xmlns,\n // Only the xmlns attribute needs the trailing slash. See #984\n 'xmlns': `${SvgElement.xmlns}/`,\n // IE needs the xmlns namespace when setting 'xmlns:xlink'. See #984\n 'xmlns:xlink': `${SvgElement.xmlns}/`\n };\n }\n\n static create (tag, attributes, formatter) {\n return SvgElement.set(document.createElementNS(SvgElement.svg, tag), attributes, formatter);\n }\n\n static get (node, name) {\n const namespace = SvgElement.attributeNamespace[name];\n const value = namespace ?\n node.getAttributeNS(namespace, name) :\n node.getAttribute(name);\n return value === 'null' ? null : value;\n }\n\n static set (node, attributes, formatter) {\n for (const name in attributes) {\n let value = attributes[name];\n const namespace = SvgElement.attributeNamespace[name];\n if (typeof value === 'number' && formatter) {\n value = formatter.number(value);\n }\n if (namespace) {\n node.setAttributeNS(namespace, name, value);\n } else {\n node.setAttribute(name, value);\n }\n }\n return node;\n }\n}\n\nmodule.exports = SvgElement;\n","const DOMPurify = require('dompurify');\nconst inlineSvgFonts = require('./font-inliner');\nconst SvgElement = require('./svg-element');\nconst convertFonts = require('./font-converter');\nconst fixupSvgString = require('./fixup-svg-string');\nconst transformStrokeWidths = require('./transform-applier');\n\n/**\n * Main quirks-mode SVG rendering code.\n */\nclass SvgRenderer {\n /**\n * Create a quirks-mode SVG renderer for a particular canvas.\n * @param {HTMLCanvasElement} [canvas] An optional canvas element to draw to. If this is not provided, the renderer\n * will create a new canvas.\n * @constructor\n */\n constructor (canvas) {\n this._canvas = canvas || document.createElement('canvas');\n this._context = this._canvas.getContext('2d');\n this._measurements = {x: 0, y: 0, width: 0, height: 0};\n this._cachedImage = null;\n this.loaded = false;\n }\n\n /**\n * @returns {!HTMLCanvasElement} this renderer's target canvas.\n */\n get canvas () {\n return this._canvas;\n }\n\n /**\n * Load an SVG from a string and draw it.\n * This will be parsed and transformed, and finally drawn.\n * When drawing is finished, the `onFinish` callback is called.\n * @param {string} svgString String of SVG data to draw in quirks-mode.\n * @param {number} [scale] - Optionally, also scale the image by this factor.\n * @param {Function} [onFinish] Optional callback for when drawing finished.\n * @deprecated Use the `loadSVG` method and public `draw` method instead.\n */\n fromString (svgString, scale, onFinish) {\n this.loadSVG(svgString, false, () => {\n this.draw(scale);\n if (onFinish) onFinish();\n });\n }\n\n /**\n * Load an SVG from a string and measure it.\n * @param {string} svgString String of SVG data to draw in quirks-mode.\n * @return {object} the natural size, in Scratch units, of this SVG.\n */\n measure (svgString) {\n this.loadString(svgString);\n return this._measurements;\n }\n\n /**\n * @return {Array} the natural size, in Scratch units, of this SVG.\n */\n get size () {\n return [this._measurements.width, this._measurements.height];\n }\n\n /**\n * @return {Array} the offset (upper left corner) of the SVG's view box.\n */\n get viewOffset () {\n return [this._measurements.x, this._measurements.y];\n }\n\n /**\n * Load an SVG string and normalize it. All the steps before drawing/measuring.\n * @param {!string} svgString String of SVG data to draw in quirks-mode.\n * @param {?boolean} fromVersion2 True if we should perform conversion from\n * version 2 to version 3 svg.\n */\n loadString (svgString, fromVersion2) {\n // New svg string invalidates the cached image\n this._cachedImage = null;\n\n // Parse string into SVG XML.\n const parser = new DOMParser();\n svgString = fixupSvgString(svgString);\n this._svgDom = parser.parseFromString(svgString, 'text/xml');\n if (this._svgDom.childNodes.length < 1 ||\n this._svgDom.documentElement.localName !== 'svg') {\n throw new Error('Document does not appear to be SVG.');\n }\n this._svgTag = this._svgDom.documentElement;\n if (fromVersion2) {\n // Fix gradients. Scratch 2 exports no x2 when x2 = 0, but\n // SVG default is that x2 is 1. This must be done before\n // transformStrokeWidths since transformStrokeWidths affects\n // gradients.\n this._transformGradients();\n }\n transformStrokeWidths(this._svgTag, window);\n this._transformImages(this._svgTag);\n if (fromVersion2) {\n // Transform all text elements.\n this._transformText();\n // Transform measurements.\n this._transformMeasurements();\n // Fix stroke roundedness.\n this._setGradientStrokeRoundedness();\n } else if (!this._svgTag.getAttribute('viewBox')) {\n // Renderer expects a view box.\n this._transformMeasurements();\n } else if (!this._svgTag.getAttribute('width') || !this._svgTag.getAttribute('height')) {\n this._svgTag.setAttribute('width', this._svgTag.viewBox.baseVal.width);\n this._svgTag.setAttribute('height', this._svgTag.viewBox.baseVal.height);\n }\n this._measurements = {\n width: this._svgTag.viewBox.baseVal.width,\n height: this._svgTag.viewBox.baseVal.height,\n x: this._svgTag.viewBox.baseVal.x,\n y: this._svgTag.viewBox.baseVal.y\n };\n }\n\n /**\n * Load an SVG string, normalize it, and prepare it for (synchronous) rendering.\n * @param {!string} svgString String of SVG data to draw in quirks-mode.\n * @param {?boolean} fromVersion2 True if we should perform conversion from version 2 to version 3 svg.\n * @param {Function} [onFinish] - An optional callback to call when the SVG is loaded and can be rendered.\n */\n loadSVG (svgString, fromVersion2, onFinish) {\n this.loadString(svgString, fromVersion2);\n this._createSVGImage(onFinish);\n }\n\n /**\n * Creates an element for the currently loaded SVG string, then calls the callback once it's loaded.\n * @param {Function} [onFinish] - An optional callback to call when the has loaded.\n */\n _createSVGImage (onFinish) {\n if (this._cachedImage === null) this._cachedImage = new Image();\n const img = this._cachedImage;\n\n img.onload = () => {\n this.loaded = true;\n if (onFinish) onFinish();\n };\n const svgText = this.toString(true /* shouldInjectFonts */);\n img.src = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;\n this.loaded = false;\n }\n\n /**\n * Transforms an SVG's text elements for Scratch 2.0 quirks.\n * These quirks include:\n * 1. `x` and `y` properties are removed/ignored.\n * 2. Alignment is set to `text-before-edge`.\n * 3. Line-breaks are converted to explicit elements.\n * 4. Any required fonts are injected.\n */\n _transformText () {\n // Collect all text elements into a list.\n const textElements = [];\n const collectText = domElement => {\n if (domElement.localName === 'text') {\n textElements.push(domElement);\n }\n for (let i = 0; i < domElement.childNodes.length; i++) {\n collectText(domElement.childNodes[i]);\n }\n };\n collectText(this._svgTag);\n convertFonts(this._svgTag);\n // For each text element, apply quirks.\n for (const textElement of textElements) {\n // Remove x and y attributes - they are not used in Scratch.\n textElement.removeAttribute('x');\n textElement.removeAttribute('y');\n // Set text-before-edge alignment:\n // Scratch renders all text like this.\n textElement.setAttribute('alignment-baseline', 'text-before-edge');\n textElement.setAttribute('xml:space', 'preserve');\n // If there's no font size provided, provide one.\n if (!textElement.getAttribute('font-size')) {\n textElement.setAttribute('font-size', '18');\n }\n let text = textElement.textContent;\n\n // Fix line breaks in text, which are not natively supported by SVG.\n // Only fix if text does not have child tspans.\n // @todo this will not work for font sizes with units such as em, percent\n // However, text made in scratch 2 should only ever export size 22 font.\n const fontSize = parseFloat(textElement.getAttribute('font-size'));\n const tx = 2;\n let ty = 0;\n let spacing = 1.2;\n // Try to match the position and spacing of Scratch 2.0's fonts.\n // Different fonts seem to use different line spacing.\n // Scratch 2 always uses alignment-baseline=text-before-edge\n // However, most SVG readers don't support this attribute\n // or don't support it alongside use of tspan, so the translations\n // here are to make up for that.\n if (textElement.getAttribute('font-family') === 'Handwriting') {\n spacing = 2;\n ty = -11 * fontSize / 22;\n } else if (textElement.getAttribute('font-family') === 'Scratch') {\n spacing = 0.89;\n ty = -3 * fontSize / 22;\n } else if (textElement.getAttribute('font-family') === 'Curly') {\n spacing = 1.38;\n ty = -6 * fontSize / 22;\n } else if (textElement.getAttribute('font-family') === 'Marker') {\n spacing = 1.45;\n ty = -6 * fontSize / 22;\n } else if (textElement.getAttribute('font-family') === 'Sans Serif') {\n spacing = 1.13;\n ty = -3 * fontSize / 22;\n } else if (textElement.getAttribute('font-family') === 'Serif') {\n spacing = 1.25;\n ty = -4 * fontSize / 22;\n }\n\n if (textElement.transform.baseVal.numberOfItems === 0) {\n const transform = this._svgTag.createSVGTransform();\n textElement.transform.baseVal.appendItem(transform);\n }\n\n // Right multiply matrix by a translation of (tx, ty)\n const mtx = textElement.transform.baseVal.getItem(0).matrix;\n mtx.e += (mtx.a * tx) + (mtx.c * ty);\n mtx.f += (mtx.b * tx) + (mtx.d * ty);\n\n if (text && textElement.childElementCount === 0) {\n textElement.textContent = '';\n const lines = text.split('\\n');\n text = '';\n for (const line of lines) {\n const tspanNode = SvgElement.create('tspan');\n tspanNode.setAttribute('x', '0');\n tspanNode.setAttribute('style', 'white-space: pre');\n tspanNode.setAttribute('dy', `${spacing}em`);\n tspanNode.textContent = line ? line : ' ';\n textElement.appendChild(tspanNode);\n }\n }\n }\n }\n\n /**\n * @param {string} [tagName] svg tag to search for (or collect all elements if not given)\n * @return {Array} a list of elements with the given tagname in _svgTag\n */\n _collectElements (tagName) {\n const elts = [];\n const collectElements = domElement => {\n if ((domElement.localName === tagName || typeof tagName === 'undefined') && domElement.getAttribute) {\n elts.push(domElement);\n }\n for (let i = 0; i < domElement.childNodes.length; i++) {\n collectElements(domElement.childNodes[i]);\n }\n };\n collectElements(this._svgTag);\n return elts;\n }\n\n /**\n * Fix SVGs to comply with SVG spec. Scratch 2 defaults to x2 = 0 when x2 is missing, but\n * SVG defaults to x2 = 1 when missing.\n */\n _transformGradients () {\n const linearGradientElements = this._collectElements('linearGradient');\n\n // For each gradient element, supply x2 if necessary.\n for (const gradientElement of linearGradientElements) {\n if (!gradientElement.getAttribute('x2')) {\n gradientElement.setAttribute('x2', '0');\n }\n }\n }\n\n /**\n * Fix SVGs to match appearance in Scratch 2, which used nearest neighbor scaling for bitmaps\n * within SVGs.\n */\n _transformImages () {\n const imageElements = this._collectElements('image');\n\n // For each image element, set image rendering to pixelated\n const pixelatedImages = 'image-rendering: optimizespeed; image-rendering: pixelated;';\n for (const elt of imageElements) {\n if (elt.getAttribute('style')) {\n elt.setAttribute('style',\n `${pixelatedImages} ${elt.getAttribute('style')}`);\n } else {\n elt.setAttribute('style', pixelatedImages);\n }\n }\n }\n\n /**\n * Find the largest stroke width in the svg. If a shape has no\n * `stroke` property, it has a stroke-width of 0. If it has a `stroke`,\n * it is by default a stroke-width of 1.\n * This is used to enlarge the computed bounding box, which doesn't take\n * stroke width into account.\n * @param {SVGSVGElement} rootNode The root SVG node to traverse.\n * @return {number} The largest stroke width in the SVG.\n */\n _findLargestStrokeWidth (rootNode) {\n let largestStrokeWidth = 0;\n const collectStrokeWidths = domElement => {\n if (domElement.getAttribute) {\n if (domElement.getAttribute('stroke')) {\n largestStrokeWidth = Math.max(largestStrokeWidth, 1);\n }\n if (domElement.getAttribute('stroke-width')) {\n largestStrokeWidth = Math.max(\n largestStrokeWidth,\n Number(domElement.getAttribute('stroke-width')) || 0\n );\n }\n }\n for (let i = 0; i < domElement.childNodes.length; i++) {\n collectStrokeWidths(domElement.childNodes[i]);\n }\n };\n collectStrokeWidths(rootNode);\n return largestStrokeWidth;\n }\n\n /**\n * Find all instances of a URL-referenced `stroke` in the svg. In 2.0, all gradient strokes\n * have a round `stroke-linejoin` and `stroke-linecap`... for some reason.\n */\n _setGradientStrokeRoundedness () {\n const elements = this._collectElements();\n\n for (const elt of elements) {\n if (!elt.style) continue;\n const stroke = elt.style.stroke || elt.getAttribute('stroke');\n if (stroke && stroke.match(/^url\\(#.*\\)$/)) {\n elt.style['stroke-linejoin'] = 'round';\n elt.style['stroke-linecap'] = 'round';\n }\n }\n }\n\n /**\n * Transform the measurements of the SVG.\n * In Scratch 2.0, SVGs are drawn without respect to the width,\n * height, and viewBox attribute on the tag. The exporter\n * does output these properties - but they appear to be incorrect often.\n * To address the incorrect measurements, we append the DOM to the\n * document, and then use SVG's native `getBBox` to find the real\n * drawn dimensions. This ensures things drawn in negative dimensions,\n * outside the given viewBox, etc., are all eventually drawn to the canvas.\n * I tried to do this several other ways: stripping the width/height/viewBox\n * attributes and then drawing (Firefox won't draw anything),\n * or inflating them and then measuring a canvas. But this seems to be\n * a natural and performant way.\n */\n _transformMeasurements () {\n // Append the SVG dom to the document.\n // This allows us to use `getBBox` on the page,\n // which returns the full bounding-box of all drawn SVG\n // elements, similar to how Scratch 2.0 did measurement.\n const svgSpot = document.createElement('span');\n // Since we're adding user-provided SVG to document.body,\n // sanitizing is required. This should not affect bounding box calculation.\n // outerHTML is attribute of Element (and not HTMLElement), so use it instead of\n // calling serializer or toString()\n // NOTE: this._svgTag remains untouched!\n const rawValue = this._svgTag.outerHTML;\n const sanitizedValue = DOMPurify.sanitize(rawValue, {\n // Use SVG profile (no HTML elements)\n USE_PROFILES: {svg: true},\n // Remove some tags that Scratch does not use.\n FORBID_TAGS: ['a', 'audio', 'canvas', 'video'],\n // Allow data URI in image tags (e.g. SVGs converted from bitmap)\n ADD_DATA_URI_TAGS: ['image']\n });\n let bbox;\n try {\n // Insert sanitized value.\n svgSpot.innerHTML = sanitizedValue;\n document.body.appendChild(svgSpot);\n // Take the bounding box. We have to get elements via svgSpot\n // because we added it via innerHTML.\n bbox = svgSpot.children[0].getBBox();\n } finally {\n // Always destroy the element, even if, for example, getBBox throws.\n document.body.removeChild(svgSpot);\n }\n\n // Enlarge the bbox from the largest found stroke width\n // This may have false-positives, but at least the bbox will always\n // contain the full graphic including strokes.\n // If the width or height is zero however, don't enlarge since\n // they won't have a stroke width that needs to be enlarged.\n let halfStrokeWidth;\n if (bbox.width === 0 || bbox.height === 0) {\n halfStrokeWidth = 0;\n } else {\n halfStrokeWidth = this._findLargestStrokeWidth(this._svgTag) / 2;\n }\n const width = bbox.width + (halfStrokeWidth * 2);\n const height = bbox.height + (halfStrokeWidth * 2);\n const x = bbox.x - halfStrokeWidth;\n const y = bbox.y - halfStrokeWidth;\n\n // Set the correct measurements on the SVG tag\n this._svgTag.setAttribute('width', width);\n this._svgTag.setAttribute('height', height);\n this._svgTag.setAttribute('viewBox',\n `${x} ${y} ${width} ${height}`);\n }\n\n /**\n * Serialize the active SVG DOM to a string.\n * @param {?boolean} shouldInjectFonts True if fonts should be included in the SVG as\n * base64 data.\n * @returns {string} String representing current SVG data.\n */\n toString (shouldInjectFonts) {\n const serializer = new XMLSerializer();\n let string = serializer.serializeToString(this._svgDom);\n if (shouldInjectFonts) {\n string = inlineSvgFonts(string);\n }\n return string;\n }\n\n /**\n * Synchronously draw the loaded SVG to this renderer's `canvas`.\n * @param {number} [scale] - Optionally, also scale the image by this factor.\n */\n draw (scale) {\n if (!this.loaded) throw new Error('SVG image has not finished loading');\n this._drawFromImage(scale);\n }\n\n /**\n * Asynchronously draw the (possibly non-loaded) SVG to a canvas.\n * @param {number} [scale] - Optionally, also scale the image by this factor.\n * @param {Function} [onFinish] - An optional callback to call when the draw operation is complete.\n * @deprecated Use the `loadSVG` and public `draw` method instead.\n */\n _draw (scale, onFinish) {\n // Convert the SVG text to an Image, and then draw it to the canvas.\n if (this._cachedImage === null) {\n this._createSVGImage(() => {\n this._drawFromImage(scale);\n onFinish();\n });\n } else {\n this._drawFromImage(scale);\n onFinish();\n }\n }\n\n /**\n * Draw to the canvas from a loaded image element.\n * @param {number} [scale] - Optionally, also scale the image by this factor.\n **/\n _drawFromImage (scale) {\n if (this._cachedImage === null) return;\n\n const ratio = Number.isFinite(scale) ? scale : 1;\n const bbox = this._measurements;\n this._canvas.width = bbox.width * ratio;\n this._canvas.height = bbox.height * ratio;\n // Even if the canvas at the current scale has a nonzero size, the image's dimensions are floored pre-scaling.\n // e.g. if an image has a width of 0.4 and is being rendered at 3x scale, the canvas will have a width of 1, but\n // the image's width will be rounded down to 0 on some browsers (Firefox) prior to being drawn at that scale.\n if (\n this._canvas.width <= 0 ||\n this._canvas.height <= 0 ||\n this._cachedImage.naturalWidth <= 0 ||\n this._cachedImage.naturalHeight <= 0\n ) return;\n this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);\n this._context.scale(ratio, ratio);\n this._context.drawImage(this._cachedImage, 0, 0);\n // Reset the canvas transform after drawing.\n this._context.setTransform(1, 0, 0, 1, 0, 0);\n // Set the CSS style of the canvas to the actual measurements.\n this._canvas.style.width = bbox.width;\n this._canvas.style.height = bbox.height;\n }\n}\n\nmodule.exports = SvgRenderer;\n","const Matrix = require('transformation-matrix');\nconst SvgElement = require('./svg-element');\nconst log = require('./util/log');\n\n/**\n * @fileOverview Apply transforms to match stroke width appearance in 2.0 and 3.0\n */\n\n// Adapted from paper.js's Path.applyTransform\nconst _parseTransform = function (domElement) {\n let matrix = Matrix.identity();\n const string = domElement.attributes && domElement.attributes.transform && domElement.attributes.transform.value;\n if (!string) return matrix;\n // https://www.w3.org/TR/SVG/types.html#DataTypeTransformList\n // Parse SVG transform string. First we split at /)\\s*/, to separate\n // commands\n const transforms = string.split(/\\)\\s*/g);\n for (const transform of transforms) {\n if (!transform) break;\n // Command come before the '(', values after\n const parts = transform.split(/\\(\\s*/);\n const command = parts[0].trim();\n const v = parts[1].split(/[\\s,]+/g);\n // Convert values to floats\n for (let j = 0; j < v.length; j++) {\n v[j] = parseFloat(v[j]);\n }\n switch (command) {\n case 'matrix':\n matrix = Matrix.compose(matrix, {a: v[0], b: v[1], c: v[2], d: v[3], e: v[4], f: v[5]});\n break;\n case 'rotate':\n matrix = Matrix.compose(matrix, Matrix.rotateDEG(v[0], v[1] || 0, v[2] || 0));\n break;\n case 'translate':\n matrix = Matrix.compose(matrix, Matrix.translate(v[0], v[1] || 0));\n break;\n case 'scale':\n matrix = Matrix.compose(matrix, Matrix.scale(v[0], v[1] || v[0]));\n break;\n case 'skewX':\n matrix = Matrix.compose(matrix, Matrix.skewDEG(v[0], 0));\n break;\n case 'skewY':\n matrix = Matrix.compose(matrix, Matrix.skewDEG(0, v[0]));\n break;\n default:\n log.error(`Couldn't parse: ${command}`);\n }\n }\n return matrix;\n};\n\n// Adapted from paper.js's Matrix.decompose\n// Given a matrix, return the x and y scale factors of the matrix\nconst _getScaleFactor = function (matrix) {\n const a = matrix.a;\n const b = matrix.b;\n const c = matrix.c;\n const d = matrix.d;\n const det = (a * d) - (b * c);\n\n if (a !== 0 || b !== 0) {\n const r = Math.sqrt((a * a) + (b * b));\n return {x: r, y: det / r};\n }\n if (c !== 0 || d !== 0) {\n const s = Math.sqrt((c * c) + (d * d));\n return {x: det / s, y: s};\n }\n // a = b = c = d = 0\n return {x: 0, y: 0};\n};\n\n// Returns null if matrix is not invertible. Otherwise returns given ellipse\n// transformed by transform, an object {radiusX, radiusY, rotation}.\nconst _calculateTransformedEllipse = function (radiusX, radiusY, theta, transform) {\n theta = -theta * Math.PI / 180;\n const a = transform.a;\n const b = -transform.c;\n const c = -transform.b;\n const d = transform.d;\n // Since other parameters determine the translation of the ellipse in SVG, we do not need to worry\n // about what e and f are.\n const det = (a * d) - (b * c);\n // Non-invertible matrix\n if (det === 0) return null;\n\n // rotA, rotB, and rotC represent Ax^2 + Bxy + Cy^2 = 1 coefficients for a rotated ellipse formula\n const sinT = Math.sin(theta);\n const cosT = Math.cos(theta);\n const sin2T = Math.sin(2 * theta);\n const rotA = (cosT * cosT / radiusX / radiusX) + (sinT * sinT / radiusY / radiusY);\n const rotB = (sin2T / radiusX / radiusX) - (sin2T / radiusY / radiusY);\n const rotC = (sinT * sinT / radiusX / radiusX) + (cosT * cosT / radiusY / radiusY);\n\n // Calculate the ellipse formula of the transformed ellipse\n // A, B, and C represent Ax^2 + Bxy + Cy^2 = 1 / det / det coefficients in a transformed ellipse formula\n // scaled by inverse det squared (to preserve accuracy)\n const A = ((rotA * d * d) - (rotB * d * c) + (rotC * c * c));\n const B = ((-2 * rotA * b * d) + (rotB * a * d) + (rotB * b * c) - (2 * rotC * a * c));\n const C = ((rotA * b * b) - (rotB * a * b) + (rotC * a * a));\n\n // Derive new radii and theta from the transformed ellipse formula\n const newRadiusXOverDet = Math.sqrt(2) *\n Math.sqrt(\n (A + C - Math.sqrt((A * A) + (B * B) - (2 * A * C) + (C * C))) /\n ((-B * B) + (4 * A * C))\n );\n const newRadiusYOverDet = 1 / Math.sqrt(A + C - (1 / newRadiusXOverDet / newRadiusXOverDet));\n let temp = (A - (1 / newRadiusXOverDet / newRadiusXOverDet)) /\n ((1 / newRadiusYOverDet / newRadiusYOverDet) - (1 / newRadiusXOverDet / newRadiusXOverDet));\n if (temp < 0 && Math.abs(temp) < 1e-8) temp = 0; // Fix floating point issue\n temp = Math.sqrt(temp);\n if (Math.abs(1 - temp) < 1e-8) temp = 1; // Fix floating point issue\n // Solve for which of the two possible thetas is correct\n let newTheta = Math.asin(temp);\n temp = (B / (\n (1 / newRadiusXOverDet / newRadiusXOverDet) -\n (1 / newRadiusYOverDet / newRadiusYOverDet)));\n const newTheta2 = -newTheta;\n if (Math.abs(Math.sin(2 * newTheta2) - temp) <\n Math.abs(Math.sin(2 * newTheta) - temp)) {\n newTheta = newTheta2;\n }\n\n return {\n radiusX: newRadiusXOverDet * det,\n radiusY: newRadiusYOverDet * det,\n rotation: -newTheta * 180 / Math.PI\n };\n};\n\n// Adapted from paper.js's PathItem.setPathData\nconst _transformPath = function (pathString, transform) {\n if (!transform || Matrix.toString(transform) === Matrix.toString(Matrix.identity())) return pathString;\n // First split the path data into parts of command-coordinates pairs\n // Commands are any of these characters: mzlhvcsqta\n const parts = pathString && pathString.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig);\n let coords;\n let relative = false;\n let previous;\n let control;\n let current = {x: 0, y: 0};\n let start = {x: 0, y: 0};\n let result = '';\n\n const getCoord = function (index, coord) {\n let val = +coords[index];\n if (relative) {\n val += current[coord];\n }\n return val;\n };\n\n const getPoint = function (index) {\n return {x: getCoord(index, 'x'), y: getCoord(index + 1, 'y')};\n };\n\n const roundTo4Places = function (num) {\n return Number(num.toFixed(4));\n };\n\n // Returns the transformed point as a string\n const getString = function (point) {\n const transformed = Matrix.applyToPoint(transform, point);\n return `${roundTo4Places(transformed.x)} ${roundTo4Places(transformed.y)} `;\n };\n\n for (let i = 0, l = parts && parts.length; i < l; i++) {\n const part = parts[i];\n const command = part[0];\n const lower = command.toLowerCase();\n // Match all coordinate values\n coords = part.match(/[+-]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][+-]?\\d+)?/g);\n const length = coords && coords.length;\n relative = command === lower;\n // Fix issues with z in the middle of SVG path data, not followed by\n // a m command, see paper.js#413:\n if (previous === 'z' && !/[mz]/.test(lower)) {\n result += `M ${current.x} ${current.y} `;\n }\n switch (lower) {\n case 'm': // Move to\n case 'l': // Line to\n {\n let move = lower === 'm';\n for (let j = 0; j < length; j += 2) {\n result += move ? 'M ' : 'L ';\n current = getPoint(j);\n result += getString(current);\n if (move) {\n start = current;\n move = false;\n }\n }\n control = current;\n break;\n }\n case 'h': // Horizontal line\n case 'v': // Vertical line\n {\n const coord = lower === 'h' ? 'x' : 'y';\n current = {x: current.x, y: current.y}; // Clone as we're going to modify it.\n for (let j = 0; j < length; j++) {\n current[coord] = getCoord(j, coord);\n result += `L ${getString(current)}`;\n }\n control = current;\n break;\n }\n case 'c':\n // Cubic Bezier curve\n for (let j = 0; j < length; j += 6) {\n const handle1 = getPoint(j);\n control = getPoint(j + 2);\n current = getPoint(j + 4);\n result += `C ${getString(handle1)}${getString(control)}${getString(current)}`;\n }\n break;\n case 's':\n // Smooth cubic Bezier curve\n for (let j = 0; j < length; j += 4) {\n const handle1 = /[cs]/.test(previous) ?\n {x: (current.x * 2) - control.x, y: (current.y * 2) - control.y} :\n current;\n control = getPoint(j);\n current = getPoint(j + 2);\n\n result += `C ${getString(handle1)}${getString(control)}${getString(current)}`;\n previous = lower;\n }\n break;\n case 'q':\n // Quadratic Bezier curve\n for (let j = 0; j < length; j += 4) {\n control = getPoint(j);\n current = getPoint(j + 2);\n result += `Q ${getString(control)}${getString(current)}`;\n }\n break;\n case 't':\n // Smooth quadratic Bezier curve\n for (let j = 0; j < length; j += 2) {\n control = /[qt]/.test(previous) ?\n {x: (current.x * 2) - control.x, y: (current.y * 2) - control.y} :\n current;\n current = getPoint(j);\n\n result += `Q ${getString(control)}${getString(current)}`;\n previous = lower;\n }\n break;\n case 'a':\n // Elliptical arc curve\n for (let j = 0; j < length; j += 7) {\n current = getPoint(j + 5);\n const rx = +coords[j];\n const ry = +coords[j + 1];\n const rotation = +coords[j + 2];\n const largeArcFlag = +coords[j + 3];\n let clockwiseFlag = +coords[j + 4];\n const newEllipse = _calculateTransformedEllipse(rx, ry, rotation, transform);\n const matrixScale = _getScaleFactor(transform);\n if (newEllipse) {\n if ((matrixScale.x > 0 && matrixScale.y < 0) ||\n (matrixScale.x < 0 && matrixScale.y > 0)) {\n clockwiseFlag = clockwiseFlag ^ 1;\n }\n result += `A ${roundTo4Places(Math.abs(newEllipse.radiusX))} ` +\n `${roundTo4Places(Math.abs(newEllipse.radiusY))} ` +\n `${roundTo4Places(newEllipse.rotation)} ${largeArcFlag} ` +\n `${clockwiseFlag} ${getString(current)}`;\n } else {\n result += `L ${getString(current)}`;\n }\n }\n break;\n case 'z':\n // Close path\n result += `Z `;\n // Correctly handle relative m commands, see paper.js#1101:\n current = start;\n break;\n }\n previous = lower;\n }\n return result;\n};\n\nconst GRAPHICS_ELEMENTS = ['circle', 'ellipse', 'image', 'line', 'path', 'polygon', 'polyline', 'rect', 'text', 'use'];\nconst CONTAINER_ELEMENTS = ['a', 'defs', 'g', 'marker', 'glyph', 'missing-glyph', 'pattern', 'svg', 'switch', 'symbol'];\nconst _isContainerElement = function (element) {\n return element.tagName && CONTAINER_ELEMENTS.includes(element.tagName.toLowerCase());\n};\nconst _isGraphicsElement = function (element) {\n return element.tagName && GRAPHICS_ELEMENTS.includes(element.tagName.toLowerCase());\n};\nconst _isPathWithTransformAndStroke = function (element, strokeWidth) {\n if (!element.attributes) return false;\n strokeWidth = element.attributes['stroke-width'] ?\n Number(element.attributes['stroke-width'].value) : Number(strokeWidth);\n return strokeWidth &&\n element.tagName && element.tagName.toLowerCase() === 'path' &&\n element.attributes.d && element.attributes.d.value;\n};\nconst _quadraticMean = function (a, b) {\n return Math.sqrt(((a * a) + (b * b)) / 2);\n};\n\nconst _createGradient = function (gradientId, svgTag, bbox, matrix) {\n // Adapted from Paper.js's SvgImport.getValue\n const getValue = function (node, name, isString, allowNull, allowPercent, defaultValue) {\n // Interpret value as number. Never return NaN, but 0 instead.\n // If the value is a sequence of numbers, parseFloat will\n // return the first occurring number, which is enough for now.\n let value = SvgElement.get(node, name);\n let res;\n if (value === null) {\n if (defaultValue) {\n res = defaultValue;\n if (/%\\s*$/.test(res)) {\n value = defaultValue;\n res = parseFloat(value);\n }\n } else if (allowNull) {\n res = null;\n } else if (isString) {\n res = '';\n } else {\n res = 0;\n }\n } else if (isString) {\n res = value;\n } else {\n res = parseFloat(value);\n }\n // Support for dimensions in percentage of the root size. If root-size\n // is not set (e.g. during ), just scale the percentage value to\n // 0..1, as required by gradients with gradientUnits=\"objectBoundingBox\"\n if (/%\\s*$/.test(value)) {\n const size = allowPercent ? 1 : bbox[/x|^width/.test(name) ? 'width' : 'height'];\n return res / 100 * size;\n }\n return res;\n };\n const getPoint = function (node, x, y, allowNull, allowPercent, defaultX, defaultY) {\n x = getValue(node, x || 'x', false, allowNull, allowPercent, defaultX);\n y = getValue(node, y || 'y', false, allowNull, allowPercent, defaultY);\n return allowNull && (x === null || y === null) ? null : {x, y};\n };\n\n let defs = svgTag.getElementsByTagName('defs');\n if (defs.length === 0) {\n defs = SvgElement.create('defs');\n svgTag.appendChild(defs);\n } else {\n defs = defs[0];\n }\n\n // Clone the old gradient. We'll make a new one, since the gradient might be reused elsewhere\n // with different transform matrix\n const oldGradient = svgTag.getElementById(gradientId);\n if (!oldGradient) return;\n\n const radial = oldGradient.tagName.toLowerCase() === 'radialgradient';\n const newGradient = svgTag.getElementById(gradientId).cloneNode(true /* deep */);\n\n // Give the new gradient a new ID\n let matrixString = Matrix.toString(matrix);\n matrixString = matrixString.substring(8, matrixString.length - 1);\n const newGradientId = `${gradientId}-${matrixString}`;\n newGradient.setAttribute('id', newGradientId);\n\n // This gradient already exists and was transformed before. Just reuse the already-transformed one.\n if (svgTag.getElementById(newGradientId)) {\n // This is the same code as in the end of the function, but I don't feel like wrapping the next 80 lines\n // in an `if (!svgTag.getElementById(newGradientId))` block\n return `url(#${newGradientId})`;\n }\n\n const scaleToBounds = getValue(newGradient, 'gradientUnits', true) !==\n 'userSpaceOnUse';\n let origin;\n let destination;\n let radius;\n let focal;\n if (radial) {\n origin = getPoint(newGradient, 'cx', 'cy', false, scaleToBounds, '50%', '50%');\n radius = getValue(newGradient, 'r', false, false, scaleToBounds, '50%');\n focal = getPoint(newGradient, 'fx', 'fy', true, scaleToBounds);\n } else {\n origin = getPoint(newGradient, 'x1', 'y1', false, scaleToBounds);\n destination = getPoint(newGradient, 'x2', 'y2', false, scaleToBounds, '1');\n if (origin.x === destination.x && origin.y === destination.y) {\n // If it's degenerate, use the color of the last stop, as described by\n // https://www.w3.org/TR/SVG/pservers.html#LinearGradientNotes\n const stops = newGradient.getElementsByTagName('stop');\n if (!stops.length || !stops[stops.length - 1].attributes ||\n !stops[stops.length - 1].attributes['stop-color']) {\n return null;\n }\n return stops[stops.length - 1].attributes['stop-color'].value;\n }\n }\n\n // Transform points\n // Emulate SVG's gradientUnits=\"objectBoundingBox\"\n if (scaleToBounds) {\n const boundsMatrix = Matrix.compose(Matrix.translate(bbox.x, bbox.y), Matrix.scale(bbox.width, bbox.height));\n origin = Matrix.applyToPoint(boundsMatrix, origin);\n if (destination) destination = Matrix.applyToPoint(boundsMatrix, destination);\n if (radius) {\n radius = _quadraticMean(bbox.width, bbox.height) * radius;\n }\n if (focal) focal = Matrix.applyToPoint(boundsMatrix, focal);\n }\n\n if (radial) {\n origin = Matrix.applyToPoint(matrix, origin);\n const matrixScale = _getScaleFactor(matrix);\n radius = _quadraticMean(matrixScale.x, matrixScale.y) * radius;\n if (focal) focal = Matrix.applyToPoint(matrix, focal);\n } else {\n const dot = (a, b) => (a.x * b.x) + (a.y * b.y);\n const multiply = (coefficient, v) => ({x: coefficient * v.x, y: coefficient * v.y});\n const add = (a, b) => ({x: a.x + b.x, y: a.y + b.y});\n const subtract = (a, b) => ({x: a.x - b.x, y: a.y - b.y});\n\n // The line through origin and gradientPerpendicular is the line at which the gradient starts\n let gradientPerpendicular = Math.abs(origin.x - destination.x) < 1e-8 ?\n add(origin, {x: 1, y: (origin.x - destination.x) / (destination.y - origin.y)}) :\n add(origin, {x: (destination.y - origin.y) / (origin.x - destination.x), y: 1});\n\n // Transform points\n gradientPerpendicular = Matrix.applyToPoint(matrix, gradientPerpendicular);\n origin = Matrix.applyToPoint(matrix, origin);\n destination = Matrix.applyToPoint(matrix, destination);\n\n // Calculate the direction that the gradient has changed to\n const originToPerpendicular = subtract(gradientPerpendicular, origin);\n const originToDestination = subtract(destination, origin);\n const gradientDirection = Math.abs(originToPerpendicular.x) < 1e-8 ?\n {x: 1, y: -originToPerpendicular.x / originToPerpendicular.y} :\n {x: -originToPerpendicular.y / originToPerpendicular.x, y: 1};\n\n // Set the destination so that the gradient moves in the correct direction, by projecting the destination vector\n // onto the gradient direction vector\n const projectionCoeff = dot(originToDestination, gradientDirection) / dot(gradientDirection, gradientDirection);\n const projection = multiply(projectionCoeff, gradientDirection);\n destination = {x: origin.x + projection.x, y: origin.y + projection.y};\n }\n\n // Put values back into svg\n if (radial) {\n newGradient.setAttribute('cx', Number(origin.x.toFixed(4)));\n newGradient.setAttribute('cy', Number(origin.y.toFixed(4)));\n newGradient.setAttribute('r', Number(radius.toFixed(4)));\n if (focal) {\n newGradient.setAttribute('fx', Number(focal.x.toFixed(4)));\n newGradient.setAttribute('fy', Number(focal.y.toFixed(4)));\n }\n } else {\n newGradient.setAttribute('x1', Number(origin.x.toFixed(4)));\n newGradient.setAttribute('y1', Number(origin.y.toFixed(4)));\n newGradient.setAttribute('x2', Number(destination.x.toFixed(4)));\n newGradient.setAttribute('y2', Number(destination.y.toFixed(4)));\n }\n newGradient.setAttribute('gradientUnits', 'userSpaceOnUse');\n defs.appendChild(newGradient);\n\n return `url(#${newGradientId})`;\n};\n\n// Adapted from paper.js's SvgImport.getDefinition\nconst _parseUrl = (value, windowRef) => {\n // When url() comes from a style property, '#'' seems to be missing on\n // WebKit. We also get variations of quotes or no quotes, single or\n // double, so handle it all with one regular expression:\n const match = value && value.match(/\\((?:[\"'#]*)([^\"')]+)/);\n const name = match && match[1];\n const res = name && windowRef ?\n // This is required by Firefox, which can produce absolute\n // urls for local gradients, see paperjs#1001:\n name.replace(`${windowRef.location.href.split('#')[0]}#`, '') :\n name;\n return res;\n};\n\n/**\n * Scratch 2.0 displays stroke widths in a \"normalized\" way, that is,\n * if a shape with a stroke width has a transform applied, it will be\n * rendered with a stroke that is the same width all the way around,\n * instead of stretched looking.\n *\n * The vector paint editor also prefers to normalize the stroke width,\n * rather than keep track of transforms at the group level, as this\n * simplifies editing (e.g. stroke width 3 always means the same thickness)\n *\n * This function performs that normalization process, pushing transforms\n * on groups down to the leaf level and averaging out the stroke width\n * around the shapes. Note that this doens't just change stroke widths, it\n * changes path data and attributes throughout the SVG.\n *\n * @param {SVGElement} svgTag The SVG dom object\n * @param {Window} windowRef The window to use. Need to pass in for\n * tests to work, as they get angry at even the mention of window.\n * @param {object} bboxForTesting The bounds to use. Need to pass in for\n * tests only, because getBBox doesn't work in Node. This should\n * be the bounds of the svgTag without including stroke width or transforms.\n * @return {void}\n */\nconst transformStrokeWidths = function (svgTag, windowRef, bboxForTesting) {\n const inherited = Matrix.identity();\n\n const applyTransforms = (element, matrix, strokeWidth, fill, stroke) => {\n if (_isContainerElement(element)) {\n // Push fills and stroke width down to leaves\n if (element.attributes['stroke-width']) {\n strokeWidth = element.attributes['stroke-width'].value;\n }\n if (element.attributes) {\n if (element.attributes.fill) fill = element.attributes.fill.value;\n if (element.attributes.stroke) stroke = element.attributes.stroke.value;\n }\n\n // If any child nodes don't take attributes, leave the attributes\n // at the parent level.\n for (let i = 0; i < element.childNodes.length; i++) {\n applyTransforms(\n element.childNodes[i],\n Matrix.compose(matrix, _parseTransform(element)),\n strokeWidth,\n fill,\n stroke\n );\n }\n element.removeAttribute('transform');\n element.removeAttribute('stroke-width');\n element.removeAttribute('fill');\n element.removeAttribute('stroke');\n } else if (_isPathWithTransformAndStroke(element, strokeWidth)) {\n if (element.attributes['stroke-width']) {\n strokeWidth = element.attributes['stroke-width'].value;\n }\n if (element.attributes.fill) fill = element.attributes.fill.value;\n if (element.attributes.stroke) stroke = element.attributes.stroke.value;\n matrix = Matrix.compose(matrix, _parseTransform(element));\n if (Matrix.toString(matrix) === Matrix.toString(Matrix.identity())) {\n element.removeAttribute('transform');\n element.setAttribute('stroke-width', strokeWidth);\n if (fill) element.setAttribute('fill', fill);\n if (stroke) element.setAttribute('stroke', stroke);\n return;\n }\n\n // Transform gradient\n const fillGradientId = _parseUrl(fill, windowRef);\n const strokeGradientId = _parseUrl(stroke, windowRef);\n\n if (fillGradientId || strokeGradientId) {\n const doc = windowRef.document;\n // Need path bounds to transform gradient\n const svgSpot = doc.createElement('span');\n let bbox;\n if (bboxForTesting) {\n bbox = bboxForTesting;\n } else {\n try {\n doc.body.appendChild(svgSpot);\n const svg = SvgElement.set(doc.createElementNS(SvgElement.svg, 'svg'));\n const path = SvgElement.set(doc.createElementNS(SvgElement.svg, 'path'));\n path.setAttribute('d', element.attributes.d.value);\n svg.appendChild(path);\n svgSpot.appendChild(svg);\n // Take the bounding box.\n bbox = svg.getBBox();\n } finally {\n // Always destroy the element, even if, for example, getBBox throws.\n doc.body.removeChild(svgSpot);\n }\n }\n\n if (fillGradientId) {\n const newFillRef = _createGradient(fillGradientId, svgTag, bbox, matrix);\n if (newFillRef) fill = newFillRef;\n }\n\n if (strokeGradientId) {\n const newStrokeRef = _createGradient(strokeGradientId, svgTag, bbox, matrix);\n if (newStrokeRef) stroke = newStrokeRef;\n }\n }\n\n // Transform path data\n element.setAttribute('d', _transformPath(element.attributes.d.value, matrix));\n element.removeAttribute('transform');\n\n // Transform stroke width\n const matrixScale = _getScaleFactor(matrix);\n element.setAttribute('stroke-width', _quadraticMean(matrixScale.x, matrixScale.y) * strokeWidth);\n if (fill) element.setAttribute('fill', fill);\n if (stroke) element.setAttribute('stroke', stroke);\n } else if (_isGraphicsElement(element)) {\n // Push stroke width, fill, and stroke down to leaves\n if (strokeWidth && !element.attributes['stroke-width']) {\n element.setAttribute('stroke-width', strokeWidth);\n }\n if (fill && !element.attributes.fill) {\n element.setAttribute('fill', fill);\n }\n if (stroke && !element.attributes.stroke) {\n element.setAttribute('stroke', stroke);\n }\n\n // Push transform down to leaves\n matrix = Matrix.compose(matrix, _parseTransform(element));\n if (Matrix.toString(matrix) === Matrix.toString(Matrix.identity())) {\n element.removeAttribute('transform');\n } else {\n element.setAttribute('transform', Matrix.toString(matrix));\n }\n }\n };\n applyTransforms(svgTag, inherited, 1 /* default SVG stroke width */);\n};\n\nmodule.exports = transformStrokeWidths;\n","const minilog = require('minilog');\nminilog.enable();\n\nmodule.exports = minilog('scratch-svg-render');\n","/**\n * Copyright (c) 2019 Vernier Software. All rights reserved.\n * This code may only be used under the BSD 3-Clause license found at\n * https://raw.githubusercontent.com/VernierST/godirect-js/master/LICENSE\n */\n\n!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=e||self).godirect=t()}(this,function(){\"use strict\";function e(e,t,n,r,i,a,o){try{var s=e[a](o),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(r,i)}function t(t){return function(){var n=this,r=arguments;return new Promise(function(i,a){var o=t.apply(n,r);function s(t){e(o,i,a,s,u,\"next\",t)}function u(t){e(o,i,a,s,u,\"throw\",t)}s(void 0)})}}function n(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}function r(e,t){for(var n=0;n=0;--a){var o=this.tryEntries[a],s=o.completion;if(\"root\"===o.tryLoc)return i(\"end\");if(o.tryLoc<=this.prev){var u=r.call(o,\"catchLoc\"),c=r.call(o,\"finallyLoc\");if(u&&c){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,\"finallyLoc\")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),M(n),d}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if(\"throw\"===r.type){var i=r.arg;M(n)}return i}}throw new Error(\"illegal catch attempt\")},delegateYield:function(e,n,r){return this.delegate={iterator:C(e),resultName:n,nextLoc:r},\"next\"===this.method&&(this.arg=t),d}}}function b(e,t,n,r){var i=t&&t.prototype instanceof _?t:_,a=Object.create(i.prototype),o=new A(r||[]);return a._invoke=function(e,t,n){var r=f;return function(i,a){if(r===l)throw new Error(\"Generator is already running\");if(r===p){if(\"throw\"===i)throw a;return L()}for(n.method=i,n.arg=a;;){var o=n.delegate;if(o){var s=R(o,n);if(s){if(s===d)continue;return s}}if(\"next\"===n.method)n.sent=n._sent=n.arg;else if(\"throw\"===n.method){if(r===f)throw r=p,n.arg;n.dispatchException(n.arg)}else\"return\"===n.method&&n.abrupt(\"return\",n.arg);r=l;var u=w(e,t,n);if(\"normal\"===u.type){if(r=n.done?p:h,u.arg===d)continue;return{value:u.arg,done:n.done}}\"throw\"===u.type&&(r=p,n.method=\"throw\",n.arg=u.arg)}}}(e,n,o),a}function w(e,t,n){try{return{type:\"normal\",arg:e.call(t,n)}}catch(e){return{type:\"throw\",arg:e}}}function _(){}function k(){}function x(){}function E(e){[\"next\",\"throw\",\"return\"].forEach(function(t){e[t]=function(e){return this._invoke(t,e)}})}function S(e){var t;this._invoke=function(n,i){function a(){return new Promise(function(t,a){!function t(n,i,a,o){var s=w(e[n],e,i);if(\"throw\"!==s.type){var u=s.arg,c=u.value;return c&&\"object\"==typeof c&&r.call(c,\"__await\")?Promise.resolve(c.__await).then(function(e){t(\"next\",e,a,o)},function(e){t(\"throw\",e,a,o)}):Promise.resolve(c).then(function(e){u.value=e,a(u)},function(e){return t(\"throw\",e,a,o)})}o(s.arg)}(n,i,t,a)})}return t=t?t.then(a,a):a()}}function R(e,n){var r=e.iterator[n.method];if(r===t){if(n.delegate=null,\"throw\"===n.method){if(e.iterator.return&&(n.method=\"return\",n.arg=t,R(e,n),\"throw\"===n.method))return d;n.method=\"throw\",n.arg=new TypeError(\"The iterator does not provide a 'throw' method\")}return d}var i=w(r,e.iterator,n.arg);if(\"throw\"===i.type)return n.method=\"throw\",n.arg=i.arg,n.delegate=null,d;var a=i.arg;return a?a.done?(n[e.resultName]=a.value,n.next=e.nextLoc,\"return\"!==n.method&&(n.method=\"next\",n.arg=t),n.delegate=null,d):a:(n.method=\"throw\",n.arg=new TypeError(\"iterator result is not an object\"),n.delegate=null,d)}function U(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function M(e){var t=e.completion||{};t.type=\"normal\",delete t.arg,e.completion=t}function A(e){this.tryEntries=[{tryLoc:\"root\"}],e.forEach(U,this),this.reset(!0)}function C(e){if(e){var n=e[a];if(n)return n.call(e);if(\"function\"==typeof e.next)return e;if(!isNaN(e.length)){var i=-1,o=function n(){for(;++i-1)return n.splice(r,1),this._listenerMap.set(e,n),!0}return!1}},{key:\"unbind\",value:function(){this._listenerMap.clear()}},{key:\"emit\",value:function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r0&&void 0!==arguments[0]?arguments[0]:{};n(this,e),this.type=t.type,this.mode=t.mode,this.minValue=t.minValue,this.maxValue=t.maxValue,this.uncertainty=t.uncertainty,this.minPeriod=t.minPeriod,this.maxPeriod=t.maxPeriod,this.typicalPeriod=t.typicalPeriod,this.granularity=t.granularity},P=function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};n(this,e),this.number=t.number,this.name=t.name,this.unit=t.unit,this.id=t.id,this.mutalExclusionMask=t.mutalExclusionMask,this.measurementInfo=t.measurementInfo},T=function(e){function t(e){var r;return n(this,t),(r=u(this,o(t).call(this))).number=e.number,r.name=e.name,r.unit=e.unit,r.specs=e,r.enabled=!1,r.values=[],r.value=null,r}return a(t,R),i(t,[{key:\"clear\",value:function(){this.value=null,this.values=[]}},{key:\"setValue\",value:function(e,t){this.value=e,t&&this.values.push(this.value),this.emit(\"value-changed\",this)}},{key:\"setEnabled\",value:function(e){this.enabled!==e&&(this.enabled=e,this.emit(\"state-changed\",this))}}]),t}(),N=function(e){function r(e){var t;if(n(this,r),t=u(this,o(r).call(this)),\"undefined\"==typeof TextDecoder){var i=require(\"text-encoding\");C=i.TextDecoder}else C=TextDecoder;return t.device=e,t.sensors=[],t.opened=!1,t.rollingCounter=0,t.collecting=!1,t.measurementPeriod=10,t.response=null,t.remainingResponseLength=0,t.defaultSensorsMask=0,t.keepValues=!0,t.minMeasurementPeriod=10,t.serialNumber=\"\",t.orderCode=\"\",t.name=\"\",t}return a(r,R),i(r,[{key:\"getBatteryLevel\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this._getStatus();case 2:return t=e.sent,e.abrupt(\"return\",t.battery);case 4:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"getChargingState\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this._getStatus();case 2:return t=e.sent,e.abrupt(\"return\",t.chargingStatus);case 4:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"open\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t,n=arguments;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return t=n.length>0&&void 0!==n[0]&&n[0],e.prev=1,e.next=4,this._connect();case 4:return e.next=6,this._init();case 6:return e.next=8,this._getStatus();case 8:return e.next=10,this._getDeviceInfo();case 10:return e.next=12,this._getDefaultSensorsMask();case 12:return e.next=14,this._getAvailableSensors();case 14:this._onOpened(),t&&this.start(),e.next=21;break;case 18:e.prev=18,e.t0=e.catch(1),console.error(e.t0);case 21:case\"end\":return e.stop()}},e,this,[[1,18]])}));return function(){return e.apply(this,arguments)}}()},{key:\"close\",value:function(){var e=t(regeneratorRuntime.mark(function e(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this._stopMeasurements();case 2:return e.next=4,this._sendCommand(d.DISCONNECT);case 4:return e.abrupt(\"return\",this._disconnect());case 5:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"enableDefaultSensors\",value:function(){for(var e=1,t=0;t<32;++t){if((this.defaultSensorsMask&e)===e){var n=this.getSensor(t);n&&n.setEnabled(!0)}e<<=1}}},{key:\"start\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=this.sensors.filter(function(e){return e.enabled});0===t.length&&(this.enableDefaultSensors(),t=this.sensors.filter(function(e){return e.enabled})),t.forEach(function(e){return e.clear()}),e&&(this.measurementPeriod=e),this._startMeasurements()}},{key:\"stop\",value:function(){this._stopMeasurements()}},{key:\"getSensor\",value:function(e){return this.sensors.find(function(t){return t.number===e})}},{key:\"_connect\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t=this;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt(\"return\",this.device.setup({onClosed:function(){return t._onClosed()},onResponse:function(e){return t._handleResponse(e)}}));case 1:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"_disconnect\",value:function(){var e=t(regeneratorRuntime.mark(function e(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt(\"return\",this.device.close());case 1:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"_init\",value:function(){return this.collecting=!1,this.rollingCounter=255,this.writeQueue=[],this._sendCommand(d.INIT)}},{key:\"_handleResponse\",value:function(e){if(U(\"command notified: \".concat(A(e.buffer))),this.remainingResponseLegnth>0){if(this.remainingResponseLegnth-=e.buffer.byteLength,this.response=new DataView((t=this.response.buffer,n=e.buffer.slice(0),(r=new Uint8Array(t.byteLength+n.byteLength)).set(new Uint8Array(t),0),r.set(new Uint8Array(n),t.byteLength),r.buffer)),this.remainingResponseLegnth>0)return}else this.response=e;var t,n,r,i=this.response.getUint8(1);if(i>this.response.buffer.byteLength)this.remainingResponseLegnth=i-this.response.buffer.byteLength;else switch(U(\"handle command: \".concat(A(this.response.buffer))),this.response.getUint8(0)){case E:this._processMeasurements(this.response);break;default:var a=this.response.getUint8(4),o=this.response.getUint8(5),s=new DataView(this.response.buffer,6);this._resolveWriteCommand(a,o,s),this.remainingResponseLegnth=0,this.response=null}}},{key:\"_getSensorsWithMask\",value:function(e){for(var t=[],n=1,r=0;r<32;++r){if((e&n)===n){var i=this.getSensor(r);i&&(t.push(i),U(\"available: [\".concat(e,\"] \").concat(t[t.length-1].number)))}n<<=1}return t}},{key:\"_processMeasurements\",value:function(e){var t=[],n=!0,r=0,i=0,a=e.getUint8(4);switch(a){case m:t=this._getSensorsWithMask(e.getUint16(5,!0)),r=e.getUint8(7,!0),i=9;break;case v:t=this._getSensorsWithMask(e.getUint32(5,!0)),r=e.getUint8(9,!0),i=11;break;case g:case y:t[0]=this.getSensor(e.getUint8(6)),r=e.getUint8(7,!0),i=8;break;case w:case b:t[0]=this.getSensor(e.getUint8(6)),r=e.getUint8(7,!0),i=8,n=!1;break;case _:case k:case x:U(\"Purposely Ignoring packet type: \".concat(a));break;default:U(\"Unknown packet type: \".concat(a))}for(var o=0;o255?(U(\"Checksum failed!\"),0):n}},{key:\"_sendCommand\",value:function(e){var t=new Uint8Array(d.HEADER.byteLength+e.byteLength);return t.set(new Uint8Array(d.HEADER),0),t.set(new Uint8Array(e),d.HEADER.byteLength),t[1]=t.length,t[2]=this._decRollingCounter(),t[3]=this._calculateChecksum(t),this._queueWriteCommand(t,0,t.length)}},{key:\"_writeCommand\",value:function(){var e=t(regeneratorRuntime.mark(function e(t,n,r){var i;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(!(r>0)){e.next=12;break}return e.prev=1,r>20?(i=t.subarray(n,n+20),r-=20,n+=20):(i=t.subarray(n,n+r),r=0),e.next=5,this.device.writeCommand(i);case 5:e.next=10;break;case 7:e.prev=7,e.t0=e.catch(1),U(\"Write Failure: \".concat(e.t0));case 10:e.next=0;break;case 12:case\"end\":return e.stop()}},e,this,[[1,7]])}));return function(t,n,r){return e.apply(this,arguments)}}()},{key:\"_queueWriteCommand\",value:function(e,t,n){var r=this;U(\"command queued: \".concat(A(e)));var i=new Promise(function(t,n){r.writeQueue.push({command:e[4],rollingCounter:e[2],resolve:t,reject:n}),setTimeout(function(){r.writeQueue=r.writeQueue.filter(function(t){return t.command===e[4]&&t.rollingCounter!==e[2]}),n(new Error(\"write command timed out after 5s. Command: \".concat(e[4].toString(16),\" Rolling Counter: \").concat(e[2].toString(16))))},1e4)});return this._writeCommand(e,t,n),i}},{key:\"_getStatus\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t,n;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this._sendCommand(d.GET_STATUS);case 2:return t=e.sent,n={masterFirmwareVersion:\"\".concat(t.getUint8(2),\".\").concat(t.getUint8(3)),bleFirmwareVersion:\"\".concat(t.getUint8(6),\".\").concat(t.getUint8(9)),battery:t.getUint8(10),chargingStatus:\"\".concat(t.getUint8(11))},e.abrupt(\"return\",n);case 5:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"_getAvailableSensors\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t,n,r=this;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this._sendCommand(d.GET_SENSOR_IDS).then(function(e){r.availableSensors=e.getUint32(0,!0),U(\"Get Available Sensors Returned \".concat(r.availableSensors))});case 2:t=1,n=0;case 4:if(!(n<31)){e.next=12;break}if((this.availableSensors&t)!==t){e.next=8;break}return e.next=8,this._getSensorInfo(n);case 8:t<<=1;case 9:++n,e.next=4;break;case 12:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"_getDefaultSensorsMask\",value:function(){var e=this;return this._sendCommand(d.GET_DEFAULT_SENSORS_MASK).then(function(t){e.defaultSensorsMask=t.getUint32(0,!0),U(\"Default Sensors:\"),M(e)})}},{key:\"_getDeviceInfo\",value:function(){var e=this;return this._sendCommand(d.GET_INFO).then(function(t){var n=new C(\"utf-8\");e.orderCode=n.decode(new Uint8Array(t.buffer,6,16).filter(S)),e.serialNumber=n.decode(new Uint8Array(t.buffer,22,16).filter(S)),e.name=n.decode(new Uint8Array(t.buffer,38,32).filter(S)),U(\"Device Info:\"),M(e)})}},{key:\"_getSensorInfo\",value:function(){var e=t(regeneratorRuntime.mark(function e(t){var n,r=this;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return(n=new Uint8Array(d.GET_SENSOR_INFO))[1]=t,e.abrupt(\"return\",this._sendCommand(n).then(function(e){var t=e.getUint32(2,!0);if(t>0){var n=new C(\"utf-8\"),i=new L({type:e.getUint8(6),mode:e.getUint8(7),minValue:e.getFloat64(108,!0),maxValue:e.getFloat64(116,!0),uncertainty:e.getFloat64(100,!0),minPeriod:e.getUint32(124,!0)/1e3,maxPeriod:((e.getUint32(132,!0)<<32)+e.getUint32(128,!0))/1e3,typicalPeriod:e.getUint32(136,!0)/1e3,granularity:e.getUint32(140,!0)/1e3}),a=new P({number:e.getUint8(0),name:n.decode(new Uint8Array(e.buffer,14,60).filter(S)),unit:n.decode(new Uint8Array(e.buffer,74,32).filter(S)),mutalExclusiveMask:e.getUint32(144,!0),measurementInfo:i,sensorId:t}),o=new T(a);U(\"Get Sensor Info Returned\"),M(o),r.sensors.push(o),o.on(\"state-changed\",function(){U(\"Sensor Restart: \".concat(o.number)),o.enabled&&(r.measurementPeriod=o.specs.measurementInfo.typicalPeriod,r.sensors.forEach(function(e){if(o.number!==e.number&&e.enabled){var t=1<r.measurementPeriod&&(r.measurementPeriod=e.specs.measurementInfo.typicalPeriod)}})),r._restartMeasurements()})}}));case 3:case\"end\":return e.stop()}},e,this)}));return function(t){return e.apply(this,arguments)}}()},{key:\"_restartMeasurements\",value:function(){var e=t(regeneratorRuntime.mark(function e(){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t=this.collecting,!this.collecting){e.next=10;break}return e.prev=2,e.next=5,this._stopMeasurements();case 5:e.next=10;break;case 7:e.prev=7,e.t0=e.catch(2),console.error(e.t0);case 10:if(this.collecting||!t){e.next=19;break}return e.prev=11,e.next=14,this._startMeasurements();case 14:e.next=19;break;case 16:e.prev=16,e.t1=e.catch(11),console.error(e.t1);case 19:case\"end\":return e.stop()}},e,this,[[2,7],[11,16]])}));return function(){return e.apply(this,arguments)}}()},{key:\"_setMeasurementPeriod\",value:function(e){var t=new Uint8Array(d.SET_MEASUREMENT_PERIOD),n=1e3*this.minMeasurementPeriod;return e>0&255,t[4]=e>>8&255,t[5]=e>>16&255,t[6]=e>>24&255,this._sendCommand(t)}},{key:\"_getEnabledChannelMask\",value:function(){var e=0;return this.sensors.filter(function(e){return e.enabled}).forEach(function(t){e+=1<>0&255,n[4]=t>>8&255,n[5]=t>>16&255,n[6]=t>>24&255,e._sendCommand(n).then(function(t){0===t.getUint8(0)&&(e.collecting=!0,e.emit(\"measurements-started\"))})})}},{key:\"_stopMeasurements\",value:function(){var e=this;return this._sendCommand(d.STOP_MEASUREMENTS).then(function(t){0===t.getUint8(0)&&(e.collecting=!1,e.emit(\"measurements-stopped\"))})}}]),r}(),O=function(){function e(t){n(this,e),this.webBluetoothNativeDevice=t,this.deviceCommand=null,this.deviceResponse=null}return i(e,[{key:\"writeCommand\",value:function(){var e=t(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt(\"return\",this.deviceCommand.writeValue(t));case 1:case\"end\":return e.stop()}},e,this)}));return function(t){return e.apply(this,arguments)}}()},{key:\"setup\",value:function(){var e=t(regeneratorRuntime.mark(function e(t){var n,r,i,a,o=this;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return n=t.onClosed,r=t.onResponse,this.webBluetoothNativeDevice.addEventListener(\"gattserverdisconnected\",n),e.prev=2,e.next=5,this.webBluetoothNativeDevice.gatt.connect();case 5:return i=e.sent,e.next=8,i.getPrimaryService(\"d91714ef-28b9-4f91-ba16-f0d9a604f112\");case 8:return a=e.sent,e.next=11,a.getCharacteristics();case 11:e.sent.forEach(function(e){switch(e.uuid){case\"f4bf14a6-c7d5-4b6d-8aa8-df1a7c83adcb\":o.deviceCommand=e;break;case\"b41e6675-a329-40e0-aa01-44d2f444babe\":o.deviceResponse=e,o.deviceResponse.addEventListener(\"characteristicvaluechanged\",function(e){var t=e.target.value;r(t)}),o.deviceResponse.startNotifications();break;default:U(\"No case found for \".concat(e.uuid))}}),e.next=18;break;case 15:e.prev=15,e.t0=e.catch(2),console.error(e.t0);case 18:if(this.deviceCommand&&this.deviceResponse){e.next=20;break}throw new Error(\"Expected command and response characteristics not found.\");case 20:case\"end\":return e.stop()}},e,this,[[2,15]])}));return function(t){return e.apply(this,arguments)}}()},{key:\"close\",value:function(){var e=t(regeneratorRuntime.mark(function e(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt(\"return\",this.webBluetoothNativeDevice.gatt.disconnect());case 1:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()},{key:\"godirectAdapter\",get:function(){return!0}}]),e}(),D={createDevice:function(){var e=t(regeneratorRuntime.mark(function e(t){var n,r,i,a,o,s,u,c=arguments;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(n=c.length>1&&void 0!==c[1]?c[1]:{},r=n.open,i=void 0===r||r,a=n.startMeasurements,o=void 0===a||a,(s=t).godirectAdapter||(s=new O(t)),u=new N(s),!i){e.next=14;break}return e.prev=5,e.next=8,u.open(o);case 8:e.next=14;break;case 10:throw e.prev=10,e.t0=e.catch(5),console.error(e.t0),e.t0;case 14:return e.abrupt(\"return\",u);case 15:case\"end\":return e.stop()}},e,this,[[5,10]])}));return function(t){return e.apply(this,arguments)}}(),selectDevice:function(){var e=t(regeneratorRuntime.mark(function e(){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(navigator.bluetooth){e.next=2;break}return e.abrupt(\"return\",Promise.reject(new Error(\"No Web Bluetooth support.\")));case 2:return e.next=4,navigator.bluetooth.requestDevice({filters:[{namePrefix:\"GDX\"}],optionalServices:[\"d91714ef-28b9-4f91-ba16-f0d9a604f112\"]});case 4:return t=e.sent,e.abrupt(\"return\",D.createDevice(t));case 6:case\"end\":return e.stop()}},e,this)}));return function(){return e.apply(this,arguments)}}()};return D});\n","(function (w) {\n \"use strict\";\n\n function findBest(atobNative) {\n // normal window\n if ('function' === typeof atobNative) { return atobNative; }\n\n\n // browserify (web worker)\n if ('function' === typeof Buffer) {\n return function atobBrowserify(a) {\n //!! Deliberately using an API that's deprecated in node.js because\n //!! this file is for browsers and we expect them to cope with it.\n //!! Discussion: github.com/node-browser-compat/atob/pull/9\n return new Buffer(a, 'base64').toString('binary');\n };\n }\n\n // ios web worker with base64js\n if ('object' === typeof w.base64js) {\n // bufferToBinaryString\n // https://git.coolaj86.com/coolaj86/unibabel.js/blob/master/index.js#L50\n return function atobWebWorker_iOS(a) {\n var buf = w.base64js.b64ToByteArray(a);\n return Array.prototype.map.call(buf, function (ch) {\n return String.fromCharCode(ch);\n }).join('');\n };\n }\n\n\t\treturn function () {\n\t\t\t// ios web worker without base64js\n\t\t\tthrow new Error(\"You're probably in an old browser or an iOS webworker.\" +\n\t\t\t\t\" It might help to include beatgammit's base64-js.\");\n };\n }\n\n var atobBest = findBest(w.atob);\n w.atob = atobBest;\n\n if ((typeof module === 'object') && module && module.exports) {\n module.exports = atobBest;\n }\n}(window));\n","(function () {\n \"use strict\";\n\n function btoa(str) {\n var buffer;\n\n if (str instanceof Buffer) {\n buffer = str;\n } else {\n buffer = Buffer.from(str.toString(), 'binary');\n }\n\n return buffer.toString('base64');\n }\n\n module.exports = btoa;\n}());\n","/* canvas-toBlob.js\n * A canvas.toBlob() implementation.\n * 2016-05-26\n * \n * By Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr\n * License: MIT\n * See https://github.com/eligrey/canvas-toBlob.js/blob/master/LICENSE.md\n */\n\n/*global self */\n/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,\n plusplus: true */\n\n/*! @source http://purl.eligrey.com/github/canvas-toBlob.js/blob/master/canvas-toBlob.js */\n\n(function(view) {\n\"use strict\";\nvar\n\t Uint8Array = view.Uint8Array\n\t, HTMLCanvasElement = view.HTMLCanvasElement\n\t, canvas_proto = HTMLCanvasElement && HTMLCanvasElement.prototype\n\t, is_base64_regex = /\\s*;\\s*base64\\s*(?:;|$)/i\n\t, to_data_url = \"toDataURL\"\n\t, base64_ranks\n\t, decode_base64 = function(base64) {\n\t\tvar\n\t\t\t len = base64.length\n\t\t\t, buffer = new Uint8Array(len / 4 * 3 | 0)\n\t\t\t, i = 0\n\t\t\t, outptr = 0\n\t\t\t, last = [0, 0]\n\t\t\t, state = 0\n\t\t\t, save = 0\n\t\t\t, rank\n\t\t\t, code\n\t\t\t, undef\n\t\t;\n\t\twhile (len--) {\n\t\t\tcode = base64.charCodeAt(i++);\n\t\t\trank = base64_ranks[code-43];\n\t\t\tif (rank !== 255 && rank !== undef) {\n\t\t\t\tlast[1] = last[0];\n\t\t\t\tlast[0] = code;\n\t\t\t\tsave = (save << 6) | rank;\n\t\t\t\tstate++;\n\t\t\t\tif (state === 4) {\n\t\t\t\t\tbuffer[outptr++] = save >>> 16;\n\t\t\t\t\tif (last[1] !== 61 /* padding character */) {\n\t\t\t\t\t\tbuffer[outptr++] = save >>> 8;\n\t\t\t\t\t}\n\t\t\t\t\tif (last[0] !== 61 /* padding character */) {\n\t\t\t\t\t\tbuffer[outptr++] = save;\n\t\t\t\t\t}\n\t\t\t\t\tstate = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// 2/3 chance there's going to be some null bytes at the end, but that\n\t\t// doesn't really matter with most image formats.\n\t\t// If it somehow matters for you, truncate the buffer up outptr.\n\t\treturn buffer;\n\t}\n;\nif (Uint8Array) {\n\tbase64_ranks = new Uint8Array([\n\t\t 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1\n\t\t, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n\t\t, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25\n\t\t, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35\n\t\t, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51\n\t]);\n}\nif (HTMLCanvasElement && (!canvas_proto.toBlob || !canvas_proto.toBlobHD)) {\n\tif (!canvas_proto.toBlob)\n\tcanvas_proto.toBlob = function(callback, type /*, ...args*/) {\n\t\t if (!type) {\n\t\t\ttype = \"image/png\";\n\t\t} if (this.mozGetAsFile) {\n\t\t\tcallback(this.mozGetAsFile(\"canvas\", type));\n\t\t\treturn;\n\t\t} if (this.msToBlob && /^\\s*image\\/png\\s*(?:$|;)/i.test(type)) {\n\t\t\tcallback(this.msToBlob());\n\t\t\treturn;\n\t\t}\n\n\t\tvar\n\t\t\t args = Array.prototype.slice.call(arguments, 1)\n\t\t\t, dataURI = this[to_data_url].apply(this, args)\n\t\t\t, header_end = dataURI.indexOf(\",\")\n\t\t\t, data = dataURI.substring(header_end + 1)\n\t\t\t, is_base64 = is_base64_regex.test(dataURI.substring(0, header_end))\n\t\t\t, blob\n\t\t;\n\t\tif (Blob.fake) {\n\t\t\t// no reason to decode a data: URI that's just going to become a data URI again\n\t\t\tblob = new Blob\n\t\t\tif (is_base64) {\n\t\t\t\tblob.encoding = \"base64\";\n\t\t\t} else {\n\t\t\t\tblob.encoding = \"URI\";\n\t\t\t}\n\t\t\tblob.data = data;\n\t\t\tblob.size = data.length;\n\t\t} else if (Uint8Array) {\n\t\t\tif (is_base64) {\n\t\t\t\tblob = new Blob([decode_base64(data)], {type: type});\n\t\t\t} else {\n\t\t\t\tblob = new Blob([decodeURIComponent(data)], {type: type});\n\t\t\t}\n\t\t}\n\t\tcallback(blob);\n\t};\n\n\tif (!canvas_proto.toBlobHD && canvas_proto.toDataURLHD) {\n\t\tcanvas_proto.toBlobHD = function() {\n\t\t\tto_data_url = \"toDataURLHD\";\n\t\t\tvar blob = this.toBlob();\n\t\t\tto_data_url = \"toDataURL\";\n\t\t\treturn blob;\n\t\t}\n\t} else {\n\t\tcanvas_proto.toBlobHD = canvas_proto.toBlob;\n\t}\n}\n}(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || this.content || this));\n","require('../modules/web.immediate');\nmodule.exports = require('../modules/_core').setImmediate;","module.exports = function(it){\n if(typeof it != 'function')throw TypeError(it + ' is not a function!');\n return it;\n};","var isObject = require('./_is-object');\nmodule.exports = function(it){\n if(!isObject(it))throw TypeError(it + ' is not an object!');\n return it;\n};","var toString = {}.toString;\n\nmodule.exports = function(it){\n return toString.call(it).slice(8, -1);\n};","var core = module.exports = {version: '2.3.0'};\nif(typeof __e == 'number')__e = core; // eslint-disable-line no-undef","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function(fn, that, length){\n aFunction(fn);\n if(that === undefined)return fn;\n switch(length){\n case 1: return function(a){\n return fn.call(that, a);\n };\n case 2: return function(a, b){\n return fn.call(that, a, b);\n };\n case 3: return function(a, b, c){\n return fn.call(that, a, b, c);\n };\n }\n return function(/* ...args */){\n return fn.apply(that, arguments);\n };\n};","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function(){\n return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;\n});","var isObject = require('./_is-object')\n , document = require('./_global').document\n // in old IE typeof document.createElement is 'object'\n , is = isObject(document) && isObject(document.createElement);\nmodule.exports = function(it){\n return is ? document.createElement(it) : {};\n};","var global = require('./_global')\n , core = require('./_core')\n , ctx = require('./_ctx')\n , hide = require('./_hide')\n , PROTOTYPE = 'prototype';\n\nvar $export = function(type, name, source){\n var IS_FORCED = type & $export.F\n , IS_GLOBAL = type & $export.G\n , IS_STATIC = type & $export.S\n , IS_PROTO = type & $export.P\n , IS_BIND = type & $export.B\n , IS_WRAP = type & $export.W\n , exports = IS_GLOBAL ? core : core[name] || (core[name] = {})\n , expProto = exports[PROTOTYPE]\n , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]\n , key, own, out;\n if(IS_GLOBAL)source = name;\n for(key in source){\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n if(own && key in exports)continue;\n // export native or passed\n out = own ? target[key] : source[key];\n // prevent global pollution for namespaces\n exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]\n // bind timers to global for call from export context\n : IS_BIND && own ? ctx(out, global)\n // wrap global constructors for prevent change them in library\n : IS_WRAP && target[key] == out ? (function(C){\n var F = function(a, b, c){\n if(this instanceof C){\n switch(arguments.length){\n case 0: return new C;\n case 1: return new C(a);\n case 2: return new C(a, b);\n } return new C(a, b, c);\n } return C.apply(this, arguments);\n };\n F[PROTOTYPE] = C[PROTOTYPE];\n return F;\n // make static versions for prototype methods\n })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%\n if(IS_PROTO){\n (exports.virtual || (exports.virtual = {}))[key] = out;\n // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%\n if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);\n }\n }\n};\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library` \nmodule.exports = $export;","module.exports = function(exec){\n try {\n return !!exec();\n } catch(e){\n return true;\n }\n};","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();\nif(typeof __g == 'number')__g = global; // eslint-disable-line no-undef","var dP = require('./_object-dp')\n , createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function(object, key, value){\n return dP.f(object, key, createDesc(1, value));\n} : function(object, key, value){\n object[key] = value;\n return object;\n};","module.exports = require('./_global').document && document.documentElement;","module.exports = !require('./_descriptors') && !require('./_fails')(function(){\r\n return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;\r\n});","// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function(fn, args, that){\n var un = that === undefined;\n switch(args.length){\n case 0: return un ? fn()\n : fn.call(that);\n case 1: return un ? fn(args[0])\n : fn.call(that, args[0]);\n case 2: return un ? fn(args[0], args[1])\n : fn.call(that, args[0], args[1]);\n case 3: return un ? fn(args[0], args[1], args[2])\n : fn.call(that, args[0], args[1], args[2]);\n case 4: return un ? fn(args[0], args[1], args[2], args[3])\n : fn.call(that, args[0], args[1], args[2], args[3]);\n } return fn.apply(that, args);\n};","module.exports = function(it){\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};","var anObject = require('./_an-object')\n , IE8_DOM_DEFINE = require('./_ie8-dom-define')\n , toPrimitive = require('./_to-primitive')\n , dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if(IE8_DOM_DEFINE)try {\n return dP(O, P, Attributes);\n } catch(e){ /* empty */ }\n if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');\n if('value' in Attributes)O[P] = Attributes.value;\n return O;\n};","module.exports = function(bitmap, value){\n return {\n enumerable : !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable : !(bitmap & 4),\n value : value\n };\n};","var ctx = require('./_ctx')\n , invoke = require('./_invoke')\n , html = require('./_html')\n , cel = require('./_dom-create')\n , global = require('./_global')\n , process = global.process\n , setTask = global.setImmediate\n , clearTask = global.clearImmediate\n , MessageChannel = global.MessageChannel\n , counter = 0\n , queue = {}\n , ONREADYSTATECHANGE = 'onreadystatechange'\n , defer, channel, port;\nvar run = function(){\n var id = +this;\n if(queue.hasOwnProperty(id)){\n var fn = queue[id];\n delete queue[id];\n fn();\n }\n};\nvar listener = function(event){\n run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif(!setTask || !clearTask){\n setTask = function setImmediate(fn){\n var args = [], i = 1;\n while(arguments.length > i)args.push(arguments[i++]);\n queue[++counter] = function(){\n invoke(typeof fn == 'function' ? fn : Function(fn), args);\n };\n defer(counter);\n return counter;\n };\n clearTask = function clearImmediate(id){\n delete queue[id];\n };\n // Node.js 0.8-\n if(require('./_cof')(process) == 'process'){\n defer = function(id){\n process.nextTick(ctx(run, id, 1));\n };\n // Browsers with MessageChannel, includes WebWorkers\n } else if(MessageChannel){\n channel = new MessageChannel;\n port = channel.port2;\n channel.port1.onmessage = listener;\n defer = ctx(port.postMessage, port, 1);\n // Browsers with postMessage, skip WebWorkers\n // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){\n defer = function(id){\n global.postMessage(id + '', '*');\n };\n global.addEventListener('message', listener, false);\n // IE8-\n } else if(ONREADYSTATECHANGE in cel('script')){\n defer = function(id){\n html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){\n html.removeChild(this);\n run.call(id);\n };\n };\n // Rest old browsers\n } else {\n defer = function(id){\n setTimeout(ctx(run, id, 1), 0);\n };\n }\n}\nmodule.exports = {\n set: setTask,\n clear: clearTask\n};","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function(it, S){\n if(!isObject(it))return it;\n var fn, val;\n if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;\n if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};","var $export = require('./_export')\n , $task = require('./_task');\n$export($export.G + $export.B, {\n setImmediate: $task.set,\n clearImmediate: $task.clear\n});","// Store markers outside of the function scope,\n// not to recreate them on every call\nvar entities = {\n 'amp': '&',\n 'apos': '\\'',\n 'lt': '<',\n 'gt': '>',\n 'quot': '\"',\n 'nbsp': '\\xa0'\n};\nvar entityPattern = /&([a-z]+);/ig;\n\nmodule.exports = function decodeHTMLEntities(text) {\n // A single replace pass with a static RegExp is faster than a loop\n return text.replace(entityPattern, function(match, entity) {\n entity = entity.toLowerCase();\n if (entities.hasOwnProperty(entity)) {\n return entities[entity];\n }\n // return original string if there is no matching entity (no replace)\n return match;\n });\n};\n","/*\n Module dependencies\n*/\nvar ElementType = require('domelementtype');\nvar entities = require('entities');\n\n/* mixed-case SVG and MathML tags & attributes\n recognized by the HTML parser, see\n https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign\n*/\nvar foreignNames = require('./foreignNames.json');\nforeignNames.elementNames.__proto__ = null; /* use as a simple dictionary */\nforeignNames.attributeNames.__proto__ = null;\n\nvar unencodedElements = {\n __proto__: null,\n style: true,\n script: true,\n xmp: true,\n iframe: true,\n noembed: true,\n noframes: true,\n plaintext: true,\n noscript: true\n};\n\n/*\n Format attributes\n*/\nfunction formatAttrs(attributes, opts) {\n if (!attributes) return;\n\n var output = '';\n var value;\n\n // Loop through the attributes\n for (var key in attributes) {\n value = attributes[key];\n if (output) {\n output += ' ';\n }\n\n if (opts.xmlMode === 'foreign') {\n /* fix up mixed-case attribute names */\n key = foreignNames.attributeNames[key] || key;\n }\n output += key;\n if ((value !== null && value !== '') || opts.xmlMode) {\n output +=\n '=\"' +\n (opts.decodeEntities\n ? entities.encodeXML(value)\n : value.replace(/\\\"/g, '"')) +\n '\"';\n }\n }\n\n return output;\n}\n\n/*\n Self-enclosing tags (stolen from node-htmlparser)\n*/\nvar singleTag = {\n __proto__: null,\n area: true,\n base: true,\n basefont: true,\n br: true,\n col: true,\n command: true,\n embed: true,\n frame: true,\n hr: true,\n img: true,\n input: true,\n isindex: true,\n keygen: true,\n link: true,\n meta: true,\n param: true,\n source: true,\n track: true,\n wbr: true\n};\n\nvar render = (module.exports = function(dom, opts) {\n if (!Array.isArray(dom) && !dom.cheerio) dom = [dom];\n opts = opts || {};\n\n var output = '';\n\n for (var i = 0; i < dom.length; i++) {\n var elem = dom[i];\n\n if (elem.type === 'root') output += render(elem.children, opts);\n else if (ElementType.isTag(elem)) output += renderTag(elem, opts);\n else if (elem.type === ElementType.Directive)\n output += renderDirective(elem);\n else if (elem.type === ElementType.Comment) output += renderComment(elem);\n else if (elem.type === ElementType.CDATA) output += renderCdata(elem);\n else output += renderText(elem, opts);\n }\n\n return output;\n});\n\nvar foreignModeIntegrationPoints = [\n 'mi',\n 'mo',\n 'mn',\n 'ms',\n 'mtext',\n 'annotation-xml',\n 'foreignObject',\n 'desc',\n 'title'\n];\n\nfunction renderTag(elem, opts) {\n // Handle SVG / MathML in HTML\n if (opts.xmlMode === 'foreign') {\n /* fix up mixed-case element names */\n elem.name = foreignNames.elementNames[elem.name] || elem.name;\n /* exit foreign mode at integration points */\n if (\n elem.parent &&\n foreignModeIntegrationPoints.indexOf(elem.parent.name) >= 0\n )\n opts = Object.assign({}, opts, { xmlMode: false });\n }\n if (!opts.xmlMode && ['svg', 'math'].indexOf(elem.name) >= 0) {\n opts = Object.assign({}, opts, { xmlMode: 'foreign' });\n }\n\n var tag = '<' + elem.name;\n var attribs = formatAttrs(elem.attribs, opts);\n\n if (attribs) {\n tag += ' ' + attribs;\n }\n\n if (opts.xmlMode && (!elem.children || elem.children.length === 0)) {\n tag += '/>';\n } else {\n tag += '>';\n if (elem.children) {\n tag += render(elem.children, opts);\n }\n\n if (!singleTag[elem.name] || opts.xmlMode) {\n tag += '';\n }\n }\n\n return tag;\n}\n\nfunction renderDirective(elem) {\n return '<' + elem.data + '>';\n}\n\nfunction renderText(elem, opts) {\n var data = elem.data || '';\n\n // if entities weren't decoded, no need to encode them back\n if (\n opts.decodeEntities &&\n !(elem.parent && elem.parent.name in unencodedElements)\n ) {\n data = entities.encodeXML(data);\n }\n\n return data;\n}\n\nfunction renderCdata(elem) {\n return '';\n}\n\nfunction renderComment(elem) {\n return '';\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * Tests whether an element is a tag or not.\n *\n * @param elem Element to test\n */\nfunction isTag(elem) {\n return (elem.type === \"tag\" /* Tag */ ||\n elem.type === \"script\" /* Script */ ||\n elem.type === \"style\" /* Style */);\n}\nexports.isTag = isTag;\n// Exports for backwards compatibility\nexports.Text = \"text\" /* Text */; //Text\nexports.Directive = \"directive\" /* Directive */; //\nexports.Comment = \"comment\" /* Comment */; //\nexports.Script = \"script\" /* Script */; //\n //\n // Has one line before it which is invalid according to GLSL ES 3.00\n //\n\n var lineOffset = 0;\n\n if (spaceRE.test(shaderSource)) {\n lineOffset = 1;\n shaderSource = shaderSource.replace(spaceRE, '');\n } // Load the shader source\n\n\n gl.shaderSource(shader, shaderSource); // Compile the shader\n\n gl.compileShader(shader); // Check the compile status\n\n var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n\n if (!compiled) {\n // Something went wrong during compilation; get the error\n var lastError = gl.getShaderInfoLog(shader);\n errFn(addLineNumbers(shaderSource, lineOffset) + \"\\n*** Error compiling shader: \" + lastError);\n gl.deleteShader(shader);\n return null;\n }\n\n return shader;\n}\n/**\n * @typedef {Object} ProgramOptions\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.} [attribLocations] a attribute name to location map\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @memberOf module:twgl\n */\n\n/**\n * Gets the program options based on all these optional arguments\n * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments pased on\n */\n\n\nfunction getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) {\n var transformFeedbackVaryings;\n\n if (typeof opt_locations === 'function') {\n opt_errorCallback = opt_locations;\n opt_locations = undefined;\n }\n\n if (typeof opt_attribs === 'function') {\n opt_errorCallback = opt_attribs;\n opt_attribs = undefined;\n } else if (opt_attribs && !Array.isArray(opt_attribs)) {\n // If we have an errorCallback we can just return this object\n // Otherwise we need to construct one with default errorCallback\n if (opt_attribs.errorCallback) {\n return opt_attribs;\n }\n\n var opt = opt_attribs;\n opt_errorCallback = opt.errorCallback;\n opt_attribs = opt.attribLocations;\n transformFeedbackVaryings = opt.transformFeedbackVaryings;\n }\n\n var options = {\n errorCallback: opt_errorCallback || error,\n transformFeedbackVaryings: transformFeedbackVaryings\n };\n\n if (opt_attribs) {\n var attribLocations = {};\n\n if (Array.isArray(opt_attribs)) {\n opt_attribs.forEach(function (attrib, ndx) {\n attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx;\n });\n } else {\n attribLocations = opt_attribs;\n }\n\n options.attribLocations = attribLocations;\n }\n\n return options;\n}\n\nvar defaultShaderType = [\"VERTEX_SHADER\", \"FRAGMENT_SHADER\"];\n\nfunction getShaderTypeFromScriptType(scriptType) {\n if (scriptType.indexOf(\"frag\") >= 0) {\n return gl.FRAGMENT_SHADER;\n } else if (scriptType.indexOf(\"vert\") >= 0) {\n return gl.VERTEX_SHADER;\n }\n\n return undefined;\n}\n\nfunction deleteShaders(gl, shaders) {\n shaders.forEach(function (shader) {\n gl.deleteShader(shader);\n });\n}\n/**\n * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the\n * program and calls useProgram.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgram(gl, [vs, fs], options);\n * twgl.createProgram(gl, [vs, fs], opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error.\n * @memberOf module:twgl/programs\n */\n\n\nfunction createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback) {\n var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n var realShaders = [];\n var newShaders = [];\n\n for (var ndx = 0; ndx < shaders.length; ++ndx) {\n var shader = shaders[ndx];\n\n if (typeof shader === 'string') {\n var elem = getElementById(shader);\n var src = elem ? elem.text : shader;\n var type = gl[defaultShaderType[ndx]];\n\n if (elem && elem.type) {\n type = getShaderTypeFromScriptType(elem.type) || type;\n }\n\n shader = loadShader(gl, src, type, progOptions.errorCallback);\n newShaders.push(shader);\n }\n\n if (helper.isShader(gl, shader)) {\n realShaders.push(shader);\n }\n }\n\n if (realShaders.length !== shaders.length) {\n progOptions.errorCallback(\"not enough shaders for program\");\n deleteShaders(gl, newShaders);\n return null;\n }\n\n var program = gl.createProgram();\n realShaders.forEach(function (shader) {\n gl.attachShader(program, shader);\n });\n\n if (progOptions.attribLocations) {\n Object.keys(progOptions.attribLocations).forEach(function (attrib) {\n gl.bindAttribLocation(program, progOptions.attribLocations[attrib], attrib);\n });\n }\n\n var varyings = progOptions.transformFeedbackVaryings;\n\n if (varyings) {\n if (varyings.attribs) {\n varyings = varyings.attribs;\n }\n\n if (!Array.isArray(varyings)) {\n varyings = Object.keys(varyings);\n }\n\n gl.transformFeedbackVaryings(program, varyings, progOptions.transformFeedbackMode || gl.SEPARATE_ATTRIBS);\n }\n\n gl.linkProgram(program); // Check the link status\n\n var linked = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (!linked) {\n // something went wrong with the link\n var lastError = gl.getProgramInfoLog(program);\n progOptions.errorCallback(\"Error in program linking:\" + lastError);\n gl.deleteProgram(program);\n deleteShaders(gl, newShaders);\n return null;\n }\n\n return program;\n}\n/**\n * Loads a shader from a script tag.\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {string} scriptId The id of the script tag.\n * @param {number} [opt_shaderType] The type of shader. If not passed in it will\n * be derived from the type of the script tag.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors.\n * @return {WebGLShader?} The created shader or null if error.\n */\n\n\nfunction createShaderFromScript(gl, scriptId, opt_shaderType, opt_errorCallback) {\n var shaderSource = \"\";\n var shaderScript = getElementById(scriptId);\n\n if (!shaderScript) {\n throw \"*** Error: unknown script element\" + scriptId;\n }\n\n shaderSource = shaderScript.text;\n var shaderType = opt_shaderType || getShaderTypeFromScriptType(shaderScript.type);\n\n if (!shaderType) {\n throw \"*** Error: unknown shader type\";\n }\n\n return loadShader(gl, shaderSource, shaderType, opt_errorCallback);\n}\n/**\n * Creates a program from 2 script tags.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_options);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderScriptIds Array of ids of the script\n * tags for the shaders. The first is assumed to be the\n * vertex shader, the second the fragment shader.\n * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram} The created program.\n * @memberOf module:twgl/programs\n */\n\n\nfunction createProgramFromScripts(gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) {\n var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n var shaders = [];\n\n for (var ii = 0; ii < shaderScriptIds.length; ++ii) {\n var shader = createShaderFromScript(gl, shaderScriptIds[ii], gl[defaultShaderType[ii]], progOptions.errorCallback);\n\n if (!shader) {\n return null;\n }\n\n shaders.push(shader);\n }\n\n return createProgram(gl, shaders, progOptions);\n}\n/**\n * Creates a program from 2 sources.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromSource(gl, [vs, fs], opt_options);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram} The created program.\n * @memberOf module:twgl/programs\n */\n\n\nfunction createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n var shaders = [];\n\n for (var ii = 0; ii < shaderSources.length; ++ii) {\n var shader = loadShader(gl, shaderSources[ii], gl[defaultShaderType[ii]], progOptions.errorCallback);\n\n if (!shader) {\n return null;\n }\n\n shaders.push(shader);\n }\n\n return createProgram(gl, shaders, progOptions);\n}\n/**\n * Returns true if attribute/uniform is a reserved/built in\n *\n * It makes no sense to me why GL returns these because it's\n * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation`\n * with names that start with `gl_` (and `webgl_` in WebGL)\n *\n * I can only assume they are there because they might count\n * when computing the number of uniforms/attributes used when you want to\n * know if you are near the limit. That doesn't really make sense\n * to me but the fact that these get returned are in the spec.\n *\n * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or\n * `gl.getActiveAttrib`.\n * @return {bool} true if it's reserved\n */\n\n\nfunction isBuiltIn(info) {\n var name = info.name;\n return name.startsWith(\"gl_\") || name.startsWith(\"webgl_\");\n}\n/**\n * Creates setter functions for all uniforms of a shader\n * program.\n *\n * @see {@link module:twgl.setUniforms}\n *\n * @param {WebGLProgram} program the program to create setters for.\n * @returns {Object.} an object with a setter by name for each uniform\n * @memberOf module:twgl/programs\n */\n\n\nfunction createUniformSetters(gl, program) {\n var textureUnit = 0;\n /**\n * Creates a setter for a uniform of the given program with it's\n * location embedded in the setter.\n * @param {WebGLProgram} program\n * @param {WebGLUniformInfo} uniformInfo\n * @returns {function} the created setter.\n */\n\n function createUniformSetter(program, uniformInfo) {\n var location = gl.getUniformLocation(program, uniformInfo.name);\n var isArray = uniformInfo.size > 1 && uniformInfo.name.substr(-3) === \"[0]\";\n var type = uniformInfo.type;\n var typeInfo = typeMap[type];\n\n if (!typeInfo) {\n throw \"unknown type: 0x\" + type.toString(16); // we should never get here.\n }\n\n var setter;\n\n if (typeInfo.bindPoint) {\n // it's a sampler\n var unit = textureUnit;\n textureUnit += uniformInfo.size;\n\n if (isArray) {\n setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size);\n } else {\n setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size);\n }\n } else {\n if (typeInfo.arraySetter && isArray) {\n setter = typeInfo.arraySetter(gl, location);\n } else {\n setter = typeInfo.setter(gl, location);\n }\n }\n\n setter.location = location;\n return setter;\n }\n\n var uniformSetters = {};\n var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n\n for (var ii = 0; ii < numUniforms; ++ii) {\n var uniformInfo = gl.getActiveUniform(program, ii);\n\n if (isBuiltIn(uniformInfo)) {\n continue;\n }\n\n var name = uniformInfo.name; // remove the array suffix.\n\n if (name.substr(-3) === \"[0]\") {\n name = name.substr(0, name.length - 3);\n }\n\n var setter = createUniformSetter(program, uniformInfo);\n uniformSetters[name] = setter;\n }\n\n return uniformSetters;\n}\n/**\n * @typedef {Object} TransformFeedbackInfo\n * @property {number} index index of transform feedback\n * @property {number} type GL type\n * @property {number} size 1 - 4\n * @memberOf module:twgl\n */\n\n/**\n * Create TransformFeedbackInfo for passing to bind/unbindTransformFeedbackInfo.\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {Object}\n * @memberOf module:twgl\n */\n\n\nfunction createTransformFeedbackInfo(gl, program) {\n var info = {};\n var numVaryings = gl.getProgramParameter(program, gl.TRANSFORM_FEEDBACK_VARYINGS);\n\n for (var ii = 0; ii < numVaryings; ++ii) {\n var varying = gl.getTransformFeedbackVarying(program, ii);\n info[varying.name] = {\n index: ii,\n type: varying.type,\n size: varying.size\n };\n }\n\n return info;\n}\n/**\n * Binds buffers for transform feedback.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo.\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @memberOf module:twgl\n */\n\n\nfunction bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) {\n if (transformFeedbackInfo.transformFeedbackInfo) {\n transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo;\n }\n\n if (bufferInfo.attribs) {\n bufferInfo = bufferInfo.attribs;\n }\n\n for (var name in bufferInfo) {\n var varying = transformFeedbackInfo[name];\n\n if (varying) {\n var buf = bufferInfo[name];\n\n if (buf.offset) {\n gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size);\n } else {\n gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer);\n }\n }\n }\n}\n/**\n * Unbinds buffers afetr transform feedback.\n *\n * Buffers can not be bound to 2 bind points so if you try to bind a buffer used\n * in a transform feedback as an ARRAY_BUFFER for an attribute it will fail.\n *\n * This function unbinds all buffers that were bound with {@link module:twgl.bindTransformFeedbackInfo}.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo.\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n */\n\n\nfunction unbindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) {\n if (transformFeedbackInfo.transformFeedbackInfo) {\n transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo;\n }\n\n if (bufferInfo.attribs) {\n bufferInfo = bufferInfo.attribs;\n }\n\n for (var name in bufferInfo) {\n var varying = transformFeedbackInfo[name];\n\n if (varying) {\n gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, varying.index, null);\n }\n }\n}\n/**\n * Creates a transform feedback and sets the buffers\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @return {WebGLTransformFeedback} the created transform feedback\n * @memberOf module:twgl\n */\n\n\nfunction createTransformFeedback(gl, programInfo, bufferInfo) {\n var tf = gl.createTransformFeedback();\n gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);\n gl.useProgram(programInfo.program);\n bindTransformFeedbackInfo(gl, programInfo, bufferInfo);\n gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); // This is only needed because of a bug in Chrome 56. Will remove\n // when chrome fixes it.\n\n unbindTransformFeedbackInfo(gl, programInfo, bufferInfo);\n return tf;\n}\n/**\n * @typedef {Object} UniformData\n * @property {number} type The WebGL type enum for this uniform\n * @property {number} size The number of elements for this uniform\n * @property {number} blockNdx The block index this uniform appears in\n * @property {number} offset The byte offset in the block for this uniform's value\n * @memberOf module:twgl\n */\n\n/**\n * The specification for one UniformBlockObject\n *\n * @typedef {Object} BlockSpec\n * @property {number} index The index of the block.\n * @property {number} size The size in bytes needed for the block\n * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices\n * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}.\n * @property {bool} usedByVertexShader Self explanitory\n * @property {bool} usedByFragmentShader Self explanitory\n * @property {bool} used Self explanitory\n * @memberOf module:twgl\n */\n\n/**\n * A `UniformBlockSpec` represents the data needed to create and bind\n * UniformBlockObjects for a given program\n *\n * @typedef {Object} UniformBlockSpec\n * @property {Object. blockSpecs The BlockSpec for each block by block name\n * @property {UniformData[]} uniformData An array of data for each uniform by uniform index.\n * @memberOf module:twgl\n */\n\n/**\n * Creates a UniformBlockSpec for the given program.\n *\n * A UniformBlockSpec represents the data needed to create and bind\n * UniformBlockObjects\n *\n * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context\n * @param {WebGLProgram} program A WebGLProgram for a successfully linked program\n * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec\n * @memberOf module:twgl/programs\n */\n\n\nfunction createUniformBlockSpecFromProgram(gl, program) {\n var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);\n var uniformData = [];\n var uniformIndices = [];\n\n for (var ii = 0; ii < numUniforms; ++ii) {\n uniformIndices.push(ii);\n uniformData.push({});\n var uniformInfo = gl.getActiveUniform(program, ii);\n\n if (isBuiltIn(uniformInfo)) {\n break;\n } // REMOVE [0]?\n\n\n uniformData[ii].name = uniformInfo.name;\n }\n\n [[\"UNIFORM_TYPE\", \"type\"], [\"UNIFORM_SIZE\", \"size\"], // num elements\n [\"UNIFORM_BLOCK_INDEX\", \"blockNdx\"], [\"UNIFORM_OFFSET\", \"offset\"]].forEach(function (pair) {\n var pname = pair[0];\n var key = pair[1];\n gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function (value, ndx) {\n uniformData[ndx][key] = value;\n });\n });\n var blockSpecs = {};\n var numUniformBlocks = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS);\n\n for (var _ii = 0; _ii < numUniformBlocks; ++_ii) {\n var name = gl.getActiveUniformBlockName(program, _ii);\n var blockSpec = {\n index: _ii,\n usedByVertexShader: gl.getActiveUniformBlockParameter(program, _ii, gl.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER),\n usedByFragmentShader: gl.getActiveUniformBlockParameter(program, _ii, gl.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER),\n size: gl.getActiveUniformBlockParameter(program, _ii, gl.UNIFORM_BLOCK_DATA_SIZE),\n uniformIndices: gl.getActiveUniformBlockParameter(program, _ii, gl.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)\n };\n blockSpec.used = blockSpec.usedByVertexSahder || blockSpec.usedByFragmentShader;\n blockSpecs[name] = blockSpec;\n }\n\n return {\n blockSpecs: blockSpecs,\n uniformData: uniformData\n };\n}\n\nvar arraySuffixRE = /\\[\\d+\\]\\.$/; // better way to check?\n\n/**\n * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values\n * and a corresponding WebGLBuffer to hold those values on the GPU\n *\n * @typedef {Object} UniformBlockInfo\n * @property {string} name The name of the block\n * @property {ArrayBuffer} array The array buffer that contains the uniform values\n * @property {Float32Array} asFloat A float view on the array buffer. This is useful\n * inspecting the contents of the buffer in the debugger.\n * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering.\n * @property {number} [offset] offset into buffer\n * @property {Object.} uniforms A uniform name to ArrayBufferView map.\n * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset\n * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array`\n * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an\n * `Int32Array` view, etc.\n * @memberOf module:twgl\n */\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {WebGLProgram} program A WebGLProgram\n * @param {module:twgl.UniformBlockSpec} uinformBlockSpec. A UniformBlockSpec as returned\n * from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {string} blockName The name of the block.\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\n\nfunction createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName) {\n var blockSpecs = uniformBlockSpec.blockSpecs;\n var uniformData = uniformBlockSpec.uniformData;\n var blockSpec = blockSpecs[blockName];\n\n if (!blockSpec) {\n warn(\"no uniform block object named:\", blockName);\n return {\n name: blockName,\n uniforms: {}\n };\n }\n\n var array = new ArrayBuffer(blockSpec.size);\n var buffer = gl.createBuffer();\n var uniformBufferIndex = blockSpec.index;\n gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);\n gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex);\n var prefix = blockName + \".\";\n\n if (arraySuffixRE.test(prefix)) {\n prefix = prefix.replace(arraySuffixRE, \".\");\n }\n\n var uniforms = {};\n blockSpec.uniformIndices.forEach(function (uniformNdx) {\n var data = uniformData[uniformNdx];\n var typeInfo = typeMap[data.type];\n var Type = typeInfo.Type;\n var length = data.size * typeInfo.size;\n var name = data.name;\n\n if (name.substr(0, prefix.length) === prefix) {\n name = name.substr(prefix.length);\n }\n\n uniforms[name] = new Type(array, data.offset, length / Type.BYTES_PER_ELEMENT);\n });\n return {\n name: blockName,\n array: array,\n asFloat: new Float32Array(array),\n // for debugging\n buffer: buffer,\n uniforms: uniforms\n };\n}\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo}\n * @param {string} blockName The name of the block.\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\n\n\nfunction createUniformBlockInfo(gl, programInfo, blockName) {\n return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName);\n}\n/**\n * Binds a unform block to the matching uniform block point.\n * Matches by blocks by name so blocks must have the same name not just the same\n * structure.\n *\n * If you have changed any values and you upload the valus into the corresponding WebGLBuffer\n * call {@link module:twgl.setUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name\n * no buffer is bound.\n * @memberOf module:twgl/programs\n */\n\n\nfunction bindUniformBlock(gl, programInfo, uniformBlockInfo) {\n var uniformBlockSpec = programInfo.uniformBlockSpec || programInfo;\n var blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name];\n\n if (blockSpec) {\n var bufferBindIndex = blockSpec.index;\n gl.bindBufferRange(gl.UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.array.byteLength);\n return true;\n }\n\n return false;\n}\n/**\n * Uploads the current uniform values to the corresponding WebGLBuffer\n * and binds that buffer to the program's corresponding bind point for the uniform block object.\n *\n * If you haven't changed any values and you only need to bind the uniform block object\n * call {@link module:twgl.bindUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @memberOf module:twgl/programs\n */\n\n\nfunction setUniformBlock(gl, programInfo, uniformBlockInfo) {\n if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) {\n gl.bufferData(gl.UNIFORM_BUFFER, uniformBlockInfo.array, gl.DYNAMIC_DRAW);\n }\n}\n/**\n * Sets values of a uniform block object\n *\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}.\n * @param {Object.} values A uniform name to value map where the value is correct for the given\n * type of uniform. So for example given a block like\n *\n * uniform SomeBlock {\n * float someFloat;\n * vec2 someVec2;\n * vec3 someVec3Array[2];\n * int someInt;\n * }\n *\n * You can set the values of the uniform block with\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * someFloat: 12.3,\n * someVec2: [1, 2],\n * someVec3Array: [1, 2, 3, 4, 5, 6],\n * someInt: 5,\n * }\n *\n * Arrays can be JavaScript arrays or typed arrays\n *\n * Any name that doesn't match will be ignored\n * @memberOf module:twgl/programs\n */\n\n\nfunction setBlockUniforms(uniformBlockInfo, values) {\n var uniforms = uniformBlockInfo.uniforms;\n\n for (var name in values) {\n var array = uniforms[name];\n\n if (array) {\n var value = values[name];\n\n if (value.length) {\n array.set(value);\n } else {\n array[0] = value;\n }\n }\n }\n}\n/**\n * Set uniforms and binds related textures.\n *\n * example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\"]);\n *\n * const tex1 = gl.createTexture();\n * const tex2 = gl.createTexture();\n *\n * ... assume we setup the textures with data ...\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * gl.useProgram(program);\n *\n * This will automatically bind the textures AND set the\n * uniforms.\n *\n * twgl.setUniforms(programInfo, uniforms);\n *\n * For the example above it is equivalent to\n *\n * var texUnit = 0;\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex1);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex2);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]);\n * gl.uniform3fv(u_somePositionLocation, [0, 1, 1]);\n * gl.uniformMatrix4fv(u_someMatrix, false, [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ]);\n *\n * Note it is perfectly reasonable to call `setUniforms` multiple times. For example\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * };\n *\n * const moreUniforms {\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * twgl.setUniforms(programInfo, uniforms);\n * twgl.setUniforms(programInfo, moreUniforms);\n *\n * You can also add WebGLSamplers to uniform samplers as in\n *\n * const uniforms = {\n * u_someSampler: {\n * texture: someWebGLTexture,\n * sampler: someWebGLSampler,\n * },\n * };\n *\n * In which case both the sampler and texture will be bound to the\n * same unit.\n *\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * uniforms.\n * You can pass multiple objects by putting them in an array or by calling with more arguments.For example\n *\n * const sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * const localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * twgl.setUniforms(programInfo, sharedUniforms, localUniforms);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, sharedUniforms);\n * twgl.setUniforms(programInfo, localUniforms};\n *\n * @memberOf module:twgl/programs\n */\n\n\nfunction setUniforms(setters, values) {\n // eslint-disable-line\n var actualSetters = setters.uniformSetters || setters;\n var numArgs = arguments.length;\n\n for (var andx = 1; andx < numArgs; ++andx) {\n var vals = arguments[andx];\n\n if (Array.isArray(vals)) {\n var numValues = vals.length;\n\n for (var ii = 0; ii < numValues; ++ii) {\n setUniforms(actualSetters, vals[ii]);\n }\n } else {\n for (var name in vals) {\n var setter = actualSetters[name];\n\n if (setter) {\n setter(vals[name]);\n }\n }\n }\n }\n}\n/**\n * Creates setter functions for all attributes of a shader\n * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes.\n *\n * @see {@link module:twgl.setAttributes} for example\n * @param {WebGLProgram} program the program to create setters for.\n * @return {Object.} an object with a setter for each attribute by name.\n * @memberOf module:twgl/programs\n */\n\n\nfunction createAttributeSetters(gl, program) {\n var attribSetters = {};\n var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);\n\n for (var ii = 0; ii < numAttribs; ++ii) {\n var attribInfo = gl.getActiveAttrib(program, ii);\n\n if (isBuiltIn(attribInfo)) {\n continue;\n }\n\n var index = gl.getAttribLocation(program, attribInfo.name);\n var typeInfo = attrTypeMap[attribInfo.type];\n var setter = typeInfo.setter(gl, index, typeInfo);\n setter.location = index;\n attribSetters[attribInfo.name] = setter;\n }\n\n return attribSetters;\n}\n/**\n * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes})\n *\n * Example:\n *\n * const program = createProgramFromScripts(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const attribSetters = createAttributeSetters(program);\n *\n * const positionBuffer = gl.createBuffer();\n * const texcoordBuffer = gl.createBuffer();\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * };\n *\n * gl.useProgram(program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setAttributes(attribSetters, attribs);\n *\n * Properties of attribs. For each attrib you can add\n * properties:\n *\n * * type: the type of data in the buffer. Default = gl.FLOAT\n * * normalize: whether or not to normalize the data. Default = false\n * * stride: the stride. Default = 0\n * * offset: offset into the buffer. Default = 0\n * * divisor: the divisor for instances. Default = undefined\n *\n * For example if you had 3 value float positions, 2 value\n * float texcoord and 4 value uint8 colors you'd setup your\n * attribs like this\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * a_color: {\n * buffer: colorBuffer,\n * numComponents: 4,\n * type: gl.UNSIGNED_BYTE,\n * normalize: true,\n * },\n * };\n *\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} buffers AttribInfos mapped by attribute name.\n * @memberOf module:twgl/programs\n * @deprecated use {@link module:twgl.setBuffersAndAttributes}\n */\n\n\nfunction setAttributes(setters, buffers) {\n for (var name in buffers) {\n var setter = setters[name];\n\n if (setter) {\n setter(buffers[name]);\n }\n }\n}\n/**\n * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate\n *\n * Example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * };\n *\n * const bufferInfo = createBufferInfoFromArrays(gl, arrays);\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setBuffersAndAttributes(gl, programInfo, bufferInfo);\n *\n * For the example above it is equivilent to\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n * gl.enableVertexAttribArray(a_positionLocation);\n * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0);\n * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);\n * gl.enableVertexAttribArray(a_texcoordLocation);\n * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgrmaInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters}\n * @param {(module:twgl.BufferInfo|module:twgl.vertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}.\n * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo}\n * @memberOf module:twgl/programs\n */\n\n\nfunction setBuffersAndAttributes(gl, programInfo, buffers) {\n if (buffers.vertexArrayObject) {\n gl.bindVertexArray(buffers.vertexArrayObject);\n } else {\n setAttributes(programInfo.attribSetters || programInfo, buffers.attribs);\n\n if (buffers.indices) {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);\n }\n }\n}\n/**\n * @typedef {Object} ProgramInfo\n * @property {WebGLProgram} program A shader program\n * @property {Object} uniformSetters object of setters as returned from createUniformSetters,\n * @property {Object} attribSetters object of setters as returned from createAttribSetters,\n * @propetty {module:twgl.UniformBlockSpec} [uniformBlockSpace] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc..\n * @property {Object} [transformFeedbackInfo] info for transform feedbacks\n * @memberOf module:twgl\n */\n\n/**\n * Creates a ProgramInfo from an existing program.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {module:twgl.ProgramInfo} The created ProgramInfo.\n * @memberOf module:twgl/programs\n */\n\n\nfunction createProgramInfoFromProgram(gl, program) {\n var uniformSetters = createUniformSetters(gl, program);\n var attribSetters = createAttributeSetters(gl, program);\n var programInfo = {\n program: program,\n uniformSetters: uniformSetters,\n attribSetters: attribSetters\n };\n\n if (utils.isWebGL2(gl)) {\n programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program);\n programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program);\n }\n\n return programInfo;\n}\n/**\n * Creates a ProgramInfo from 2 sources.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramInfo(gl, [vs, fs], options);\n * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the attributes. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile\n * @memberOf module:twgl/programs\n */\n\n\nfunction createProgramInfo(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n var good = true;\n shaderSources = shaderSources.map(function (source) {\n // Lets assume if there is no \\n it's an id\n if (source.indexOf(\"\\n\") < 0) {\n var script = getElementById(source);\n\n if (!script) {\n progOptions.errorCallback(\"no element with id: \" + source);\n good = false;\n } else {\n source = script.text;\n }\n }\n\n return source;\n });\n\n if (!good) {\n return null;\n }\n\n var program = createProgramFromSources(gl, shaderSources, progOptions);\n\n if (!program) {\n return null;\n }\n\n return createProgramInfoFromProgram(gl, program);\n}\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.axisRotate = axisRotate;\nexports.axisRotation = axisRotation;\nexports.copy = copy;\nexports.frustum = frustum;\nexports.getAxis = getAxis;\nexports.getTranslation = getTranslation;\nexports.identity = identity;\nexports.inverse = inverse;\nexports.lookAt = lookAt;\nexports.multiply = multiply;\nexports.negate = negate;\nexports.ortho = ortho;\nexports.perspective = perspective;\nexports.rotateX = rotateX;\nexports.rotateY = rotateY;\nexports.rotateZ = rotateZ;\nexports.rotationX = rotationX;\nexports.rotationY = rotationY;\nexports.rotationZ = rotationZ;\nexports.scale = scale;\nexports.scaling = scaling;\nexports.setAxis = setAxis;\nexports.setDefaultType = setDefaultType;\nexports.setTranslation = setTranslation;\nexports.transformDirection = transformDirection;\nexports.transformNormal = transformNormal;\nexports.transformPoint = transformPoint;\nexports.translate = translate;\nexports.translation = translation;\nexports.transpose = transpose;\n\nvar v3 = _interopRequireWildcard(__webpack_require__(3));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * 4x4 Matrix math math functions.\n *\n * Almost all functions take an optional `dst` argument. If it is not passed in the\n * functions will create a new matrix. In other words you can do this\n *\n * const mat = m4.translation([1, 2, 3]); // Creates a new translation matrix\n *\n * or\n *\n * const mat = m4.create();\n * m4.translation([1, 2, 3], mat); // Puts translation matrix in mat.\n *\n * The first style is often easier but depending on where it's used it generates garbage where\n * as there is almost never allocation with the second style.\n *\n * It is always save to pass any matrix as the destination. So for example\n *\n * const mat = m4.identity();\n * const trans = m4.translation([1, 2, 3]);\n * m4.multiply(mat, trans, mat); // Multiplies mat * trans and puts result in mat.\n *\n * @module twgl/m4\n */\nvar MatType = Float32Array;\nvar tempV3a = v3.create();\nvar tempV3b = v3.create();\nvar tempV3c = v3.create();\n/**\n * A JavaScript array with 16 values or a Float32Array with 16 values.\n * When created by the library will create the default type which is `Float32Array`\n * but can be set by calling {@link module:twgl/m4.setDefaultType}.\n * @typedef {(number[]|Float32Array)} Mat4\n * @memberOf module:twgl/m4\n */\n\n/**\n * Sets the type this library creates for a Mat4\n * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array`\n * @return {constructor} previous constructor for Mat4\n */\n\nfunction setDefaultType(ctor) {\n var oldType = MatType;\n MatType = ctor;\n return oldType;\n}\n/**\n * Negates a matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} -m.\n * @memberOf module:twgl/m4\n */\n\n\nfunction negate(m, dst) {\n dst = dst || new MatType(16);\n dst[0] = -m[0];\n dst[1] = -m[1];\n dst[2] = -m[2];\n dst[3] = -m[3];\n dst[4] = -m[4];\n dst[5] = -m[5];\n dst[6] = -m[6];\n dst[7] = -m[7];\n dst[8] = -m[8];\n dst[9] = -m[9];\n dst[10] = -m[10];\n dst[11] = -m[11];\n dst[12] = -m[12];\n dst[13] = -m[13];\n dst[14] = -m[14];\n dst[15] = -m[15];\n return dst;\n}\n/**\n * Copies a matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] The matrix.\n * @return {module:twgl/m4.Mat4} A copy of m.\n * @memberOf module:twgl/m4\n */\n\n\nfunction copy(m, dst) {\n dst = dst || new MatType(16);\n dst[0] = m[0];\n dst[1] = m[1];\n dst[2] = m[2];\n dst[3] = m[3];\n dst[4] = m[4];\n dst[5] = m[5];\n dst[6] = m[6];\n dst[7] = m[7];\n dst[8] = m[8];\n dst[9] = m[9];\n dst[10] = m[10];\n dst[11] = m[11];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n return dst;\n}\n/**\n * Creates an n-by-n identity matrix.\n *\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} An n-by-n identity matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction identity(dst) {\n dst = dst || new MatType(16);\n dst[0] = 1;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = 1;\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = 1;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n return dst;\n}\n/**\n * Takes the transpose of a matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The transpose of m.\n * @memberOf module:twgl/m4\n */\n\n\nfunction transpose(m, dst) {\n dst = dst || new MatType(16);\n\n if (dst === m) {\n var t;\n t = m[1];\n m[1] = m[4];\n m[4] = t;\n t = m[2];\n m[2] = m[8];\n m[8] = t;\n t = m[3];\n m[3] = m[12];\n m[12] = t;\n t = m[6];\n m[6] = m[9];\n m[9] = t;\n t = m[7];\n m[7] = m[13];\n m[13] = t;\n t = m[11];\n m[11] = m[14];\n m[14] = t;\n return dst;\n }\n\n var m00 = m[0 * 4 + 0];\n var m01 = m[0 * 4 + 1];\n var m02 = m[0 * 4 + 2];\n var m03 = m[0 * 4 + 3];\n var m10 = m[1 * 4 + 0];\n var m11 = m[1 * 4 + 1];\n var m12 = m[1 * 4 + 2];\n var m13 = m[1 * 4 + 3];\n var m20 = m[2 * 4 + 0];\n var m21 = m[2 * 4 + 1];\n var m22 = m[2 * 4 + 2];\n var m23 = m[2 * 4 + 3];\n var m30 = m[3 * 4 + 0];\n var m31 = m[3 * 4 + 1];\n var m32 = m[3 * 4 + 2];\n var m33 = m[3 * 4 + 3];\n dst[0] = m00;\n dst[1] = m10;\n dst[2] = m20;\n dst[3] = m30;\n dst[4] = m01;\n dst[5] = m11;\n dst[6] = m21;\n dst[7] = m31;\n dst[8] = m02;\n dst[9] = m12;\n dst[10] = m22;\n dst[11] = m32;\n dst[12] = m03;\n dst[13] = m13;\n dst[14] = m23;\n dst[15] = m33;\n return dst;\n}\n/**\n * Computes the inverse of a 4-by-4 matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The inverse of m.\n * @memberOf module:twgl/m4\n */\n\n\nfunction inverse(m, dst) {\n dst = dst || new MatType(16);\n var m00 = m[0 * 4 + 0];\n var m01 = m[0 * 4 + 1];\n var m02 = m[0 * 4 + 2];\n var m03 = m[0 * 4 + 3];\n var m10 = m[1 * 4 + 0];\n var m11 = m[1 * 4 + 1];\n var m12 = m[1 * 4 + 2];\n var m13 = m[1 * 4 + 3];\n var m20 = m[2 * 4 + 0];\n var m21 = m[2 * 4 + 1];\n var m22 = m[2 * 4 + 2];\n var m23 = m[2 * 4 + 3];\n var m30 = m[3 * 4 + 0];\n var m31 = m[3 * 4 + 1];\n var m32 = m[3 * 4 + 2];\n var m33 = m[3 * 4 + 3];\n var tmp_0 = m22 * m33;\n var tmp_1 = m32 * m23;\n var tmp_2 = m12 * m33;\n var tmp_3 = m32 * m13;\n var tmp_4 = m12 * m23;\n var tmp_5 = m22 * m13;\n var tmp_6 = m02 * m33;\n var tmp_7 = m32 * m03;\n var tmp_8 = m02 * m23;\n var tmp_9 = m22 * m03;\n var tmp_10 = m02 * m13;\n var tmp_11 = m12 * m03;\n var tmp_12 = m20 * m31;\n var tmp_13 = m30 * m21;\n var tmp_14 = m10 * m31;\n var tmp_15 = m30 * m11;\n var tmp_16 = m10 * m21;\n var tmp_17 = m20 * m11;\n var tmp_18 = m00 * m31;\n var tmp_19 = m30 * m01;\n var tmp_20 = m00 * m21;\n var tmp_21 = m20 * m01;\n var tmp_22 = m00 * m11;\n var tmp_23 = m10 * m01;\n var t0 = tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31 - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);\n var t1 = tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31 - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);\n var t2 = tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31 - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);\n var t3 = tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21 - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);\n var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);\n dst[0] = d * t0;\n dst[1] = d * t1;\n dst[2] = d * t2;\n dst[3] = d * t3;\n dst[4] = d * (tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30 - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30));\n dst[5] = d * (tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30 - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30));\n dst[6] = d * (tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30 - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30));\n dst[7] = d * (tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20 - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20));\n dst[8] = d * (tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33 - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33));\n dst[9] = d * (tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33 - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33));\n dst[10] = d * (tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33 - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33));\n dst[11] = d * (tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23 - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23));\n dst[12] = d * (tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12 - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22));\n dst[13] = d * (tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22 - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02));\n dst[14] = d * (tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02 - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12));\n dst[15] = d * (tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12 - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02));\n return dst;\n}\n/**\n * Multiplies two 4-by-4 matrices with a on the left and b on the right\n * @param {module:twgl/m4.Mat4} a The matrix on the left.\n * @param {module:twgl/m4.Mat4} b The matrix on the right.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The matrix product of a and b.\n * @memberOf module:twgl/m4\n */\n\n\nfunction multiply(a, b, dst) {\n dst = dst || new MatType(16);\n var a00 = a[0];\n var a01 = a[1];\n var a02 = a[2];\n var a03 = a[3];\n var a10 = a[4 + 0];\n var a11 = a[4 + 1];\n var a12 = a[4 + 2];\n var a13 = a[4 + 3];\n var a20 = a[8 + 0];\n var a21 = a[8 + 1];\n var a22 = a[8 + 2];\n var a23 = a[8 + 3];\n var a30 = a[12 + 0];\n var a31 = a[12 + 1];\n var a32 = a[12 + 2];\n var a33 = a[12 + 3];\n var b00 = b[0];\n var b01 = b[1];\n var b02 = b[2];\n var b03 = b[3];\n var b10 = b[4 + 0];\n var b11 = b[4 + 1];\n var b12 = b[4 + 2];\n var b13 = b[4 + 3];\n var b20 = b[8 + 0];\n var b21 = b[8 + 1];\n var b22 = b[8 + 2];\n var b23 = b[8 + 3];\n var b30 = b[12 + 0];\n var b31 = b[12 + 1];\n var b32 = b[12 + 2];\n var b33 = b[12 + 3];\n dst[0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;\n dst[1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;\n dst[2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;\n dst[3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;\n dst[4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;\n dst[5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;\n dst[6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;\n dst[7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;\n dst[8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;\n dst[9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;\n dst[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;\n dst[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;\n dst[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;\n dst[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;\n dst[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;\n dst[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;\n return dst;\n}\n/**\n * Sets the translation component of a 4-by-4 matrix to the given\n * vector.\n * @param {module:twgl/m4.Mat4} a The matrix.\n * @param {Vec3} v The vector.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} a once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction setTranslation(a, v, dst) {\n dst = dst || identity();\n\n if (a !== dst) {\n dst[0] = a[0];\n dst[1] = a[1];\n dst[2] = a[2];\n dst[3] = a[3];\n dst[4] = a[4];\n dst[5] = a[5];\n dst[6] = a[6];\n dst[7] = a[7];\n dst[8] = a[8];\n dst[9] = a[9];\n dst[10] = a[10];\n dst[11] = a[11];\n }\n\n dst[12] = v[0];\n dst[13] = v[1];\n dst[14] = v[2];\n dst[15] = 1;\n return dst;\n}\n/**\n * Returns the translation component of a 4-by-4 matrix as a vector with 3\n * entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {Vec3} [dst] vector..\n * @return {Vec3} The translation component of m.\n * @memberOf module:twgl/m4\n */\n\n\nfunction getTranslation(m, dst) {\n dst = dst || v3.create();\n dst[0] = m[12];\n dst[1] = m[13];\n dst[2] = m[14];\n return dst;\n}\n/**\n * Returns an axis of a 4x4 matrix as a vector with 3 entries\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} axis The axis 0 = x, 1 = y, 2 = z;\n * @return {Vec3} [dst] vector.\n * @return {Vec3} The axis component of m.\n * @memberOf module:twgl/m4\n */\n\n\nfunction getAxis(m, axis, dst) {\n dst = dst || v3.create();\n var off = axis * 4;\n dst[0] = m[off + 0];\n dst[1] = m[off + 1];\n dst[2] = m[off + 2];\n return dst;\n}\n/**\n * Sets an axis of a 4x4 matrix as a vector with 3 entries\n * @param {Vec3} v the axis vector\n * @param {number} axis The axis 0 = x, 1 = y, 2 = z;\n * @param {module:twgl/m4.Mat4} [dst] The matrix to set. If none a new one is created\n * @return {module:twgl/m4.Mat4} dst\n * @memberOf module:twgl/m4\n */\n\n\nfunction setAxis(a, v, axis, dst) {\n if (dst !== a) {\n dst = copy(a, dst);\n }\n\n var off = axis * 4;\n dst[off + 0] = v[0];\n dst[off + 1] = v[1];\n dst[off + 2] = v[2];\n return dst;\n}\n/**\n * Computes a 4-by-4 perspective transformation matrix given the angular height\n * of the frustum, the aspect ratio, and the near and far clipping planes. The\n * arguments define a frustum extending in the negative z direction. The given\n * angle is the vertical angle of the frustum, and the horizontal angle is\n * determined to produce the given aspect ratio. The arguments near and far are\n * the distances to the near and far clipping planes. Note that near and far\n * are not z coordinates, but rather they are distances along the negative\n * z-axis. The matrix generated sends the viewing frustum to the unit box.\n * We assume a unit box extending from -1 to 1 in the x and y dimensions and\n * from 0 to 1 in the z dimension.\n * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians).\n * @param {number} aspect The aspect ratio width / height.\n * @param {number} zNear The depth (negative z coordinate)\n * of the near clipping plane.\n * @param {number} zFar The depth (negative z coordinate)\n * of the far clipping plane.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The perspective matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) {\n dst = dst || new MatType(16);\n var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians);\n var rangeInv = 1.0 / (zNear - zFar);\n dst[0] = f / aspect;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = f;\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = (zNear + zFar) * rangeInv;\n dst[11] = -1;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = zNear * zFar * rangeInv * 2;\n dst[15] = 0;\n return dst;\n}\n/**\n * Computes a 4-by-4 othogonal transformation matrix given the left, right,\n * bottom, and top dimensions of the near clipping plane as well as the\n * near and far clipping plane distances.\n * @param {number} left Left side of the near clipping plane viewport.\n * @param {number} right Right side of the near clipping plane viewport.\n * @param {number} top Top of the near clipping plane viewport.\n * @param {number} bottom Bottom of the near clipping plane viewport.\n * @param {number} near The depth (negative z coordinate)\n * of the near clipping plane.\n * @param {number} far The depth (negative z coordinate)\n * of the far clipping plane.\n * @param {module:twgl/m4.Mat4} [dst] Output matrix.\n * @return {module:twgl/m4.Mat4} The perspective matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction ortho(left, right, bottom, top, near, far, dst) {\n dst = dst || new MatType(16);\n dst[0] = 2 / (right - left);\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = 2 / (top - bottom);\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = 2 / (near - far);\n dst[11] = 0;\n dst[12] = (right + left) / (left - right);\n dst[13] = (top + bottom) / (bottom - top);\n dst[14] = (far + near) / (near - far);\n dst[15] = 1;\n return dst;\n}\n/**\n * Computes a 4-by-4 perspective transformation matrix given the left, right,\n * top, bottom, near and far clipping planes. The arguments define a frustum\n * extending in the negative z direction. The arguments near and far are the\n * distances to the near and far clipping planes. Note that near and far are not\n * z coordinates, but rather they are distances along the negative z-axis. The\n * matrix generated sends the viewing frustum to the unit box. We assume a unit\n * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z\n * dimension.\n * @param {number} left The x coordinate of the left plane of the box.\n * @param {number} right The x coordinate of the right plane of the box.\n * @param {number} bottom The y coordinate of the bottom plane of the box.\n * @param {number} top The y coordinate of the right plane of the box.\n * @param {number} near The negative z coordinate of the near plane of the box.\n * @param {number} far The negative z coordinate of the far plane of the box.\n * @param {module:twgl/m4.Mat4} [dst] Output matrix.\n * @return {module:twgl/m4.Mat4} The perspective projection matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction frustum(left, right, bottom, top, near, far, dst) {\n dst = dst || new MatType(16);\n var dx = right - left;\n var dy = top - bottom;\n var dz = near - far;\n dst[0] = 2 * near / dx;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = 2 * near / dy;\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = (left + right) / dx;\n dst[9] = (top + bottom) / dy;\n dst[10] = far / dz;\n dst[11] = -1;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = near * far / dz;\n dst[15] = 0;\n return dst;\n}\n/**\n * Computes a 4-by-4 look-at transformation.\n *\n * This is a matrix which positions the camera itself. If you want\n * a view matrix (a matrix which moves things in front of the camera)\n * take the inverse of this.\n *\n * @param {Vec3} eye The position of the eye.\n * @param {Vec3} target The position meant to be viewed.\n * @param {Vec3} up A vector pointing up.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The look-at matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction lookAt(eye, target, up, dst) {\n dst = dst || new MatType(16);\n var xAxis = tempV3a;\n var yAxis = tempV3b;\n var zAxis = tempV3c;\n v3.normalize(v3.subtract(eye, target, zAxis), zAxis);\n v3.normalize(v3.cross(up, zAxis, xAxis), xAxis);\n v3.normalize(v3.cross(zAxis, xAxis, yAxis), yAxis);\n dst[0] = xAxis[0];\n dst[1] = xAxis[1];\n dst[2] = xAxis[2];\n dst[3] = 0;\n dst[4] = yAxis[0];\n dst[5] = yAxis[1];\n dst[6] = yAxis[2];\n dst[7] = 0;\n dst[8] = zAxis[0];\n dst[9] = zAxis[1];\n dst[10] = zAxis[2];\n dst[11] = 0;\n dst[12] = eye[0];\n dst[13] = eye[1];\n dst[14] = eye[2];\n dst[15] = 1;\n return dst;\n}\n/**\n * Creates a 4-by-4 matrix which translates by the given vector v.\n * @param {Vec3} v The vector by\n * which to translate.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The translation matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction translation(v, dst) {\n dst = dst || new MatType(16);\n dst[0] = 1;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = 1;\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = 1;\n dst[11] = 0;\n dst[12] = v[0];\n dst[13] = v[1];\n dst[14] = v[2];\n dst[15] = 1;\n return dst;\n}\n/**\n * Modifies the given 4-by-4 matrix by translation by the given vector v.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {Vec3} v The vector by\n * which to translate.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} m once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction translate(m, v, dst) {\n dst = dst || new MatType(16);\n var v0 = v[0];\n var v1 = v[1];\n var v2 = v[2];\n var m00 = m[0];\n var m01 = m[1];\n var m02 = m[2];\n var m03 = m[3];\n var m10 = m[1 * 4 + 0];\n var m11 = m[1 * 4 + 1];\n var m12 = m[1 * 4 + 2];\n var m13 = m[1 * 4 + 3];\n var m20 = m[2 * 4 + 0];\n var m21 = m[2 * 4 + 1];\n var m22 = m[2 * 4 + 2];\n var m23 = m[2 * 4 + 3];\n var m30 = m[3 * 4 + 0];\n var m31 = m[3 * 4 + 1];\n var m32 = m[3 * 4 + 2];\n var m33 = m[3 * 4 + 3];\n\n if (m !== dst) {\n dst[0] = m00;\n dst[1] = m01;\n dst[2] = m02;\n dst[3] = m03;\n dst[4] = m10;\n dst[5] = m11;\n dst[6] = m12;\n dst[7] = m13;\n dst[8] = m20;\n dst[9] = m21;\n dst[10] = m22;\n dst[11] = m23;\n }\n\n dst[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30;\n dst[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31;\n dst[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32;\n dst[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33;\n return dst;\n}\n/**\n * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The rotation matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction rotationX(angleInRadians, dst) {\n dst = dst || new MatType(16);\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n dst[0] = 1;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = c;\n dst[6] = s;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = -s;\n dst[10] = c;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n return dst;\n}\n/**\n * Modifies the given 4-by-4 matrix by a rotation around the x-axis by the given\n * angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} m once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction rotateX(m, angleInRadians, dst) {\n dst = dst || new MatType(16);\n var m10 = m[4];\n var m11 = m[5];\n var m12 = m[6];\n var m13 = m[7];\n var m20 = m[8];\n var m21 = m[9];\n var m22 = m[10];\n var m23 = m[11];\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n dst[4] = c * m10 + s * m20;\n dst[5] = c * m11 + s * m21;\n dst[6] = c * m12 + s * m22;\n dst[7] = c * m13 + s * m23;\n dst[8] = c * m20 - s * m10;\n dst[9] = c * m21 - s * m11;\n dst[10] = c * m22 - s * m12;\n dst[11] = c * m23 - s * m13;\n\n if (m !== dst) {\n dst[0] = m[0];\n dst[1] = m[1];\n dst[2] = m[2];\n dst[3] = m[3];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n/**\n * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The rotation matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction rotationY(angleInRadians, dst) {\n dst = dst || new MatType(16);\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n dst[0] = c;\n dst[1] = 0;\n dst[2] = -s;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = 1;\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = s;\n dst[9] = 0;\n dst[10] = c;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n return dst;\n}\n/**\n * Modifies the given 4-by-4 matrix by a rotation around the y-axis by the given\n * angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} m once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction rotateY(m, angleInRadians, dst) {\n dst = dst || new MatType(16);\n var m00 = m[0 * 4 + 0];\n var m01 = m[0 * 4 + 1];\n var m02 = m[0 * 4 + 2];\n var m03 = m[0 * 4 + 3];\n var m20 = m[2 * 4 + 0];\n var m21 = m[2 * 4 + 1];\n var m22 = m[2 * 4 + 2];\n var m23 = m[2 * 4 + 3];\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n dst[0] = c * m00 - s * m20;\n dst[1] = c * m01 - s * m21;\n dst[2] = c * m02 - s * m22;\n dst[3] = c * m03 - s * m23;\n dst[8] = c * m20 + s * m00;\n dst[9] = c * m21 + s * m01;\n dst[10] = c * m22 + s * m02;\n dst[11] = c * m23 + s * m03;\n\n if (m !== dst) {\n dst[4] = m[4];\n dst[5] = m[5];\n dst[6] = m[6];\n dst[7] = m[7];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n/**\n * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The rotation matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction rotationZ(angleInRadians, dst) {\n dst = dst || new MatType(16);\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n dst[0] = c;\n dst[1] = s;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = -s;\n dst[5] = c;\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = 1;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n return dst;\n}\n/**\n * Modifies the given 4-by-4 matrix by a rotation around the z-axis by the given\n * angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} m once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction rotateZ(m, angleInRadians, dst) {\n dst = dst || new MatType(16);\n var m00 = m[0 * 4 + 0];\n var m01 = m[0 * 4 + 1];\n var m02 = m[0 * 4 + 2];\n var m03 = m[0 * 4 + 3];\n var m10 = m[1 * 4 + 0];\n var m11 = m[1 * 4 + 1];\n var m12 = m[1 * 4 + 2];\n var m13 = m[1 * 4 + 3];\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n dst[0] = c * m00 + s * m10;\n dst[1] = c * m01 + s * m11;\n dst[2] = c * m02 + s * m12;\n dst[3] = c * m03 + s * m13;\n dst[4] = c * m10 - s * m00;\n dst[5] = c * m11 - s * m01;\n dst[6] = c * m12 - s * m02;\n dst[7] = c * m13 - s * m03;\n\n if (m !== dst) {\n dst[8] = m[8];\n dst[9] = m[9];\n dst[10] = m[10];\n dst[11] = m[11];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n/**\n * Creates a 4-by-4 matrix which rotates around the given axis by the given\n * angle.\n * @param {Vec3} axis The axis\n * about which to rotate.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} A matrix which rotates angle radians\n * around the axis.\n * @memberOf module:twgl/m4\n */\n\n\nfunction axisRotation(axis, angleInRadians, dst) {\n dst = dst || new MatType(16);\n var x = axis[0];\n var y = axis[1];\n var z = axis[2];\n var n = Math.sqrt(x * x + y * y + z * z);\n x /= n;\n y /= n;\n z /= n;\n var xx = x * x;\n var yy = y * y;\n var zz = z * z;\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n var oneMinusCosine = 1 - c;\n dst[0] = xx + (1 - xx) * c;\n dst[1] = x * y * oneMinusCosine + z * s;\n dst[2] = x * z * oneMinusCosine - y * s;\n dst[3] = 0;\n dst[4] = x * y * oneMinusCosine - z * s;\n dst[5] = yy + (1 - yy) * c;\n dst[6] = y * z * oneMinusCosine + x * s;\n dst[7] = 0;\n dst[8] = x * z * oneMinusCosine + y * s;\n dst[9] = y * z * oneMinusCosine - x * s;\n dst[10] = zz + (1 - zz) * c;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n return dst;\n}\n/**\n * Modifies the given 4-by-4 matrix by rotation around the given axis by the\n * given angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {Vec3} axis The axis\n * about which to rotate.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} m once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction axisRotate(m, axis, angleInRadians, dst) {\n dst = dst || new MatType(16);\n var x = axis[0];\n var y = axis[1];\n var z = axis[2];\n var n = Math.sqrt(x * x + y * y + z * z);\n x /= n;\n y /= n;\n z /= n;\n var xx = x * x;\n var yy = y * y;\n var zz = z * z;\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n var oneMinusCosine = 1 - c;\n var r00 = xx + (1 - xx) * c;\n var r01 = x * y * oneMinusCosine + z * s;\n var r02 = x * z * oneMinusCosine - y * s;\n var r10 = x * y * oneMinusCosine - z * s;\n var r11 = yy + (1 - yy) * c;\n var r12 = y * z * oneMinusCosine + x * s;\n var r20 = x * z * oneMinusCosine + y * s;\n var r21 = y * z * oneMinusCosine - x * s;\n var r22 = zz + (1 - zz) * c;\n var m00 = m[0];\n var m01 = m[1];\n var m02 = m[2];\n var m03 = m[3];\n var m10 = m[4];\n var m11 = m[5];\n var m12 = m[6];\n var m13 = m[7];\n var m20 = m[8];\n var m21 = m[9];\n var m22 = m[10];\n var m23 = m[11];\n dst[0] = r00 * m00 + r01 * m10 + r02 * m20;\n dst[1] = r00 * m01 + r01 * m11 + r02 * m21;\n dst[2] = r00 * m02 + r01 * m12 + r02 * m22;\n dst[3] = r00 * m03 + r01 * m13 + r02 * m23;\n dst[4] = r10 * m00 + r11 * m10 + r12 * m20;\n dst[5] = r10 * m01 + r11 * m11 + r12 * m21;\n dst[6] = r10 * m02 + r11 * m12 + r12 * m22;\n dst[7] = r10 * m03 + r11 * m13 + r12 * m23;\n dst[8] = r20 * m00 + r21 * m10 + r22 * m20;\n dst[9] = r20 * m01 + r21 * m11 + r22 * m21;\n dst[10] = r20 * m02 + r21 * m12 + r22 * m22;\n dst[11] = r20 * m03 + r21 * m13 + r22 * m23;\n\n if (m !== dst) {\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n/**\n * Creates a 4-by-4 matrix which scales in each dimension by an amount given by\n * the corresponding entry in the given vector; assumes the vector has three\n * entries.\n * @param {Vec3} v A vector of\n * three entries specifying the factor by which to scale in each dimension.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} The scaling matrix.\n * @memberOf module:twgl/m4\n */\n\n\nfunction scaling(v, dst) {\n dst = dst || new MatType(16);\n dst[0] = v[0];\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = 0;\n dst[5] = v[1];\n dst[6] = 0;\n dst[7] = 0;\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = v[2];\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n return dst;\n}\n/**\n * Modifies the given 4-by-4 matrix, scaling in each dimension by an amount\n * given by the corresponding entry in the given vector; assumes the vector has\n * three entries.\n * @param {module:twgl/m4.Mat4} m The matrix to be modified.\n * @param {Vec3} v A vector of three entries specifying the\n * factor by which to scale in each dimension.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created..\n * @return {module:twgl/m4.Mat4} m once modified.\n * @memberOf module:twgl/m4\n */\n\n\nfunction scale(m, v, dst) {\n dst = dst || new MatType(16);\n var v0 = v[0];\n var v1 = v[1];\n var v2 = v[2];\n dst[0] = v0 * m[0 * 4 + 0];\n dst[1] = v0 * m[0 * 4 + 1];\n dst[2] = v0 * m[0 * 4 + 2];\n dst[3] = v0 * m[0 * 4 + 3];\n dst[4] = v1 * m[1 * 4 + 0];\n dst[5] = v1 * m[1 * 4 + 1];\n dst[6] = v1 * m[1 * 4 + 2];\n dst[7] = v1 * m[1 * 4 + 3];\n dst[8] = v2 * m[2 * 4 + 0];\n dst[9] = v2 * m[2 * 4 + 1];\n dst[10] = v2 * m[2 * 4 + 2];\n dst[11] = v2 * m[2 * 4 + 3];\n\n if (m !== dst) {\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n/**\n * Takes a 4-by-4 matrix and a vector with 3 entries,\n * interprets the vector as a point, transforms that point by the matrix, and\n * returns the result as a vector with 3 entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {Vec3} v The point.\n * @param {Vec3} dst optional vec3 to store result\n * @return {Vec3} dst or new vec3 if not provided\n * @memberOf module:twgl/m4\n */\n\n\nfunction transformPoint(m, v, dst) {\n dst = dst || v3.create();\n var v0 = v[0];\n var v1 = v[1];\n var v2 = v[2];\n var d = v0 * m[0 * 4 + 3] + v1 * m[1 * 4 + 3] + v2 * m[2 * 4 + 3] + m[3 * 4 + 3];\n dst[0] = (v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0] + m[3 * 4 + 0]) / d;\n dst[1] = (v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1] + m[3 * 4 + 1]) / d;\n dst[2] = (v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2] + m[3 * 4 + 2]) / d;\n return dst;\n}\n/**\n * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a\n * direction, transforms that direction by the matrix, and returns the result;\n * assumes the transformation of 3-dimensional space represented by the matrix\n * is parallel-preserving, i.e. any combination of rotation, scaling and\n * translation, but not a perspective distortion. Returns a vector with 3\n * entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {Vec3} v The direction.\n * @param {Vec3} dst optional Vec3 to store result\n * @return {Vec3} dst or new Vec3 if not provided\n * @memberOf module:twgl/m4\n */\n\n\nfunction transformDirection(m, v, dst) {\n dst = dst || v3.create();\n var v0 = v[0];\n var v1 = v[1];\n var v2 = v[2];\n dst[0] = v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0];\n dst[1] = v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1];\n dst[2] = v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2];\n return dst;\n}\n/**\n * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector\n * as a normal to a surface, and computes a vector which is normal upon\n * transforming that surface by the matrix. The effect of this function is the\n * same as transforming v (as a direction) by the inverse-transpose of m. This\n * function assumes the transformation of 3-dimensional space represented by the\n * matrix is parallel-preserving, i.e. any combination of rotation, scaling and\n * translation, but not a perspective distortion. Returns a vector with 3\n * entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {Vec3} v The normal.\n * @param {Vec3} [dst] The direction.\n * @return {Vec3} The transformed direction.\n * @memberOf module:twgl/m4\n */\n\n\nfunction transformNormal(m, v, dst) {\n dst = dst || v3.create();\n var mi = inverse(m);\n var v0 = v[0];\n var v1 = v[1];\n var v2 = v[2];\n dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2];\n dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2];\n dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2];\n return dst;\n}\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.createAttribsFromArrays = createAttribsFromArrays;\nexports.createBuffersFromArrays = createBuffersFromArrays;\nexports.createBufferFromArray = createBufferFromArray;\nexports.createBufferFromTypedArray = createBufferFromTypedArray;\nexports.createBufferInfoFromArrays = createBufferInfoFromArrays;\nexports.setAttribInfoBufferFromArray = setAttribInfoBufferFromArray;\nexports.setAttributePrefix = setAttributePrefix;\nexports.setAttributeDefaults_ = setDefaults;\nexports.getNumComponents_ = getNumComponents;\nexports.getArray_ = getArray;\n\nvar typedArrays = _interopRequireWildcard(__webpack_require__(1));\n\nvar helper = _interopRequireWildcard(__webpack_require__(0));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * Low level attribute and buffer related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibily they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/attributes\n */\n// make sure we don't see a global gl\nvar gl = undefined; // eslint-disable-line\n\nvar defaults = {\n attribPrefix: \"\"\n};\n/**\n * Sets the default attrib prefix\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using unprefixed names.\n *\n * In otherwords I'll create arrays of geometry like this\n *\n * var arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * @deprecated see {@link module:twgl.setDefaults}\n * @param {string} prefix prefix for attribs\n * @memberOf module:twgl/attributes\n */\n\nfunction setAttributePrefix(prefix) {\n defaults.attribPrefix = prefix;\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n}\n\nfunction setBufferFromTypedArray(gl, type, buffer, array, drawType) {\n gl.bindBuffer(type, buffer);\n gl.bufferData(type, array, drawType || gl.STATIC_DRAW);\n}\n/**\n * Given typed array creates a WebGLBuffer and copies the typed array\n * into it.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken\n * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`.\n * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`.\n * @return {WebGLBuffer} the created WebGLBuffer\n * @memberOf module:twgl/attributes\n */\n\n\nfunction createBufferFromTypedArray(gl, typedArray, type, drawType) {\n if (helper.isBuffer(gl, typedArray)) {\n return typedArray;\n }\n\n type = type || gl.ARRAY_BUFFER;\n var buffer = gl.createBuffer();\n setBufferFromTypedArray(gl, type, buffer, typedArray, drawType);\n return buffer;\n}\n\nfunction isIndices(name) {\n return name === \"indices\";\n} // This is really just a guess. Though I can't really imagine using\n// anything else? Maybe for some compression?\n\n\nfunction getNormalizationForTypedArray(typedArray) {\n if (typedArray instanceof Int8Array) {\n return true;\n } // eslint-disable-line\n\n\n if (typedArray instanceof Uint8Array) {\n return true;\n } // eslint-disable-line\n\n\n return false;\n} // This is really just a guess. Though I can't really imagine using\n// anything else? Maybe for some compression?\n\n\nfunction getNormalizationForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) {\n return true;\n } // eslint-disable-line\n\n\n if (typedArrayType === Uint8Array) {\n return true;\n } // eslint-disable-line\n\n\n return false;\n}\n\nfunction getArray(array) {\n return array.length ? array : array.data;\n}\n\nvar texcoordRE = /coord|texture/i;\nvar colorRE = /color|colour/i;\n\nfunction guessNumComponentsFromName(name, length) {\n var numComponents;\n\n if (texcoordRE.test(name)) {\n numComponents = 2;\n } else if (colorRE.test(name)) {\n numComponents = 4;\n } else {\n numComponents = 3; // position, normals, indices ...\n }\n\n if (length % numComponents > 0) {\n throw \"Can not guess numComponents for attribute '\" + name + \"'. Tried \" + numComponents + \" but \" + length + \" values is not evenly divisible by \" + numComponents + \". You should specify it.\";\n }\n\n return numComponents;\n}\n\nfunction getNumComponents(array, arrayName) {\n return array.numComponents || array.size || guessNumComponentsFromName(arrayName, getArray(array).length);\n}\n\nfunction makeTypedArray(array, name) {\n if (typedArrays.isArrayBuffer(array)) {\n return array;\n }\n\n if (typedArrays.isArrayBuffer(array.data)) {\n return array.data;\n }\n\n if (Array.isArray(array)) {\n array = {\n data: array\n };\n }\n\n var Type = array.type;\n\n if (!Type) {\n if (isIndices(name)) {\n Type = Uint16Array;\n } else {\n Type = Float32Array;\n }\n }\n\n return new Type(array.data);\n}\n/**\n * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer\n * for the attribute.\n *\n * @typedef {Object} AttribInfo\n * @property {number} [numComponents] the number of components for this attribute.\n * @property {number} [size] synonym for `numComponents`.\n * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT`\n * @property {boolean} [normalize] whether or not to normalize the data. Default = false\n * @property {number} [offset] offset into buffer in bytes. Default = 0\n * @property {number} [stride] the stride in bytes per element. Default = 0\n * @property {number} [divisor] the divisor in instances. Default = undefined. Note: undefined = don't call gl.vertexAttribDivisor\n * where as anything else = do call it with this value\n * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * Use this type of array spec when TWGL can't guess the type or number of compoments of an array\n * @typedef {Object} FullArraySpec\n * @property {(number|number[]|ArrayBufferView)} data The data of the array. A number alone becomes the number of elements of type.\n * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array.\n * If `coord` is in the name assumes `numComponents = 2`.\n * If `color` is in the name assumes `numComponents = 4`.\n * otherwise assumes `numComponents = 3`\n * @property {constructor} type The type. This is only used if `data` is a JavaScript array. It is the constructor for the typedarray. (eg. `Uint8Array`).\n * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: Uint8Array, data: [255,0,255,255, ...], }`.\n * @property {number} [size] synonym for `numComponents`.\n * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false.\n * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0\n * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0\n * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = undefined. Note: undefined = don't call gl.vertexAttribDivisor\n * where as anything else = do call it with this value\n * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix.\n * @property {string} [name] synonym for `attrib`.\n * @property {string} [attribName] synonym for `attrib`.\n * @memberOf module:twgl\n */\n\n/**\n * An individual array in {@link module:twgl.Arrays}\n *\n * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView`\n * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will\n * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer.\n *\n * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec\n * @memberOf module:twgl\n */\n\n/**\n * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your\n * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}.\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * Objects with various fields. See {@link module:twgl.FullArraySpec}.\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * @typedef {Object.} Arrays\n * @memberOf module:twgl\n */\n\n/**\n * Creates a set of attribute data and WebGLBuffers from set of arrays\n *\n * Given\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * color: { numComponents: 4, data: [255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255], type: Uint8Array, },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * returns something like\n *\n * var attribs = {\n * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, },\n * };\n *\n * notes:\n *\n * * Arrays can take various forms\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * @param {WebGLRenderingContext} gl The webgl rendering context.\n * @param {module:twgl.Arrays} arrays The arrays\n * @return {Object.} the attribs\n * @memberOf module:twgl/attributes\n */\n\n\nfunction createAttribsFromArrays(gl, arrays) {\n var attribs = {};\n Object.keys(arrays).forEach(function (arrayName) {\n if (!isIndices(arrayName)) {\n var array = arrays[arrayName];\n var attribName = array.attrib || array.name || array.attribName || defaults.attribPrefix + arrayName;\n var buffer;\n var type;\n var normalization;\n var numComponents;\n var numValues;\n\n if (typeof array === \"number\" || typeof array.data === \"number\") {\n numValues = array.data || array;\n var arrayType = array.type || Float32Array;\n var numBytes = numValues * arrayType.BYTES_PER_ELEMENT;\n type = typedArrays.getGLTypeForTypedArrayType(arrayType);\n normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType);\n numComponents = array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues);\n buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, numBytes, array.drawType || gl.STATIC_DRAW);\n } else {\n var typedArray = makeTypedArray(array, arrayName);\n buffer = createBufferFromTypedArray(gl, typedArray, undefined, array.drawType);\n type = typedArrays.getGLTypeForTypedArray(typedArray);\n normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArray(typedArray);\n numComponents = getNumComponents(array, arrayName);\n numValues = typedArray.length;\n }\n\n attribs[attribName] = {\n buffer: buffer,\n numComponents: numComponents,\n type: type,\n normalize: normalization,\n stride: array.stride || 0,\n offset: array.offset || 0,\n divisor: array.divisor === undefined ? undefined : array.divisor,\n drawType: array.drawType\n };\n }\n });\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n return attribs;\n}\n/**\n * Sets the contents of a buffer attached to an attribInfo\n *\n * This is helper function to dynamically update a buffer.\n *\n * Let's say you make a bufferInfo\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);\n *\n * And you want to dynamically upate the positions. You could do this\n *\n * // assuming arrays.position has already been updated with new data.\n * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position);\n *\n * @param {WebGLRenderingContext} gl\n * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix\n * the name of the attribute will include the prefix.\n * @param {ArraySpec} array Note: it is arguably ineffient to pass in anything but a typed array because anything\n * else will have to be converted to a typed array before it can be used by WebGL. During init time that\n * inefficiency is usually not important but if you're updating data dynamically best to be efficient.\n * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer\n * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView`\n * for the portion of the array you want to use.\n *\n * var someArray = new Float32Array(1000); // an array with 1000 floats\n * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray\n *\n * Now you can pass `someSubArray` into setAttribInfoBufferFromArray`\n * @memberOf module:twgl/attributes\n */\n\n\nfunction setAttribInfoBufferFromArray(gl, attribInfo, array, offset) {\n array = makeTypedArray(array);\n\n if (offset !== undefined) {\n gl.bindBuffer(gl.ARRAY_BUFFER, attribInfo.buffer);\n gl.bufferSubData(gl.ARRAY_BUFFER, offset, array);\n } else {\n setBufferFromTypedArray(gl, gl.ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType);\n }\n}\n\nfunction getBytesPerValueForGLType(gl, type) {\n if (type === gl.BYTE) return 1; // eslint-disable-line\n\n if (type === gl.UNSIGNED_BYTE) return 1; // eslint-disable-line\n\n if (type === gl.SHORT) return 2; // eslint-disable-line\n\n if (type === gl.UNSIGNED_SHORT) return 2; // eslint-disable-line\n\n if (type === gl.INT) return 4; // eslint-disable-line\n\n if (type === gl.UNSIGNED_INT) return 4; // eslint-disable-line\n\n if (type === gl.FLOAT) return 4; // eslint-disable-line\n\n return 0;\n}\n/**\n * tries to get the number of elements from a set of arrays.\n */\n\n\nvar positionKeys = ['position', 'positions', 'a_position'];\n\nfunction getNumElementsFromNonIndexedArrays(arrays) {\n var key;\n\n for (var _ii = 0; _ii < positionKeys.length; ++_ii) {\n key = positionKeys[_ii];\n\n if (key in arrays) {\n break;\n }\n }\n\n if (ii === positionKeys.length) {\n key = Object.keys(arrays)[0];\n }\n\n var array = arrays[key];\n var length = getArray(array).length;\n var numComponents = getNumComponents(array, key);\n var numElements = length / numComponents;\n\n if (length % numComponents > 0) {\n throw \"numComponents \" + numComponents + \" not correct for length \" + length;\n }\n\n return numElements;\n}\n\nfunction getNumElementsFromAttributes(gl, attribs) {\n var key;\n var ii;\n\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n\n if (key in attribs) {\n break;\n }\n\n key = defaults.attribPrefix + key;\n\n if (key in attribs) {\n break;\n }\n }\n\n if (ii === positionKeys.length) {\n key = Object.keys(attribs)[0];\n }\n\n var attrib = attribs[key];\n gl.bindBuffer(gl.ARRAY_BUFFER, attrib.buffer);\n var numBytes = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE);\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n var bytesPerValue = getBytesPerValueForGLType(gl, attrib.type);\n var totalElements = numBytes / bytesPerValue;\n var numComponents = attrib.numComponents || attrib.size; // TODO: check stride\n\n var numElements = totalElements / numComponents;\n\n if (numElements % 1 !== 0) {\n throw \"numComponents \" + numComponents + \" not correct for length \" + length;\n }\n\n return numElements;\n}\n/**\n * @typedef {Object} BufferInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist.\n * @property {Object.} [attribs] The attribs approriate to call `setAttributes`\n * @memberOf module:twgl\n */\n\n/**\n * Creates a BufferInfo from an object of arrays.\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * Given an object like\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * Creates an BufferInfo like this\n *\n * bufferInfo = {\n * numElements: 4, // or whatever the number of elements is\n * indices: WebGLBuffer, // this property will not exist if there are no indices\n * attribs: {\n * a_position: { buffer: WebGLBuffer, numComponents: 3, },\n * a_normal: { buffer: WebGLBuffer, numComponents: 3, },\n * a_texcoord: { buffer: WebGLBuffer, numComponents: 2, },\n * },\n * };\n *\n * The properties of arrays can be JavaScript arrays in which case the number of components\n * will be guessed.\n *\n * var arrays = {\n * position: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0],\n * texcoord: [0, 0, 0, 1, 1, 0, 1, 1],\n * normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],\n * indices: [0, 1, 2, 1, 2, 3],\n * };\n *\n * They can also by TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n *\n * Or augmentedTypedArrays\n *\n * var positions = createAugmentedTypedArray(3, 4);\n * var texcoords = createAugmentedTypedArray(2, 4);\n * var normals = createAugmentedTypedArray(3, 4);\n * var indices = createAugmentedTypedArray(3, 2, Uint16Array);\n *\n * positions.push([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]);\n * texcoords.push([0, 0, 0, 1, 1, 0, 1, 1]);\n * normals.push([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);\n * indices.push([0, 1, 2, 1, 2, 3]);\n *\n * var arrays = {\n * position: positions,\n * texcoord: texcoords,\n * normal: normals,\n * indices: indices,\n * };\n *\n * For the last example it is equivalent to\n *\n * var bufferInfo = {\n * attribs: {\n * a_position: { numComponents: 3, buffer: gl.createBuffer(), },\n * a_texcoods: { numComponents: 2, buffer: gl.createBuffer(), },\n * a_normals: { numComponents: 3, buffer: gl.createBuffer(), },\n * },\n * indices: gl.createBuffer(),\n * numElements: 6,\n * };\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.a_position.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.a_texcoord.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.a_normal.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.normal, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.indices);\n * gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, arrays.indices, gl.STATIC_DRAW);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.Arrays} arrays Your data\n * @return {module:twgl.BufferInfo} A BufferInfo\n * @memberOf module:twgl/attributes\n */\n\n\nfunction createBufferInfoFromArrays(gl, arrays) {\n var bufferInfo = {\n attribs: createAttribsFromArrays(gl, arrays)\n };\n var indices = arrays.indices;\n\n if (indices) {\n var newIndices = makeTypedArray(indices, \"indices\");\n bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, gl.ELEMENT_ARRAY_BUFFER);\n bufferInfo.numElements = newIndices.length;\n bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices);\n } else {\n bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs);\n }\n\n return bufferInfo;\n}\n/**\n * Creates a buffer from an array, typed array, or array spec\n *\n * Given something like this\n *\n * [1, 2, 3],\n *\n * or\n *\n * new Uint16Array([1,2,3]);\n *\n * or\n *\n * {\n * data: [1, 2, 3],\n * type: Uint8Array,\n * }\n *\n * returns a WebGLBuffer that constains the given data.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.ArraySpec} array an array, typed array, or array spec.\n * @param {string} arrayName name of array. Used to guess the type if type can not be dervied other wise.\n * @return {WebGLBuffer} a WebGLBuffer containing the data in array.\n * @memberOf module:twgl/attributes\n */\n\n\nfunction createBufferFromArray(gl, array, arrayName) {\n var type = arrayName === \"indices\" ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;\n var typedArray = makeTypedArray(array, arrayName);\n return createBufferFromTypedArray(gl, typedArray, type);\n}\n/**\n * Creates buffers from arrays or typed arrays\n *\n * Given something like this\n *\n * var arrays = {\n * positions: [1, 2, 3],\n * normals: [0, 0, 1],\n * }\n *\n * returns something like\n *\n * buffers = {\n * positions: WebGLBuffer,\n * normals: WebGLBuffer,\n * }\n *\n * If the buffer is named 'indices' it will be made an ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.Arrays} arrays\n * @return {Object} returns an object with one WebGLBuffer per array\n * @memberOf module:twgl/attributes\n */\n\n\nfunction createBuffersFromArrays(gl, arrays) {\n var buffers = {};\n Object.keys(arrays).forEach(function (key) {\n buffers[key] = createBufferFromArray(gl, arrays[key], key);\n }); // Ugh!\n\n if (arrays.indices) {\n buffers.numElements = arrays.indices.length;\n buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices');\n } else {\n buffers.numElements = getNumElementsFromNonIndexedArrays(arrays);\n }\n\n return buffers;\n}\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.setTextureDefaults_ = setDefaults;\nexports.createSampler = createSampler;\nexports.createSamplers = createSamplers;\nexports.setSamplerParameters = setSamplerParameters;\nexports.createTexture = createTexture;\nexports.setEmptyTexture = setEmptyTexture;\nexports.setTextureFromArray = setTextureFromArray;\nexports.loadTextureFromUrl = loadTextureFromUrl;\nexports.setTextureFromElement = setTextureFromElement;\nexports.setTextureFilteringForSize = setTextureFilteringForSize;\nexports.setTextureParameters = setTextureParameters;\nexports.setDefaultTextureColor = setDefaultTextureColor;\nexports.createTextures = createTextures;\nexports.resizeTexture = resizeTexture;\nexports.getNumComponentsForFormat = getNumComponentsForFormat;\nexports.getBytesPerElementForInternalFormat = getBytesPerElementForInternalFormat;\n\nvar utils = _interopRequireWildcard(__webpack_require__(4));\n\nvar typedArrays = _interopRequireWildcard(__webpack_require__(1));\n\nvar helper = _interopRequireWildcard(__webpack_require__(0));\n\nvar _globalObject = _interopRequireDefault(__webpack_require__(2));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * Low level texture related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibily they are available at both `twgl.textures` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/textures\n */\n// make sure we don't see a global gl\nvar gl = undefined; // eslint-disable-line\n\nvar defaults = {\n textureColor: new Uint8Array([128, 192, 255, 255]),\n textureOptions: {},\n crossOrigin: undefined\n};\nvar isArrayBuffer = typedArrays.isArrayBuffer; // Should we make this on demand?\n\nvar ctx = _globalObject.default.document && _globalObject.default.document.createElement ? _globalObject.default.document.createElement(\"canvas\").getContext(\"2d\") : null; // NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but\n// not only does Firefox NOT support it but Firefox freezes immediately\n// if you try to create one instead of just returning null and continuing.\n// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext(\"2d\")); // OffscreenCanvas may not support 2d\n// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2\n// we can use the various unpack settings. Otherwise we could try using\n// the ability of an imagebitmap to be cut. Unfortunately cutting an imagebitmap\n// is async and the current TWGL code expects a non-Async result though that\n// might not be a problem. ImageBitmap though is not available in Edge or Safari\n// as of 2018-01-02\n\n/* PixelFormat */\n\nvar ALPHA = 0x1906;\nvar RGB = 0x1907;\nvar RGBA = 0x1908;\nvar LUMINANCE = 0x1909;\nvar LUMINANCE_ALPHA = 0x190A;\nvar DEPTH_COMPONENT = 0x1902;\nvar DEPTH_STENCIL = 0x84F9;\n/* TextureWrapMode */\n\nvar REPEAT = 0x2901; // eslint-disable-line\n\nvar MIRRORED_REPEAT = 0x8370; // eslint-disable-line\n\n/* TextureMagFilter */\n\nvar NEAREST = 0x2600; // eslint-disable-line\n\n/* TextureMinFilter */\n\nvar NEAREST_MIPMAP_NEAREST = 0x2700; // eslint-disable-line\n\nvar LINEAR_MIPMAP_NEAREST = 0x2701; // eslint-disable-line\n\nvar NEAREST_MIPMAP_LINEAR = 0x2702; // eslint-disable-line\n\nvar LINEAR_MIPMAP_LINEAR = 0x2703; // eslint-disable-line\n\nvar R8 = 0x8229;\nvar R8_SNORM = 0x8F94;\nvar R16F = 0x822D;\nvar R32F = 0x822E;\nvar R8UI = 0x8232;\nvar R8I = 0x8231;\nvar RG16UI = 0x823A;\nvar RG16I = 0x8239;\nvar RG32UI = 0x823C;\nvar RG32I = 0x823B;\nvar RG8 = 0x822B;\nvar RG8_SNORM = 0x8F95;\nvar RG16F = 0x822F;\nvar RG32F = 0x8230;\nvar RG8UI = 0x8238;\nvar RG8I = 0x8237;\nvar R16UI = 0x8234;\nvar R16I = 0x8233;\nvar R32UI = 0x8236;\nvar R32I = 0x8235;\nvar RGB8 = 0x8051;\nvar SRGB8 = 0x8C41;\nvar RGB565 = 0x8D62;\nvar RGB8_SNORM = 0x8F96;\nvar R11F_G11F_B10F = 0x8C3A;\nvar RGB9_E5 = 0x8C3D;\nvar RGB16F = 0x881B;\nvar RGB32F = 0x8815;\nvar RGB8UI = 0x8D7D;\nvar RGB8I = 0x8D8F;\nvar RGB16UI = 0x8D77;\nvar RGB16I = 0x8D89;\nvar RGB32UI = 0x8D71;\nvar RGB32I = 0x8D83;\nvar RGBA8 = 0x8058;\nvar SRGB8_ALPHA8 = 0x8C43;\nvar RGBA8_SNORM = 0x8F97;\nvar RGB5_A1 = 0x8057;\nvar RGBA4 = 0x8056;\nvar RGB10_A2 = 0x8059;\nvar RGBA16F = 0x881A;\nvar RGBA32F = 0x8814;\nvar RGBA8UI = 0x8D7C;\nvar RGBA8I = 0x8D8E;\nvar RGB10_A2UI = 0x906F;\nvar RGBA16UI = 0x8D76;\nvar RGBA16I = 0x8D88;\nvar RGBA32I = 0x8D82;\nvar RGBA32UI = 0x8D70;\nvar DEPTH_COMPONENT16 = 0x81A5;\nvar DEPTH_COMPONENT24 = 0x81A6;\nvar DEPTH_COMPONENT32F = 0x8CAC;\nvar DEPTH32F_STENCIL8 = 0x8CAD;\nvar DEPTH24_STENCIL8 = 0x88F0;\n/* DataType */\n\nvar BYTE = 0x1400;\nvar UNSIGNED_BYTE = 0x1401;\nvar SHORT = 0x1402;\nvar UNSIGNED_SHORT = 0x1403;\nvar INT = 0x1404;\nvar UNSIGNED_INT = 0x1405;\nvar FLOAT = 0x1406;\nvar UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nvar UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nvar UNSIGNED_SHORT_5_6_5 = 0x8363;\nvar HALF_FLOAT = 0x140B;\nvar HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:(\n\nvar UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nvar UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nvar UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nvar FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nvar UNSIGNED_INT_24_8 = 0x84FA;\nvar RG = 0x8227;\nvar RG_INTEGER = 0x8228;\nvar RED = 0x1903;\nvar RED_INTEGER = 0x8D94;\nvar RGB_INTEGER = 0x8D98;\nvar RGBA_INTEGER = 0x8D99;\nvar formatInfo = {};\n{\n // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle\n // the name.\n var f = formatInfo;\n f[ALPHA] = {\n numColorComponents: 1\n };\n f[LUMINANCE] = {\n numColorComponents: 1\n };\n f[LUMINANCE_ALPHA] = {\n numColorComponents: 2\n };\n f[RGB] = {\n numColorComponents: 3\n };\n f[RGBA] = {\n numColorComponents: 4\n };\n f[RED] = {\n numColorComponents: 1\n };\n f[RED_INTEGER] = {\n numColorComponents: 1\n };\n f[RG] = {\n numColorComponents: 2\n };\n f[RG_INTEGER] = {\n numColorComponents: 2\n };\n f[RGB] = {\n numColorComponents: 3\n };\n f[RGB_INTEGER] = {\n numColorComponents: 3\n };\n f[RGBA] = {\n numColorComponents: 4\n };\n f[RGBA_INTEGER] = {\n numColorComponents: 4\n };\n f[DEPTH_COMPONENT] = {\n numColorComponents: 1\n };\n f[DEPTH_STENCIL] = {\n numColorComponents: 2\n };\n}\nvar textureInternalFormatInfo = {};\n{\n // NOTE: these properties need unique names so we can let Uglify mangle the name.\n var t = textureInternalFormatInfo; // unsized formats\n\n t[ALPHA] = {\n textureFormat: ALPHA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [1, 2, 2, 4],\n type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT]\n };\n t[LUMINANCE] = {\n textureFormat: LUMINANCE,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [1, 2, 2, 4],\n type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT]\n };\n t[LUMINANCE_ALPHA] = {\n textureFormat: LUMINANCE_ALPHA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [2, 4, 4, 8],\n type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT]\n };\n t[RGB] = {\n textureFormat: RGB,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [3, 6, 6, 12, 2],\n type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5]\n };\n t[RGBA] = {\n textureFormat: RGBA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [4, 8, 8, 16, 2, 2],\n type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1]\n }; // sized formats\n\n t[R8] = {\n textureFormat: RED,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: 1,\n type: UNSIGNED_BYTE\n };\n t[R8_SNORM] = {\n textureFormat: RED,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: 1,\n type: BYTE\n };\n t[R16F] = {\n textureFormat: RED,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: [4, 2],\n type: [FLOAT, HALF_FLOAT]\n };\n t[R32F] = {\n textureFormat: RED,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 4,\n type: FLOAT\n };\n t[R8UI] = {\n textureFormat: RED_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 1,\n type: UNSIGNED_BYTE\n };\n t[R8I] = {\n textureFormat: RED_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 1,\n type: BYTE\n };\n t[R16UI] = {\n textureFormat: RED_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 2,\n type: UNSIGNED_SHORT\n };\n t[R16I] = {\n textureFormat: RED_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 2,\n type: SHORT\n };\n t[R32UI] = {\n textureFormat: RED_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: UNSIGNED_INT\n };\n t[R32I] = {\n textureFormat: RED_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: INT\n };\n t[RG8] = {\n textureFormat: RG,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: 2,\n type: UNSIGNED_BYTE\n };\n t[RG8_SNORM] = {\n textureFormat: RG,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: 2,\n type: BYTE\n };\n t[RG16F] = {\n textureFormat: RG,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: [8, 4],\n type: [FLOAT, HALF_FLOAT]\n };\n t[RG32F] = {\n textureFormat: RG,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 8,\n type: FLOAT\n };\n t[RG8UI] = {\n textureFormat: RG_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 2,\n type: UNSIGNED_BYTE\n };\n t[RG8I] = {\n textureFormat: RG_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 2,\n type: BYTE\n };\n t[RG16UI] = {\n textureFormat: RG_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: UNSIGNED_SHORT\n };\n t[RG16I] = {\n textureFormat: RG_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: SHORT\n };\n t[RG32UI] = {\n textureFormat: RG_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 8,\n type: UNSIGNED_INT\n };\n t[RG32I] = {\n textureFormat: RG_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 8,\n type: INT\n };\n t[RGB8] = {\n textureFormat: RGB,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: 3,\n type: UNSIGNED_BYTE\n };\n t[SRGB8] = {\n textureFormat: RGB,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: 3,\n type: UNSIGNED_BYTE\n };\n t[RGB565] = {\n textureFormat: RGB,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [3, 2],\n type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5]\n };\n t[RGB8_SNORM] = {\n textureFormat: RGB,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: 3,\n type: BYTE\n };\n t[R11F_G11F_B10F] = {\n textureFormat: RGB,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: [12, 6, 4],\n type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV]\n };\n t[RGB9_E5] = {\n textureFormat: RGB,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: [12, 6, 4],\n type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV]\n };\n t[RGB16F] = {\n textureFormat: RGB,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: [12, 6],\n type: [FLOAT, HALF_FLOAT]\n };\n t[RGB32F] = {\n textureFormat: RGB,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 12,\n type: FLOAT\n };\n t[RGB8UI] = {\n textureFormat: RGB_INTEGER,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 3,\n type: UNSIGNED_BYTE\n };\n t[RGB8I] = {\n textureFormat: RGB_INTEGER,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 3,\n type: BYTE\n };\n t[RGB16UI] = {\n textureFormat: RGB_INTEGER,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 6,\n type: UNSIGNED_SHORT\n };\n t[RGB16I] = {\n textureFormat: RGB_INTEGER,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 6,\n type: SHORT\n };\n t[RGB32UI] = {\n textureFormat: RGB_INTEGER,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 12,\n type: UNSIGNED_INT\n };\n t[RGB32I] = {\n textureFormat: RGB_INTEGER,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 12,\n type: INT\n };\n t[RGBA8] = {\n textureFormat: RGBA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: 4,\n type: UNSIGNED_BYTE\n };\n t[SRGB8_ALPHA8] = {\n textureFormat: RGBA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: 4,\n type: UNSIGNED_BYTE\n };\n t[RGBA8_SNORM] = {\n textureFormat: RGBA,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: 4,\n type: BYTE\n };\n t[RGB5_A1] = {\n textureFormat: RGBA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [4, 2, 4],\n type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV]\n };\n t[RGBA4] = {\n textureFormat: RGBA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: [4, 2],\n type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4]\n };\n t[RGB10_A2] = {\n textureFormat: RGBA,\n colorRenderable: true,\n textureFilterable: true,\n bytesPerElement: 4,\n type: UNSIGNED_INT_2_10_10_10_REV\n };\n t[RGBA16F] = {\n textureFormat: RGBA,\n colorRenderable: false,\n textureFilterable: true,\n bytesPerElement: [16, 8],\n type: [FLOAT, HALF_FLOAT]\n };\n t[RGBA32F] = {\n textureFormat: RGBA,\n colorRenderable: false,\n textureFilterable: false,\n bytesPerElement: 16,\n type: FLOAT\n };\n t[RGBA8UI] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: UNSIGNED_BYTE\n };\n t[RGBA8I] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: BYTE\n };\n t[RGB10_A2UI] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: UNSIGNED_INT_2_10_10_10_REV\n };\n t[RGBA16UI] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 8,\n type: UNSIGNED_SHORT\n };\n t[RGBA16I] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 8,\n type: SHORT\n };\n t[RGBA32I] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 16,\n type: INT\n };\n t[RGBA32UI] = {\n textureFormat: RGBA_INTEGER,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 16,\n type: UNSIGNED_INT\n }; // Sized Internal\n\n t[DEPTH_COMPONENT16] = {\n textureFormat: DEPTH_COMPONENT,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: [2, 4],\n type: [UNSIGNED_SHORT, UNSIGNED_INT]\n };\n t[DEPTH_COMPONENT24] = {\n textureFormat: DEPTH_COMPONENT,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: UNSIGNED_INT\n };\n t[DEPTH_COMPONENT32F] = {\n textureFormat: DEPTH_COMPONENT,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: FLOAT\n };\n t[DEPTH24_STENCIL8] = {\n textureFormat: DEPTH_STENCIL,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: UNSIGNED_INT_24_8\n };\n t[DEPTH32F_STENCIL8] = {\n textureFormat: DEPTH_STENCIL,\n colorRenderable: true,\n textureFilterable: false,\n bytesPerElement: 4,\n type: FLOAT_32_UNSIGNED_INT_24_8_REV\n };\n Object.keys(t).forEach(function (internalFormat) {\n var info = t[internalFormat];\n info.bytesPerElementMap = {};\n\n if (Array.isArray(info.bytesPerElement)) {\n info.bytesPerElement.forEach(function (bytesPerElement, ndx) {\n var type = info.type[ndx];\n info.bytesPerElementMap[type] = bytesPerElement;\n });\n } else {\n var type = info.type;\n info.bytesPerElementMap[type] = info.bytesPerElement;\n }\n });\n}\n/**\n * Gets the number of bytes per element for a given internalFormat / type\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @param {number} type The type parameter for texImage2D etc..\n * @return {number} the number of bytes per element for the given internalFormat, type combo\n * @memberOf module:twgl/textures\n */\n\nfunction getBytesPerElementForInternalFormat(internalFormat, type) {\n var info = textureInternalFormatInfo[internalFormat];\n\n if (!info) {\n throw \"unknown internal format\";\n }\n\n var bytesPerElement = info.bytesPerElementMap[type];\n\n if (bytesPerElement === undefined) {\n throw \"unknown internal format\";\n }\n\n return bytesPerElement;\n}\n/**\n * Gets the format for a given internalFormat\n *\n * @param {number} internalFormat The internal format\n * @return {{format:number, type:number}} the corresponding format and type\n */\n\n\nfunction getFormatAndTypeForInternalFormat(internalFormat) {\n var info = textureInternalFormatInfo[internalFormat];\n\n if (!info) {\n throw \"unknown internal format\";\n }\n\n return {\n format: info.textureFormat,\n type: Array.isArray(info.type) ? info.type[0] : info.type\n };\n}\n/**\n * Returns true if value is power of 2\n * @param {number} value number to check.\n * @return true if value is power of 2\n */\n\n\nfunction isPowerOf2(value) {\n return (value & value - 1) === 0;\n}\n/**\n * Gets whether or not we can generate mips for the given format\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @param {number} type The type parameter for texImage2D etc..\n * @return {boolean} true if we can generate mips\n */\n\n\nfunction canGenerateMipmap(gl, width, height, internalFormat\n/*, type */\n) {\n if (!utils.isWebGL2(gl)) {\n return isPowerOf2(width) && isPowerOf2(height);\n }\n\n var info = textureInternalFormatInfo[internalFormat];\n\n if (!info) {\n throw \"unknown internal format\";\n }\n\n return info.colorRenderable && info.textureFilterable;\n}\n/**\n * Gets whether or not we can generate mips for the given format\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @param {number} type The type parameter for texImage2D etc..\n * @return {boolean} true if we can generate mips\n */\n\n\nfunction canFilter(internalFormat\n/*, type */\n) {\n var info = textureInternalFormatInfo[internalFormat];\n\n if (!info) {\n throw \"unknown internal format\";\n }\n\n return info.textureFilterable;\n}\n/**\n * Gets the number of compontents for a given image format.\n * @param {number} format the format.\n * @return {number} the number of components for the format.\n * @memberOf module:twgl/textures\n */\n\n\nfunction getNumComponentsForFormat(format) {\n var info = formatInfo[format];\n\n if (!info) {\n throw \"unknown format: \" + format;\n }\n\n return info.numColorComponents;\n}\n/**\n * Gets the texture type for a given array type.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @return {number} the gl texture type\n */\n\n\nfunction getTextureTypeForArrayType(gl, src, defaultType) {\n if (isArrayBuffer(src)) {\n return typedArrays.getGLTypeForTypedArray(src);\n }\n\n return defaultType || gl.UNSIGNED_BYTE;\n}\n\nfunction guessDimensions(gl, target, width, height, numElements) {\n if (numElements % 1 !== 0) {\n throw \"can't guess dimensions\";\n }\n\n if (!width && !height) {\n var size = Math.sqrt(numElements / (target === gl.TEXTURE_CUBE_MAP ? 6 : 1));\n\n if (size % 1 === 0) {\n width = size;\n height = size;\n } else {\n width = numElements;\n height = 1;\n }\n } else if (!height) {\n height = numElements / width;\n\n if (height % 1) {\n throw \"can't guess dimensions\";\n }\n } else if (!width) {\n width = numElements / height;\n\n if (width % 1) {\n throw \"can't guess dimensions\";\n }\n }\n\n return {\n width: width,\n height: height\n };\n}\n/**\n * Sets the default texture color.\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * @param {number[]} color Array of 4 values in the range 0 to 1\n * @deprecated see {@link module:twgl.setDefaults}\n * @memberOf module:twgl/textures\n */\n\n\nfunction setDefaultTextureColor(color) {\n defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n\n if (newDefaults.textureColor) {\n setDefaultTextureColor(newDefaults.textureColor);\n }\n}\n/**\n * A function to generate the source for a texture.\n * @callback TextureFunc\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options the texture options\n * @return {*} Returns any of the things documentented for `src` for {@link module:twgl.TextureOptions}.\n * @memberOf module:twgl\n */\n\n/**\n * Texture options passed to most texture functions. Each function will use whatever options\n * are appropriate for its needs. This lets you pass the same options to all functions.\n *\n * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`,\n * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`.\n *\n * @typedef {Object} TextureOptions\n * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`.\n * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true.\n * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null.\n * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null.\n * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` .\n * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR`\n * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`.\n * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR`\n * @property {number} [minMag] both the min and mag filter settings.\n * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA`\n * @property {number} [format] format for texture. Defaults to `gl.RGBA`.\n * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src`\n * is ArrayBufferView defaults to type that matches ArrayBufferView type.\n * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube\n * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [minLod] TEXTURE_MIN_LOD setting\n * @property {number} [maxLod] TEXTURE_MAX_LOD setting\n * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting\n * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting\n * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1.\n * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {(number[]|ArrayBufferView)} color color used as temporary 1x1 pixel color for textures loaded async when src is a string.\n * If it's a JavaScript array assumes color is 0 to 1 like most GL colors as in `[1, 0, 0, 1] = red=1, green=0, blue=0, alpha=0`.\n * Defaults to `[0.5, 0.75, 1, 1]`. See {@link module:twgl.setDefaultTextureColor}. If `false` texture is set. Can be used to re-load a texture\n * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and\n * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above\n * then then `auto` is assumed to be `false` unless explicity set to `true`.\n * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is\n *\n * [gl.TEXTURE_CUBE_MAP_POSITIVE_X,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]\n *\n * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture\n *\n * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable\n * 1x1 pixel texture will be returned immediatley. The texture will be updated once the image has downloaded.\n * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3.\n * The pieces will be uploaded in `cubeFaceOrder`\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map.\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then eact entry is a slice of the a 2d array texture\n * and will be scaled to the specified width and height OR to the size of the first image that loads.\n *\n * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`,\n * `HTMLCanvasElement`, `HTMLVideoElement`.\n *\n * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is\n * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents`\n * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided\n * by 6. Then\n *\n * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height\n * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`.\n *\n * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`.\n *\n * If `number[]` will be converted to `type`.\n *\n * If `src` is a function it will be called with a `WebGLRenderingContext` and these options.\n * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement`\n * an array etc...\n *\n * If `src` is undefined then an empty texture will be created of size `width` by `height`.\n *\n * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded.\n * default: undefined. Also see {@link module:twgl.setDefaults}.\n *\n * @memberOf module:twgl\n */\n// NOTE: While querying GL is considered slow it's not remotely as slow\n// as uploading a texture. On top of that you're unlikely to call this in\n// a perf critical loop. Even if upload a texture every frame that's unlikely\n// to be more than 1 or 2 textures a frame. In other words, the benefits of\n// making the API easy to use outweigh any supposed perf benefits\n//\n// Also note I get that having one global of these is bad practice.\n// As long as it's used correctly it means no garbage which probably\n// doesn't matter when dealing with textures but old habits die hard.\n\n\nvar lastPackState = {};\n/**\n * Saves any packing state that will be set based on the options.\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n */\n\nfunction savePackState(gl, options) {\n if (options.colorspaceConversion !== undefined) {\n lastPackState.colorspaceConversion = gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL);\n gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion);\n }\n\n if (options.premultiplyAlpha !== undefined) {\n lastPackState.premultiplyAlpha = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha);\n }\n\n if (options.flipY !== undefined) {\n lastPackState.flipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, options.flipY);\n }\n}\n/**\n * Restores any packing state that was set based on the options.\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n */\n\n\nfunction restorePackState(gl, options) {\n if (options.colorspaceConversion !== undefined) {\n gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, lastPackState.colorspaceConversion);\n }\n\n if (options.premultiplyAlpha !== undefined) {\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, lastPackState.premultiplyAlpha);\n }\n\n if (options.flipY !== undefined) {\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, lastPackState.flipY);\n }\n}\n/**\n * Saves state related to data size\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n */\n\n\nfunction saveSkipState(gl) {\n lastPackState.unpackAlignment = gl.getParameter(gl.UNPACK_ALIGNMENT);\n\n if (utils.isWebGL2(gl)) {\n lastPackState.unpackRowLength = gl.getParameter(gl.UNPACK_ROW_LENGTH);\n lastPackState.unpackImageHeight = gl.getParameter(gl.UNPACK_IMAGE_HEIGHT);\n lastPackState.unpackSkipPixels = gl.getParameter(gl.UNPACK_SKIP_PIXELS);\n lastPackState.unpackSkipRows = gl.getParameter(gl.UNPACK_SKIP_ROWS);\n lastPackState.unpackSkipImages = gl.getParameter(gl.UNPACK_SKIP_IMAGES);\n }\n}\n/**\n * Restores state related to data size\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n */\n\n\nfunction restoreSkipState(gl) {\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, lastPackState.unpackAlignment);\n\n if (utils.isWebGL2(gl)) {\n gl.pixelStorei(gl.UNPACK_ROW_LENGTH, lastPackState.unpackRowLength);\n gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, lastPackState.unpackImageHeight);\n gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, lastPackState.unpackSkipPixels);\n gl.pixelStorei(gl.UNPACK_SKIP_ROWS, lastPackState.unpackSkipRows);\n gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, lastPackState.unpackSkipImages);\n }\n}\n/**\n * Sets the parameters of a texture or sampler\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number|WebGLSampler} target texture target or sampler\n * @param {function()} parameteriFn texParamteri or samplerParameteri fn\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n */\n\n\nfunction setTextureSamplerParameters(gl, target, parameteriFn, options) {\n if (options.minMag) {\n parameteriFn.call(gl, target, gl.TEXTURE_MIN_FILTER, options.minMag);\n parameteriFn.call(gl, target, gl.TEXTURE_MAG_FILTER, options.minMag);\n }\n\n if (options.min) {\n parameteriFn.call(gl, target, gl.TEXTURE_MIN_FILTER, options.min);\n }\n\n if (options.mag) {\n parameteriFn.call(gl, target, gl.TEXTURE_MAG_FILTER, options.mag);\n }\n\n if (options.wrap) {\n parameteriFn.call(gl, target, gl.TEXTURE_WRAP_S, options.wrap);\n parameteriFn.call(gl, target, gl.TEXTURE_WRAP_T, options.wrap);\n\n if (target === gl.TEXTURE_3D || helper.isSampler(gl, target)) {\n parameteriFn.call(gl, target, gl.TEXTURE_WRAP_R, options.wrap);\n }\n }\n\n if (options.wrapR) {\n parameteriFn.call(gl, target, gl.TEXTURE_WRAP_R, options.wrapR);\n }\n\n if (options.wrapS) {\n parameteriFn.call(gl, target, gl.TEXTURE_WRAP_S, options.wrapS);\n }\n\n if (options.wrapT) {\n parameteriFn.call(gl, target, gl.TEXTURE_WRAP_T, options.wrapT);\n }\n\n if (options.minLod) {\n parameteriFn.call(gl, target, gl.TEXTURE_MIN_LOD, options.minLod);\n }\n\n if (options.maxLod) {\n parameteriFn.call(gl, target, gl.TEXTURE_MAX_LOD, options.maxLod);\n }\n\n if (options.baseLevel) {\n parameteriFn.call(gl, target, gl.TEXTURE_BASE_LEVEL, options.baseLevel);\n }\n\n if (options.maxLevel) {\n parameteriFn.call(gl, target, gl.TEXTURE_MAX_LEVEL, options.maxLevel);\n }\n}\n/**\n * Sets the texture parameters of a texture.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\n\n\nfunction setTextureParameters(gl, tex, options) {\n var target = options.target || gl.TEXTURE_2D;\n gl.bindTexture(target, tex);\n setTextureSamplerParameters(gl, target, gl.texParameteri, options);\n}\n/**\n * Sets the sampler parameters of a sampler.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLSampler} sampler the WebGLSampler to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\n\n\nfunction setSamplerParameters(gl, sampler, options) {\n setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options);\n}\n/**\n * Creates a new sampler object and sets parameters.\n *\n * Example:\n *\n * const sampler = twgl.createSampler(gl, {\n * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER\n * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per sampler.\n * @return {Object.} the created samplers by name\n */\n\n\nfunction createSampler(gl, options) {\n var sampler = gl.createSampler();\n setSamplerParameters(gl, sampler, options);\n return sampler;\n}\n/**\n * Creates a multiple sampler objects and sets parameters on each.\n *\n * Example:\n *\n * const samplers = twgl.createSamplers(gl, {\n * nearest: {\n * minMag: gl.NEAREST,\n * },\n * nearestClampS: {\n * minMag: gl.NEAREST,\n * wrapS: gl.CLAMP_TO_NEAREST,\n * },\n * linear: {\n * minMag: gl.LINEAR,\n * },\n * nearestClamp: {\n * minMag: gl.NEAREST,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClamp: {\n * minMag: gl.LINEAR,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClampT: {\n * minMag: gl.LINEAR,\n * wrapT: gl.CLAMP_TO_EDGE,\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler\n */\n\n\nfunction createSamplers(gl, samplerOptions) {\n var samplers = {};\n Object.keys(samplerOptions).forEach(function (name) {\n samplers[name] = createSampler(gl, samplerOptions[name]);\n });\n return samplers;\n}\n/**\n * Makes a 1x1 pixel\n * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`.\n * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values\n * @return {Uint8Array} Unit8Array with color.\n */\n\n\nfunction make1Pixel(color) {\n color = color || defaults.textureColor;\n\n if (isArrayBuffer(color)) {\n return color;\n }\n\n return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n/**\n * Sets filtering or generates mips for texture based on width or height\n * If width or height is not passed in uses `options.width` and//or `options.height`\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @param {number} [width] width of texture\n * @param {number} [height] height of texture\n * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc..\n * @param {number} [type] The type parameter for texImage2D etc..\n * @memberOf module:twgl/textures\n */\n\n\nfunction setTextureFilteringForSize(gl, tex, options, width, height, internalFormat, type) {\n options = options || defaults.textureOptions;\n internalFormat = internalFormat || gl.RGBA;\n type = type || gl.UNSIGNED_BYTE;\n var target = options.target || gl.TEXTURE_2D;\n width = width || options.width;\n height = height || options.height;\n gl.bindTexture(target, tex);\n\n if (canGenerateMipmap(gl, width, height, internalFormat, type)) {\n gl.generateMipmap(target);\n } else {\n var filtering = canFilter(internalFormat, type) ? gl.LINEAR : gl.NEAREST;\n gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, filtering);\n gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, filtering);\n gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n }\n}\n\nfunction shouldAutomaticallySetTextureFilteringForSize(options) {\n return options.auto === true || options.auto === undefined && options.level === undefined;\n}\n/**\n * Gets an array of cubemap face enums\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @return {number[]} cubemap face enums\n */\n\n\nfunction getCubeFaceOrder(gl, options) {\n options = options || {};\n return options.cubeFaceOrder || [gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];\n}\n/**\n * @typedef {Object} FaceInfo\n * @property {number} face gl enum for texImage2D\n * @property {number} ndx face index (0 - 5) into source data\n * @ignore\n */\n\n/**\n * Gets an array of FaceInfos\n * There's a bug in some NVidia drivers that will crash the driver if\n * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take\n * the user's desired order from his faces to WebGL and make sure we\n * do the faces in WebGL order\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundent but\n * it's needed internally to sort the array of `ndx` properties by `face`.\n */\n\n\nfunction getCubeFacesWithNdx(gl, options) {\n var faces = getCubeFaceOrder(gl, options); // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :(\n\n var facesWithNdx = faces.map(function (face, ndx) {\n return {\n face: face,\n ndx: ndx\n };\n });\n facesWithNdx.sort(function (a, b) {\n return a.face - b.face;\n });\n return facesWithNdx;\n}\n/**\n * Set a texture from the contents of an element. Will also set\n * texture filtering or generate mips based on the dimensions of the element\n * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will\n * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {HTMLElement} element a canvas, img, or video element.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @kind function\n */\n\n\nfunction setTextureFromElement(gl, tex, element, options) {\n options = options || defaults.textureOptions;\n var target = options.target || gl.TEXTURE_2D;\n var level = options.level || 0;\n var width = element.width;\n var height = element.height;\n var internalFormat = options.internalFormat || options.format || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var format = options.format || formatType.format;\n var type = options.type || formatType.type;\n savePackState(gl, options);\n gl.bindTexture(target, tex);\n\n if (target === gl.TEXTURE_CUBE_MAP) {\n // guess the parts\n var imgWidth = element.width;\n var imgHeight = element.height;\n var size;\n var slices;\n\n if (imgWidth / 6 === imgHeight) {\n // It's 6x1\n size = imgHeight;\n slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0];\n } else if (imgHeight / 6 === imgWidth) {\n // It's 1x6\n size = imgWidth;\n slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5];\n } else if (imgWidth / 3 === imgHeight / 2) {\n // It's 3x2\n size = imgWidth / 3;\n slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1];\n } else if (imgWidth / 2 === imgHeight / 3) {\n // It's 2x3\n size = imgWidth / 2;\n slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2];\n } else {\n throw \"can't figure out cube map from element: \" + (element.src ? element.src : element.nodeName);\n }\n\n if (ctx) {\n ctx.canvas.width = size;\n ctx.canvas.height = size;\n width = size;\n height = size;\n getCubeFacesWithNdx(gl, options).forEach(function (f) {\n var xOffset = slices[f.ndx * 2 + 0] * size;\n var yOffset = slices[f.ndx * 2 + 1] * size;\n ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size);\n gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas);\n }); // Free up the canvas memory\n\n ctx.canvas.width = 1;\n ctx.canvas.height = 1;\n } else if (_globalObject.default.createImageBitmap) {\n // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's\n // note lossy? (alpha is not premultiplied? although I'm not sure what\n width = size;\n height = size;\n getCubeFacesWithNdx(gl, options).forEach(function (f) {\n var xOffset = slices[f.ndx * 2 + 0] * size;\n var yOffset = slices[f.ndx * 2 + 1] * size; // We can't easily use a default texture color here as it would have to match\n // the type across all faces where as with a 2D one there's only one face\n // so we're replacing everything all at once. It also has to be the correct size.\n // On the other hand we need all faces to be the same size so as one face loads\n // the rest match else the texture will be unrenderable.\n\n gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null);\n\n _globalObject.default.createImageBitmap(element, xOffset, yOffset, size, size, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none'\n }).then(function (imageBitmap) {\n savePackState(gl, options);\n gl.bindTexture(target, tex);\n gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap);\n restorePackState(gl, options);\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat, type);\n }\n });\n });\n }\n } else if (target === gl.TEXTURE_3D || target === gl.TEXTURE_2D_ARRAY) {\n var smallest = Math.min(element.width, element.height);\n var largest = Math.max(element.width, element.height);\n var depth = largest / smallest;\n\n if (depth % 1 !== 0) {\n throw \"can not compute 3D dimensions of element\";\n }\n\n var xMult = element.width === largest ? 1 : 0;\n var yMult = element.height === largest ? 1 : 0;\n saveSkipState(gl);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n gl.pixelStorei(gl.UNPACK_ROW_LENGTH, element.width);\n gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);\n gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null);\n\n for (var d = 0; d < depth; ++d) {\n var srcX = d * smallest * xMult;\n var srcY = d * smallest * yMult;\n gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, srcX);\n gl.pixelStorei(gl.UNPACK_SKIP_ROWS, srcY);\n gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element);\n }\n\n restoreSkipState(gl);\n } else {\n gl.texImage2D(target, level, internalFormat, format, type, element);\n }\n\n restorePackState(gl, options);\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat, type);\n }\n\n setTextureParameters(gl, tex, options);\n}\n\nfunction noop() {}\n/**\n * Loads an image\n * @param {string} url url to image\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @return {HTMLImageElement} the image being loaded.\n */\n\n\nfunction loadImage(url, crossOrigin, callback) {\n callback = callback || noop;\n var img;\n\n if (_globalObject.default.Image) {\n img = new _globalObject.default.Image();\n crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin;\n\n if (crossOrigin !== undefined) {\n img.crossOrigin = crossOrigin;\n }\n\n var clearEventHandlers = function clearEventHandlers() {\n img.removeEventListener('error', onError); // eslint-disable-line\n\n img.removeEventListener('load', onLoad); // eslint-disable-line\n\n img = null;\n };\n\n var onError = function onError() {\n var msg = \"couldn't load image: \" + url;\n helper.error(msg);\n callback(msg, img);\n clearEventHandlers();\n };\n\n var onLoad = function onLoad() {\n callback(null, img);\n clearEventHandlers();\n };\n\n img.addEventListener('error', onError);\n img.addEventListener('load', onLoad);\n img.src = url;\n return img;\n } else if (_globalObject.default.ImageBitmap) {\n var err;\n var bm;\n\n var cb = function cb() {\n callback(err, bm);\n };\n\n var options = {};\n\n if (crossOrigin) {\n options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin\n }\n\n fetch(url, options).then(function (response) {\n if (!response.ok) {\n throw response;\n }\n\n return response.blob();\n }).then(function (blob) {\n return _globalObject.default.createImageBitmap(blob, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none'\n });\n }).then(function (bitmap) {\n // not sure if this works. We don't want\n // to catch the user's error. So, call\n // the callback in a timeout so we're\n // not in this scope inside the promise.\n bm = bitmap;\n setTimeout(cb);\n }).catch(function (e) {\n err = e;\n setTimeout(cb);\n });\n img = null;\n }\n\n return img;\n}\n/**\n * check if object is a TexImageSource\n *\n * @param {Object} obj Object to test\n * @return {boolean} true if object is a TexImageSource\n */\n\n\nfunction isTexImageSource(obj) {\n return _globalObject.default.ImageBitmap && obj instanceof _globalObject.default.ImageBitmap || _globalObject.default.ImageData && obj instanceof _globalObject.default.ImageData || _globalObject.default.HTMLElement && obj instanceof _globalObject.default.HTMLElement;\n}\n/**\n * if obj is an TexImageSource then just\n * uses it otherwise if obj is a string\n * then load it first.\n *\n * @param {string|TexImageSource} obj\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n */\n\n\nfunction loadAndUseImage(obj, crossOrigin, callback) {\n if (isTexImageSource(obj)) {\n setTimeout(function () {\n callback(null, obj);\n });\n return obj;\n }\n\n return loadImage(obj, crossOrigin, callback);\n}\n/**\n * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set\n * the default texture color is used which can be set by calling `setDefaultTextureColor`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\n\n\nfunction setTextureTo1PixelColor(gl, tex, options) {\n options = options || defaults.textureOptions;\n var target = options.target || gl.TEXTURE_2D;\n gl.bindTexture(target, tex);\n\n if (options.color === false) {\n return;\n } // Assume it's a URL\n // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering.\n\n\n var color = make1Pixel(options.color);\n\n if (target === gl.TEXTURE_CUBE_MAP) {\n for (var ii = 0; ii < 6; ++ii) {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color);\n }\n } else if (target === gl.TEXTURE_3D || target === gl.TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color);\n } else {\n gl.texImage2D(target, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color);\n }\n}\n/**\n * The src image(s) used to create a texture.\n *\n * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures}\n * you can pass in urls for images to load into the textures. If it's a single url\n * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap\n * this will be a corresponding array of images for the cubemap.\n *\n * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback TextureReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} texture the texture.\n * @param {module:twgl.TextureSrc} souce image(s) used to as the src for the texture\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when all images have finished downloading and been uploaded into their respective textures\n * @callback TexturesReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}.\n * @param {Object.} sources the image(s) used for the texture by name.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback CubemapReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each face.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback ThreeDReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each slice.\n * @memberOf module:twgl\n */\n\n/**\n * Loads a texture from an image from a Url as specified in `options.src`\n * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is\n * immediately useable. It will be updated with the contents of the image once the image has finished\n * downloading. Filtering options will be set as approriate for image unless `options.auto === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will\n * be non null if there was an error.\n * @return {HTMLImageElement} the image being downloaded.\n * @memberOf module:twgl/textures\n */\n\n\nfunction loadTextureFromUrl(gl, tex, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n setTextureTo1PixelColor(gl, tex, options); // Because it's async we need to copy the options.\n\n options = Object.assign({}, options);\n var img = loadAndUseImage(options.src, options.crossOrigin, function (err, img) {\n if (err) {\n callback(err, tex, img);\n } else {\n setTextureFromElement(gl, tex, img, options);\n callback(null, tex, img);\n }\n });\n return img;\n}\n/**\n * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n */\n\n\nfunction loadCubemapFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n var urls = options.src;\n\n if (urls.length !== 6) {\n throw \"there must be 6 urls for a cubemap\";\n }\n\n var level = options.level || 0;\n var internalFormat = options.internalFormat || options.format || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var format = options.format || formatType.format;\n var type = options.type || gl.UNSIGNED_BYTE;\n var target = options.target || gl.TEXTURE_2D;\n\n if (target !== gl.TEXTURE_CUBE_MAP) {\n throw \"target must be TEXTURE_CUBE_MAP\";\n }\n\n setTextureTo1PixelColor(gl, tex, options); // Because it's async we need to copy the options.\n\n options = Object.assign({}, options);\n var numToLoad = 6;\n var errors = [];\n var faces = getCubeFaceOrder(gl, options);\n var imgs; // eslint-disable-line\n\n function uploadImg(faceTarget) {\n return function (err, img) {\n --numToLoad;\n\n if (err) {\n errors.push(err);\n } else {\n if (img.width !== img.height) {\n errors.push(\"cubemap face img is not a square: \" + img.src);\n } else {\n savePackState(gl, options);\n gl.bindTexture(target, tex); // So assuming this is the first image we now have one face that's img sized\n // and 5 faces that are 1x1 pixel so size the other faces\n\n if (numToLoad === 5) {\n // use the default order\n getCubeFaceOrder(gl).forEach(function (otherTarget) {\n // Should we re-use the same face or a color?\n gl.texImage2D(otherTarget, level, internalFormat, format, type, img);\n });\n } else {\n gl.texImage2D(faceTarget, level, internalFormat, format, type, img);\n }\n\n restorePackState(gl, options);\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n }\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function (url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx]));\n });\n}\n/**\n * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`.\n * Will set the texture to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n *\n * If the width and height is not specified the width and height of the first\n * image loaded will be used. Note that since images are loaded async\n * which image downloads first is unknown.\n *\n * If an image is not the same size as the width and height it will be scaled\n * to that width and height.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n */\n\n\nfunction loadSlicesFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n var urls = options.src;\n var internalFormat = options.internalFormat || options.format || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var format = options.format || formatType.format;\n var type = options.type || gl.UNSIGNED_BYTE;\n var target = options.target || gl.TEXTURE_2D_ARRAY;\n\n if (target !== gl.TEXTURE_3D && target !== gl.TEXTURE_2D_ARRAY) {\n throw \"target must be TEXTURE_3D or TEXTURE_2D_ARRAY\";\n }\n\n setTextureTo1PixelColor(gl, tex, options); // Because it's async we need to copy the options.\n\n options = Object.assign({}, options);\n var numToLoad = urls.length;\n var errors = [];\n var imgs; // eslint-disable-line\n\n var level = options.level || 0;\n var width = options.width;\n var height = options.height;\n var depth = urls.length;\n var firstImage = true;\n\n function uploadImg(slice) {\n return function (err, img) {\n --numToLoad;\n\n if (err) {\n errors.push(err);\n } else {\n savePackState(gl, options);\n gl.bindTexture(target, tex);\n\n if (firstImage) {\n firstImage = false;\n width = options.width || img.width;\n height = options.height || img.height;\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); // put it in every slice otherwise some slices will be 0,0,0,0\n\n for (var s = 0; s < depth; ++s) {\n gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img);\n }\n } else {\n var src = img;\n\n if (img.width !== width || img.height !== height) {\n // Size the image to fix\n src = ctx.canvas;\n ctx.canvas.width = width;\n ctx.canvas.height = height;\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); // free the canvas memory\n\n if (src === ctx.canvas) {\n ctx.canvas.width = 0;\n ctx.canvas.height = 0;\n }\n }\n\n restorePackState(gl, options);\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function (url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx));\n });\n}\n/**\n * Sets a texture from an array or typed array. If the width or height is not provided will attempt to\n * guess the size. See {@link module:twgl.TextureOptions}.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\n\n\nfunction setTextureFromArray(gl, tex, src, options) {\n options = options || defaults.textureOptions;\n var target = options.target || gl.TEXTURE_2D;\n gl.bindTexture(target, tex);\n var width = options.width;\n var height = options.height;\n var depth = options.depth;\n var level = options.level || 0;\n var internalFormat = options.internalFormat || options.format || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var format = options.format || formatType.format;\n var type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n\n if (!isArrayBuffer(src)) {\n var Type = typedArrays.getTypedArrayTypeForGLType(type);\n src = new Type(src);\n } else if (src instanceof Uint8ClampedArray) {\n src = new Uint8Array(src.buffer);\n }\n\n var bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type);\n var numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT?\n\n if (numElements % 1) {\n throw \"length wrong size for format: \" + utils.glEnumToString(gl, format);\n }\n\n var dimensions;\n\n if (target === gl.TEXTURE_3D) {\n if (!width && !height && !depth) {\n var size = Math.cbrt(numElements);\n\n if (size % 1 !== 0) {\n throw \"can't guess cube size of array of numElements: \" + numElements;\n }\n\n width = size;\n height = size;\n depth = size;\n } else if (width && (!height || !depth)) {\n dimensions = guessDimensions(gl, target, height, depth, numElements / width);\n height = dimensions.width;\n depth = dimensions.height;\n } else if (height && (!width || !depth)) {\n dimensions = guessDimensions(gl, target, width, depth, numElements / height);\n width = dimensions.width;\n depth = dimensions.height;\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements / depth);\n width = dimensions.width;\n height = dimensions.height;\n }\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements);\n width = dimensions.width;\n height = dimensions.height;\n }\n\n saveSkipState(gl);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, options.unpackAlignment || 1);\n savePackState(gl, options);\n\n if (target === gl.TEXTURE_CUBE_MAP) {\n var elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT;\n var faceSize = numElements / 6 * elementsPerElement;\n getCubeFacesWithNdx(gl, options).forEach(function (f) {\n var offset = faceSize * f.ndx;\n var data = src.subarray(offset, offset + faceSize);\n gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data);\n });\n } else if (target === gl.TEXTURE_3D) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src);\n }\n\n restorePackState(gl, options);\n restoreSkipState(gl);\n return {\n width: width,\n height: height,\n depth: depth,\n type: type\n };\n}\n/**\n * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`.\n * You must set `options.width` and `options.height`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\n\n\nfunction setEmptyTexture(gl, tex, options) {\n var target = options.target || gl.TEXTURE_2D;\n gl.bindTexture(target, tex);\n var level = options.level || 0;\n var internalFormat = options.internalFormat || options.format || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var format = options.format || formatType.format;\n var type = options.type || formatType.type;\n savePackState(gl, options);\n\n if (target === gl.TEXTURE_CUBE_MAP) {\n for (var ii = 0; ii < 6; ++ii) {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n } else if (target === gl.TEXTURE_3D) {\n gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n\n restorePackState(gl, options);\n}\n/**\n * Creates a texture based on the options passed in.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture.\n * @return {WebGLTexture} the created texture.\n * @memberOf module:twgl/textures\n */\n\n\nfunction createTexture(gl, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n var tex = gl.createTexture();\n var target = options.target || gl.TEXTURE_2D;\n var width = options.width || 1;\n var height = options.height || 1;\n var internalFormat = options.internalFormat || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var type = options.type || formatType.type;\n gl.bindTexture(target, tex);\n\n if (target === gl.TEXTURE_CUBE_MAP) {\n // this should have been the default for CUBEMAPS :(\n gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n }\n\n var src = options.src;\n\n if (src) {\n if (typeof src === \"function\") {\n src = src(gl, options);\n }\n\n if (typeof src === \"string\") {\n loadTextureFromUrl(gl, tex, options, callback);\n } else if (isArrayBuffer(src) || Array.isArray(src) && (typeof src[0] === 'number' || Array.isArray(src[0]) || isArrayBuffer(src[0]))) {\n var dimensions = setTextureFromArray(gl, tex, src, options);\n width = dimensions.width;\n height = dimensions.height;\n type = dimensions.type;\n } else if (Array.isArray(src) && (typeof src[0] === 'string' || isTexImageSource(src[0]))) {\n if (target === gl.TEXTURE_CUBE_MAP) {\n loadCubemapFromUrls(gl, tex, options, callback);\n } else {\n loadSlicesFromUrls(gl, tex, options, callback);\n }\n } else if (isTexImageSource(src)) {\n setTextureFromElement(gl, tex, src, options);\n width = src.width;\n height = src.height;\n } else {\n throw \"unsupported src type\";\n }\n } else {\n setEmptyTexture(gl, tex, options);\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat, type);\n }\n\n setTextureParameters(gl, tex, options);\n return tex;\n}\n/**\n * Resizes a texture based on the options passed in.\n *\n * Note: This is not a generic resize anything function.\n * It's mostly used by {@link module:twgl.resizeFramebufferInfo}\n * It will use `options.src` if it exists to try to determine a `type`\n * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided\n * for the texture. Texture parameters will be set accordingly\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the texture to resize\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {number} [width] the new width. If not passed in will use `options.width`\n * @param {number} [height] the new height. If not passed in will use `options.height`\n * @memberOf module:twgl/textures\n */\n\n\nfunction resizeTexture(gl, tex, options, width, height) {\n width = width || options.width;\n height = height || options.height;\n var target = options.target || gl.TEXTURE_2D;\n gl.bindTexture(target, tex);\n var level = options.level || 0;\n var internalFormat = options.internalFormat || options.format || gl.RGBA;\n var formatType = getFormatAndTypeForInternalFormat(internalFormat);\n var format = options.format || formatType.format;\n var type;\n var src = options.src;\n\n if (!src) {\n type = options.type || formatType.type;\n } else if (isArrayBuffer(src) || Array.isArray(src) && typeof src[0] === 'number') {\n type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n } else {\n type = options.type || formatType.type;\n }\n\n if (target === gl.TEXTURE_CUBE_MAP) {\n for (var ii = 0; ii < 6; ++ii) {\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null);\n }\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null);\n }\n}\n/**\n * Check if a src is an async request.\n * if src is a string we're going to download an image\n * if src is an array of strings we're going to download cubemap images\n * @param {*} src The src from a TextureOptions\n * @returns {bool} true if src is async.\n */\n\n\nfunction isAsyncSrc(src) {\n return typeof src === 'string' || Array.isArray(src) && typeof src[0] === 'string';\n}\n/**\n * Creates a bunch of textures based on the passed in options.\n *\n * Example:\n *\n * const textures = twgl.createTextures(gl, {\n * // a power of 2 image\n * hftIcon: { src: \"images/hft-icon-16.png\", mag: gl.NEAREST },\n * // a non-power of 2 image\n * clover: { src: \"images/clover.jpg\" },\n * // From a canvas\n * fromCanvas: { src: ctx.canvas },\n * // A cubemap from 6 images\n * yokohama: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: [\n * 'images/yokohama/posx.jpg',\n * 'images/yokohama/negx.jpg',\n * 'images/yokohama/posy.jpg',\n * 'images/yokohama/negy.jpg',\n * 'images/yokohama/posz.jpg',\n * 'images/yokohama/negz.jpg',\n * ],\n * },\n * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)\n * goldengate: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: 'images/goldengate.jpg',\n * },\n * // A 2x2 pixel texture from a JavaScript array\n * checker: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * src: [\n * 255,255,255,255,\n * 192,192,192,255,\n * 192,192,192,255,\n * 255,255,255,255,\n * ],\n * },\n * // a 1x2 pixel texture from a typed array.\n * stripe: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * format: gl.LUMINANCE,\n * src: new Uint8Array([\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * ]),\n * width: 1,\n * },\n * });\n *\n * Now\n *\n * * `textures.hftIcon` will be a 2d texture\n * * `textures.clover` will be a 2d texture\n * * `textures.fromCanvas` will be a 2d texture\n * * `textures.yohohama` will be a cubemap texture\n * * `textures.goldengate` will be a cubemap texture\n * * `textures.checker` will be a 2d texture\n * * `textures.stripe` will be a 2d texture\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per texture.\n * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded.\n * @return {Object.} the created textures by name\n * @memberOf module:twgl/textures\n */\n\n\nfunction createTextures(gl, textureOptions, callback) {\n callback = callback || noop;\n var numDownloading = 0;\n var errors = [];\n var textures = {};\n var images = {};\n\n function callCallbackIfReady() {\n if (numDownloading === 0) {\n setTimeout(function () {\n callback(errors.length ? errors : undefined, textures, images);\n }, 0);\n }\n }\n\n Object.keys(textureOptions).forEach(function (name) {\n var options = textureOptions[name];\n var onLoadFn;\n\n if (isAsyncSrc(options.src)) {\n onLoadFn = function onLoadFn(err, tex, img) {\n images[name] = img;\n --numDownloading;\n\n if (err) {\n errors.push(err);\n }\n\n callCallbackIfReady();\n };\n\n ++numDownloading;\n }\n\n textures[name] = createTexture(gl, options, onLoadFn);\n }); // queue the callback if there are no images to download.\n // We do this because if your code is structured to wait for\n // images to download but then you comment out all the async\n // images your code would break.\n\n callCallbackIfReady();\n return textures;\n} // Using quotes prevents Uglify from changing the names.\n// No speed diff AFAICT.\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nvar _exportNames = {\n m4: true,\n v3: true,\n primitives: true\n};\nexports.primitives = exports.v3 = exports.m4 = void 0;\n\nvar m4 = _interopRequireWildcard(__webpack_require__(6));\n\nexports.m4 = m4;\n\nvar v3 = _interopRequireWildcard(__webpack_require__(3));\n\nexports.v3 = v3;\n\nvar primitives = _interopRequireWildcard(__webpack_require__(10));\n\nexports.primitives = primitives;\n\nvar _twgl = __webpack_require__(11);\n\nObject.keys(_twgl).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = _twgl[key];\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.create3DFVertices = create3DFVertices;\nexports.createAugmentedTypedArray = createAugmentedTypedArray;\nexports.createCubeVertices = createCubeVertices;\nexports.createPlaneVertices = createPlaneVertices;\nexports.createSphereVertices = createSphereVertices;\nexports.createTruncatedConeVertices = createTruncatedConeVertices;\nexports.createXYQuadVertices = createXYQuadVertices;\nexports.createCresentVertices = createCresentVertices;\nexports.createCylinderVertices = createCylinderVertices;\nexports.createTorusVertices = createTorusVertices;\nexports.createDiscVertices = createDiscVertices;\nexports.deindexVertices = deindexVertices;\nexports.flattenNormals = flattenNormals;\nexports.makeRandomVertexColors = makeRandomVertexColors;\nexports.reorientDirections = reorientDirections;\nexports.reorientNormals = reorientNormals;\nexports.reorientPositions = reorientPositions;\nexports.reorientVertices = reorientVertices;\nexports.concatVertices = concatVertices;\nexports.duplicateVertices = duplicateVertices;\nexports.createDiscBuffers = exports.createDiscBufferInfo = exports.createTorusBuffers = exports.createTorusBufferInfo = exports.createCylinderBuffers = exports.createCylinderBufferInfo = exports.createCresentBuffers = exports.createCresentBufferInfo = exports.createXYQuadBuffers = exports.createXYQuadBufferInfo = exports.createTruncatedConeBuffers = exports.createTruncatedConeBufferInfo = exports.createSphereBuffers = exports.createSphereBufferInfo = exports.createPlaneBuffers = exports.createPlaneBufferInfo = exports.createCubeBuffers = exports.createCubeBufferInfo = exports.create3DFBuffers = exports.create3DFBufferInfo = void 0;\n\nvar attributes = _interopRequireWildcard(__webpack_require__(7));\n\nvar helper = _interopRequireWildcard(__webpack_require__(0));\n\nvar typedArrays = _interopRequireWildcard(__webpack_require__(1));\n\nvar m4 = _interopRequireWildcard(__webpack_require__(6));\n\nvar v3 = _interopRequireWildcard(__webpack_require__(3));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * Various functions to make simple primitives\n *\n * note: Most primitive functions come in 3 styles\n *\n * * `createSomeShapeBufferInfo`\n *\n * These functions are almost always the functions you want to call. They\n * create vertices then make WebGLBuffers and create {@link module:twgl.AttribInfo}s\n * returing a {@link module:twgl.BufferInfo} you can pass to {@link module:twgl.setBuffersAndAttributes}\n * and {@link module:twgl.drawBufferInfo} etc...\n *\n * * `createSomeShapeBuffers`\n *\n * These create WebGLBuffers and put your data in them but nothing else.\n * It's a shortcut to doing it yourself if you don't want to use\n * the higher level functions.\n *\n * * `createSomeShapeVertices`\n *\n * These just create vertices, no buffers. This allows you to manipulate the vertices\n * or add more data before generating a {@link module:twgl.BufferInfo}. Once you're finished\n * manipulating the vertices call {@link module:twgl.createBufferInfoFromArrays}.\n *\n * example:\n *\n * const arrays = twgl.primitives.createPlaneArrays(1);\n * twgl.primitives.reorientVertices(arrays, m4.rotationX(Math.PI * 0.5));\n * const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);\n *\n * @module twgl/primitives\n */\nvar getArray = attributes.getArray_; // eslint-disable-line\n\nvar getNumComponents = attributes.getNumComponents_; // eslint-disable-line\n\n/**\n * Add `push` to a typed array. It just keeps a 'cursor'\n * and allows use to `push` values into the array so we\n * don't have to manually compute offsets\n * @param {TypedArray} typedArray TypedArray to augment\n * @param {number} numComponents number of components.\n */\n\nfunction augmentTypedArray(typedArray, numComponents) {\n var cursor = 0;\n\n typedArray.push = function () {\n for (var ii = 0; ii < arguments.length; ++ii) {\n var value = arguments[ii];\n\n if (value instanceof Array || typedArrays.isArrayBuffer(value)) {\n for (var jj = 0; jj < value.length; ++jj) {\n typedArray[cursor++] = value[jj];\n }\n } else {\n typedArray[cursor++] = value;\n }\n }\n };\n\n typedArray.reset = function (opt_index) {\n cursor = opt_index || 0;\n };\n\n typedArray.numComponents = numComponents;\n Object.defineProperty(typedArray, 'numElements', {\n get: function get() {\n return this.length / this.numComponents | 0;\n }\n });\n return typedArray;\n}\n/**\n * creates a typed array with a `push` function attached\n * so that you can easily *push* values.\n *\n * `push` can take multiple arguments. If an argument is an array each element\n * of the array will be added to the typed array.\n *\n * Example:\n *\n * const array = createAugmentedTypedArray(3, 2); // creates a Float32Array with 6 values\n * array.push(1, 2, 3);\n * array.push([4, 5, 6]);\n * // array now contains [1, 2, 3, 4, 5, 6]\n *\n * Also has `numComponents` and `numElements` properties.\n *\n * @param {number} numComponents number of components\n * @param {number} numElements number of elements. The total size of the array will be `numComponents * numElements`.\n * @param {constructor} opt_type A constructor for the type. Default = `Float32Array`.\n * @return {ArrayBufferView} A typed array.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createAugmentedTypedArray(numComponents, numElements, opt_type) {\n var Type = opt_type || Float32Array;\n return augmentTypedArray(new Type(numComponents * numElements), numComponents);\n}\n\nfunction allButIndices(name) {\n return name !== \"indices\";\n}\n/**\n * Given indexed vertices creates a new set of vertices unindexed by expanding the indexed vertices.\n * @param {Object.} vertices The indexed vertices to deindex\n * @return {Object.} The deindexed vertices\n * @memberOf module:twgl/primitives\n */\n\n\nfunction deindexVertices(vertices) {\n var indices = vertices.indices;\n var newVertices = {};\n var numElements = indices.length;\n\n function expandToUnindexed(channel) {\n var srcBuffer = vertices[channel];\n var numComponents = srcBuffer.numComponents;\n var dstBuffer = createAugmentedTypedArray(numComponents, numElements, srcBuffer.constructor);\n\n for (var ii = 0; ii < numElements; ++ii) {\n var ndx = indices[ii];\n var offset = ndx * numComponents;\n\n for (var jj = 0; jj < numComponents; ++jj) {\n dstBuffer.push(srcBuffer[offset + jj]);\n }\n }\n\n newVertices[channel] = dstBuffer;\n }\n\n Object.keys(vertices).filter(allButIndices).forEach(expandToUnindexed);\n return newVertices;\n}\n/**\n * flattens the normals of deindexed vertices in place.\n * @param {Object.} vertices The deindexed vertices who's normals to flatten\n * @return {Object.} The flattened vertices (same as was passed in)\n * @memberOf module:twgl/primitives\n */\n\n\nfunction flattenNormals(vertices) {\n if (vertices.indices) {\n throw \"can't flatten normals of indexed vertices. deindex them first\";\n }\n\n var normals = vertices.normal;\n var numNormals = normals.length;\n\n for (var ii = 0; ii < numNormals; ii += 9) {\n // pull out the 3 normals for this triangle\n var nax = normals[ii + 0];\n var nay = normals[ii + 1];\n var naz = normals[ii + 2];\n var nbx = normals[ii + 3];\n var nby = normals[ii + 4];\n var nbz = normals[ii + 5];\n var ncx = normals[ii + 6];\n var ncy = normals[ii + 7];\n var ncz = normals[ii + 8]; // add them\n\n var nx = nax + nbx + ncx;\n var ny = nay + nby + ncy;\n var nz = naz + nbz + ncz; // normalize them\n\n var length = Math.sqrt(nx * nx + ny * ny + nz * nz);\n nx /= length;\n ny /= length;\n nz /= length; // copy them back in\n\n normals[ii + 0] = nx;\n normals[ii + 1] = ny;\n normals[ii + 2] = nz;\n normals[ii + 3] = nx;\n normals[ii + 4] = ny;\n normals[ii + 5] = nz;\n normals[ii + 6] = nx;\n normals[ii + 7] = ny;\n normals[ii + 8] = nz;\n }\n\n return vertices;\n}\n\nfunction applyFuncToV3Array(array, matrix, fn) {\n var len = array.length;\n var tmp = new Float32Array(3);\n\n for (var ii = 0; ii < len; ii += 3) {\n fn(matrix, [array[ii], array[ii + 1], array[ii + 2]], tmp);\n array[ii] = tmp[0];\n array[ii + 1] = tmp[1];\n array[ii + 2] = tmp[2];\n }\n}\n\nfunction transformNormal(mi, v, dst) {\n dst = dst || v3.create();\n var v0 = v[0];\n var v1 = v[1];\n var v2 = v[2];\n dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2];\n dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2];\n dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2];\n return dst;\n}\n/**\n * Reorients directions by the given matrix..\n * @param {number[]|TypedArray} array The array. Assumes value floats per element.\n * @param {Matrix} matrix A matrix to multiply by.\n * @return {number[]|TypedArray} the same array that was passed in\n * @memberOf module:twgl/primitives\n */\n\n\nfunction reorientDirections(array, matrix) {\n applyFuncToV3Array(array, matrix, m4.transformDirection);\n return array;\n}\n/**\n * Reorients normals by the inverse-transpose of the given\n * matrix..\n * @param {number[]|TypedArray} array The array. Assumes value floats per element.\n * @param {Matrix} matrix A matrix to multiply by.\n * @return {number[]|TypedArray} the same array that was passed in\n * @memberOf module:twgl/primitives\n */\n\n\nfunction reorientNormals(array, matrix) {\n applyFuncToV3Array(array, m4.inverse(matrix), transformNormal);\n return array;\n}\n/**\n * Reorients positions by the given matrix. In other words, it\n * multiplies each vertex by the given matrix.\n * @param {number[]|TypedArray} array The array. Assumes value floats per element.\n * @param {Matrix} matrix A matrix to multiply by.\n * @return {number[]|TypedArray} the same array that was passed in\n * @memberOf module:twgl/primitives\n */\n\n\nfunction reorientPositions(array, matrix) {\n applyFuncToV3Array(array, matrix, m4.transformPoint);\n return array;\n}\n/**\n * Reorients arrays by the given matrix. Assumes arrays have\n * names that contains 'pos' could be reoriented as positions,\n * 'binorm' or 'tan' as directions, and 'norm' as normals.\n *\n * @param {Object.} arrays The vertices to reorient\n * @param {Matrix} matrix matrix to reorient by.\n * @return {Object.} same arrays that were passed in.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction reorientVertices(arrays, matrix) {\n Object.keys(arrays).forEach(function (name) {\n var array = arrays[name];\n\n if (name.indexOf(\"pos\") >= 0) {\n reorientPositions(array, matrix);\n } else if (name.indexOf(\"tan\") >= 0 || name.indexOf(\"binorm\") >= 0) {\n reorientDirections(array, matrix);\n } else if (name.indexOf(\"norm\") >= 0) {\n reorientNormals(array, matrix);\n }\n });\n return arrays;\n}\n/**\n * Creates XY quad BufferInfo\n *\n * The default with no parameters will return a 2x2 quad with values from -1 to +1.\n * If you want a unit quad with that goes from 0 to 1 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5);\n *\n * If you want a unit quad centered above 0,0 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1\n * @param {number} [xOffset] the amount to offset the quad in X\n * @param {number} [yOffset] the amount to offset the quad in Y\n * @return {Object.} the created XY Quad BufferInfo\n * @memberOf module:twgl/primitives\n * @function createXYQuadBufferInfo\n */\n\n/**\n * Creates XY quad Buffers\n *\n * The default with no parameters will return a 2x2 quad with values from -1 to +1.\n * If you want a unit quad with that goes from 0 to 1 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5);\n *\n * If you want a unit quad centered above 0,0 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1\n * @param {number} [xOffset] the amount to offset the quad in X\n * @param {number} [yOffset] the amount to offset the quad in Y\n * @return {module:twgl.BufferInfo} the created XY Quad buffers\n * @memberOf module:twgl/primitives\n * @function createXYQuadBuffers\n */\n\n/**\n * Creates XY quad vertices\n *\n * The default with no parameters will return a 2x2 quad with values from -1 to +1.\n * If you want a unit quad with that goes from 0 to 1 you'd call it with\n *\n * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5);\n *\n * If you want a unit quad centered above 0,0 you'd call it with\n *\n * twgl.primitives.createXYQuadVertices(1, 0, 0.5);\n *\n * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1\n * @param {number} [xOffset] the amount to offset the quad in X\n * @param {number} [yOffset] the amount to offset the quad in Y\n * @return {Object. the created XY Quad vertices\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createXYQuadVertices(size, xOffset, yOffset) {\n size = size || 2;\n xOffset = xOffset || 0;\n yOffset = yOffset || 0;\n size *= 0.5;\n return {\n position: {\n numComponents: 2,\n data: [xOffset + -1 * size, yOffset + -1 * size, xOffset + 1 * size, yOffset + -1 * size, xOffset + -1 * size, yOffset + 1 * size, xOffset + 1 * size, yOffset + 1 * size]\n },\n normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],\n texcoord: [0, 0, 1, 0, 0, 1, 1, 1],\n indices: [0, 1, 2, 2, 1, 3]\n };\n}\n/**\n * Creates XZ plane BufferInfo.\n *\n * The created plane has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [width] Width of the plane. Default = 1\n * @param {number} [depth] Depth of the plane. Default = 1\n * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1\n * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1\n * @param {Matrix4} [matrix] A matrix by which to multiply all the vertices.\n * @return {@module:twgl.BufferInfo} The created plane BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createPlaneBufferInfo\n */\n\n/**\n * Creates XZ plane buffers.\n *\n * The created plane has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [width] Width of the plane. Default = 1\n * @param {number} [depth] Depth of the plane. Default = 1\n * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1\n * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1\n * @param {Matrix4} [matrix] A matrix by which to multiply all the vertices.\n * @return {Object.} The created plane buffers.\n * @memberOf module:twgl/primitives\n * @function createPlaneBuffers\n */\n\n/**\n * Creates XZ plane vertices.\n *\n * The created plane has position, normal, and texcoord data\n *\n * @param {number} [width] Width of the plane. Default = 1\n * @param {number} [depth] Depth of the plane. Default = 1\n * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1\n * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1\n * @param {Matrix4} [matrix] A matrix by which to multiply all the vertices.\n * @return {Object.} The created plane vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createPlaneVertices(width, depth, subdivisionsWidth, subdivisionsDepth, matrix) {\n width = width || 1;\n depth = depth || 1;\n subdivisionsWidth = subdivisionsWidth || 1;\n subdivisionsDepth = subdivisionsDepth || 1;\n matrix = matrix || m4.identity();\n var numVertices = (subdivisionsWidth + 1) * (subdivisionsDepth + 1);\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices);\n\n for (var z = 0; z <= subdivisionsDepth; z++) {\n for (var x = 0; x <= subdivisionsWidth; x++) {\n var u = x / subdivisionsWidth;\n var v = z / subdivisionsDepth;\n positions.push(width * u - width * 0.5, 0, depth * v - depth * 0.5);\n normals.push(0, 1, 0);\n texcoords.push(u, v);\n }\n }\n\n var numVertsAcross = subdivisionsWidth + 1;\n var indices = createAugmentedTypedArray(3, subdivisionsWidth * subdivisionsDepth * 2, Uint16Array);\n\n for (var _z = 0; _z < subdivisionsDepth; _z++) {\n // eslint-disable-line\n for (var _x = 0; _x < subdivisionsWidth; _x++) {\n // eslint-disable-line\n // Make triangle 1 of quad.\n indices.push((_z + 0) * numVertsAcross + _x, (_z + 1) * numVertsAcross + _x, (_z + 0) * numVertsAcross + _x + 1); // Make triangle 2 of quad.\n\n indices.push((_z + 1) * numVertsAcross + _x, (_z + 1) * numVertsAcross + _x + 1, (_z + 0) * numVertsAcross + _x + 1);\n }\n }\n\n var arrays = reorientVertices({\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n }, matrix);\n return arrays;\n}\n/**\n * Creates sphere BufferInfo.\n *\n * The created sphere has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of the sphere.\n * @param {number} subdivisionsAxis number of steps around the sphere.\n * @param {number} subdivisionsHeight number of vertically on the sphere.\n * @param {number} [opt_startLatitudeInRadians] where to start the\n * top of the sphere. Default = 0.\n * @param {number} [opt_endLatitudeInRadians] Where to end the\n * bottom of the sphere. Default = Math.PI.\n * @param {number} [opt_startLongitudeInRadians] where to start\n * wrapping the sphere. Default = 0.\n * @param {number} [opt_endLongitudeInRadians] where to end\n * wrapping the sphere. Default = 2 * Math.PI.\n * @return {module:twgl.BufferInfo} The created sphere BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createSphereBufferInfo\n */\n\n/**\n * Creates sphere buffers.\n *\n * The created sphere has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of the sphere.\n * @param {number} subdivisionsAxis number of steps around the sphere.\n * @param {number} subdivisionsHeight number of vertically on the sphere.\n * @param {number} [opt_startLatitudeInRadians] where to start the\n * top of the sphere. Default = 0.\n * @param {number} [opt_endLatitudeInRadians] Where to end the\n * bottom of the sphere. Default = Math.PI.\n * @param {number} [opt_startLongitudeInRadians] where to start\n * wrapping the sphere. Default = 0.\n * @param {number} [opt_endLongitudeInRadians] where to end\n * wrapping the sphere. Default = 2 * Math.PI.\n * @return {Object.} The created sphere buffers.\n * @memberOf module:twgl/primitives\n * @function createSphereBuffers\n */\n\n/**\n * Creates sphere vertices.\n *\n * The created sphere has position, normal, and texcoord data\n *\n * @param {number} radius radius of the sphere.\n * @param {number} subdivisionsAxis number of steps around the sphere.\n * @param {number} subdivisionsHeight number of vertically on the sphere.\n * @param {number} [opt_startLatitudeInRadians] where to start the\n * top of the sphere. Default = 0.\n * @param {number} [opt_endLatitudeInRadians] Where to end the\n * bottom of the sphere. Default = Math.PI.\n * @param {number} [opt_startLongitudeInRadians] where to start\n * wrapping the sphere. Default = 0.\n * @param {number} [opt_endLongitudeInRadians] where to end\n * wrapping the sphere. Default = 2 * Math.PI.\n * @return {Object.} The created sphere vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createSphereVertices(radius, subdivisionsAxis, subdivisionsHeight, opt_startLatitudeInRadians, opt_endLatitudeInRadians, opt_startLongitudeInRadians, opt_endLongitudeInRadians) {\n if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) {\n throw Error('subdivisionAxis and subdivisionHeight must be > 0');\n }\n\n opt_startLatitudeInRadians = opt_startLatitudeInRadians || 0;\n opt_endLatitudeInRadians = opt_endLatitudeInRadians || Math.PI;\n opt_startLongitudeInRadians = opt_startLongitudeInRadians || 0;\n opt_endLongitudeInRadians = opt_endLongitudeInRadians || Math.PI * 2;\n var latRange = opt_endLatitudeInRadians - opt_startLatitudeInRadians;\n var longRange = opt_endLongitudeInRadians - opt_startLongitudeInRadians; // We are going to generate our sphere by iterating through its\n // spherical coordinates and generating 2 triangles for each quad on a\n // ring of the sphere.\n\n var numVertices = (subdivisionsAxis + 1) * (subdivisionsHeight + 1);\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices); // Generate the individual vertices in our vertex buffer.\n\n for (var y = 0; y <= subdivisionsHeight; y++) {\n for (var x = 0; x <= subdivisionsAxis; x++) {\n // Generate a vertex based on its spherical coordinates\n var u = x / subdivisionsAxis;\n var v = y / subdivisionsHeight;\n var theta = longRange * u;\n var phi = latRange * v;\n var sinTheta = Math.sin(theta);\n var cosTheta = Math.cos(theta);\n var sinPhi = Math.sin(phi);\n var cosPhi = Math.cos(phi);\n var ux = cosTheta * sinPhi;\n var uy = cosPhi;\n var uz = sinTheta * sinPhi;\n positions.push(radius * ux, radius * uy, radius * uz);\n normals.push(ux, uy, uz);\n texcoords.push(1 - u, v);\n }\n }\n\n var numVertsAround = subdivisionsAxis + 1;\n var indices = createAugmentedTypedArray(3, subdivisionsAxis * subdivisionsHeight * 2, Uint16Array);\n\n for (var _x2 = 0; _x2 < subdivisionsAxis; _x2++) {\n // eslint-disable-line\n for (var _y = 0; _y < subdivisionsHeight; _y++) {\n // eslint-disable-line\n // Make triangle 1 of quad.\n indices.push((_y + 0) * numVertsAround + _x2, (_y + 0) * numVertsAround + _x2 + 1, (_y + 1) * numVertsAround + _x2); // Make triangle 2 of quad.\n\n indices.push((_y + 1) * numVertsAround + _x2, (_y + 0) * numVertsAround + _x2 + 1, (_y + 1) * numVertsAround + _x2 + 1);\n }\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n };\n}\n/**\n * Array of the indices of corners of each face of a cube.\n * @type {Array.}\n */\n\n\nvar CUBE_FACE_INDICES = [[3, 7, 5, 1], // right\n[6, 2, 0, 4], // left\n[6, 7, 3, 2], // ??\n[0, 1, 5, 4], // ??\n[7, 6, 4, 5], // front\n[2, 3, 1, 0]];\n/**\n * Creates a BufferInfo for a cube.\n *\n * The cube is created around the origin. (-size / 2, size / 2).\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] width, height and depth of the cube.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCubeBufferInfo\n */\n\n/**\n * Creates the buffers and indices for a cube.\n *\n * The cube is created around the origin. (-size / 2, size / 2).\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] width, height and depth of the cube.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCubeBuffers\n */\n\n/**\n * Creates the vertices and indices for a cube.\n *\n * The cube is created around the origin. (-size / 2, size / 2).\n *\n * @param {number} [size] width, height and depth of the cube.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n\nfunction createCubeVertices(size) {\n size = size || 1;\n var k = size / 2;\n var cornerVertices = [[-k, -k, -k], [+k, -k, -k], [-k, +k, -k], [+k, +k, -k], [-k, -k, +k], [+k, -k, +k], [-k, +k, +k], [+k, +k, +k]];\n var faceNormals = [[+1, +0, +0], [-1, +0, +0], [+0, +1, +0], [+0, -1, +0], [+0, +0, +1], [+0, +0, -1]];\n var uvCoords = [[1, 0], [0, 0], [0, 1], [1, 1]];\n var numVertices = 6 * 4;\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices);\n var indices = createAugmentedTypedArray(3, 6 * 2, Uint16Array);\n\n for (var f = 0; f < 6; ++f) {\n var faceIndices = CUBE_FACE_INDICES[f];\n\n for (var v = 0; v < 4; ++v) {\n var position = cornerVertices[faceIndices[v]];\n var normal = faceNormals[f];\n var uv = uvCoords[v]; // Each face needs all four vertices because the normals and texture\n // coordinates are not all the same.\n\n positions.push(position);\n normals.push(normal);\n texcoords.push(uv);\n } // Two triangles make a square face.\n\n\n var offset = 4 * f;\n indices.push(offset + 0, offset + 1, offset + 2);\n indices.push(offset + 0, offset + 2, offset + 3);\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n };\n}\n/**\n * Creates a BufferInfo for a truncated cone, which is like a cylinder\n * except that it has different top and bottom radii. A truncated cone\n * can also be used to create cylinders and regular cones. The\n * truncated cone will be created centered about the origin, with the\n * y axis as its vertical axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} bottomRadius Bottom radius of truncated cone.\n * @param {number} topRadius Top radius of truncated cone.\n * @param {number} height Height of truncated cone.\n * @param {number} radialSubdivisions The number of subdivisions around the\n * truncated cone.\n * @param {number} verticalSubdivisions The number of subdivisions down the\n * truncated cone.\n * @param {boolean} [opt_topCap] Create top cap. Default = true.\n * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true.\n * @return {module:twgl.BufferInfo} The created cone BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createTruncatedConeBufferInfo\n */\n\n/**\n * Creates buffers for a truncated cone, which is like a cylinder\n * except that it has different top and bottom radii. A truncated cone\n * can also be used to create cylinders and regular cones. The\n * truncated cone will be created centered about the origin, with the\n * y axis as its vertical axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} bottomRadius Bottom radius of truncated cone.\n * @param {number} topRadius Top radius of truncated cone.\n * @param {number} height Height of truncated cone.\n * @param {number} radialSubdivisions The number of subdivisions around the\n * truncated cone.\n * @param {number} verticalSubdivisions The number of subdivisions down the\n * truncated cone.\n * @param {boolean} [opt_topCap] Create top cap. Default = true.\n * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created cone buffers.\n * @memberOf module:twgl/primitives\n * @function createTruncatedConeBuffers\n */\n\n/**\n * Creates vertices for a truncated cone, which is like a cylinder\n * except that it has different top and bottom radii. A truncated cone\n * can also be used to create cylinders and regular cones. The\n * truncated cone will be created centered about the origin, with the\n * y axis as its vertical axis. .\n *\n * @param {number} bottomRadius Bottom radius of truncated cone.\n * @param {number} topRadius Top radius of truncated cone.\n * @param {number} height Height of truncated cone.\n * @param {number} radialSubdivisions The number of subdivisions around the\n * truncated cone.\n * @param {number} verticalSubdivisions The number of subdivisions down the\n * truncated cone.\n * @param {boolean} [opt_topCap] Create top cap. Default = true.\n * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created cone vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createTruncatedConeVertices(bottomRadius, topRadius, height, radialSubdivisions, verticalSubdivisions, opt_topCap, opt_bottomCap) {\n if (radialSubdivisions < 3) {\n throw Error('radialSubdivisions must be 3 or greater');\n }\n\n if (verticalSubdivisions < 1) {\n throw Error('verticalSubdivisions must be 1 or greater');\n }\n\n var topCap = opt_topCap === undefined ? true : opt_topCap;\n var bottomCap = opt_bottomCap === undefined ? true : opt_bottomCap;\n var extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0);\n var numVertices = (radialSubdivisions + 1) * (verticalSubdivisions + 1 + extra);\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices);\n var indices = createAugmentedTypedArray(3, radialSubdivisions * (verticalSubdivisions + extra) * 2, Uint16Array);\n var vertsAroundEdge = radialSubdivisions + 1; // The slant of the cone is constant across its surface\n\n var slant = Math.atan2(bottomRadius - topRadius, height);\n var cosSlant = Math.cos(slant);\n var sinSlant = Math.sin(slant);\n var start = topCap ? -2 : 0;\n var end = verticalSubdivisions + (bottomCap ? 2 : 0);\n\n for (var yy = start; yy <= end; ++yy) {\n var v = yy / verticalSubdivisions;\n var y = height * v;\n var ringRadius = void 0;\n\n if (yy < 0) {\n y = 0;\n v = 1;\n ringRadius = bottomRadius;\n } else if (yy > verticalSubdivisions) {\n y = height;\n v = 1;\n ringRadius = topRadius;\n } else {\n ringRadius = bottomRadius + (topRadius - bottomRadius) * (yy / verticalSubdivisions);\n }\n\n if (yy === -2 || yy === verticalSubdivisions + 2) {\n ringRadius = 0;\n v = 0;\n }\n\n y -= height / 2;\n\n for (var ii = 0; ii < vertsAroundEdge; ++ii) {\n var sin = Math.sin(ii * Math.PI * 2 / radialSubdivisions);\n var cos = Math.cos(ii * Math.PI * 2 / radialSubdivisions);\n positions.push(sin * ringRadius, y, cos * ringRadius);\n normals.push(yy < 0 || yy > verticalSubdivisions ? 0 : sin * cosSlant, yy < 0 ? -1 : yy > verticalSubdivisions ? 1 : sinSlant, yy < 0 || yy > verticalSubdivisions ? 0 : cos * cosSlant);\n texcoords.push(ii / radialSubdivisions, 1 - v);\n }\n }\n\n for (var _yy = 0; _yy < verticalSubdivisions + extra; ++_yy) {\n // eslint-disable-line\n for (var _ii = 0; _ii < radialSubdivisions; ++_ii) {\n // eslint-disable-line\n indices.push(vertsAroundEdge * (_yy + 0) + 0 + _ii, vertsAroundEdge * (_yy + 0) + 1 + _ii, vertsAroundEdge * (_yy + 1) + 1 + _ii);\n indices.push(vertsAroundEdge * (_yy + 0) + 0 + _ii, vertsAroundEdge * (_yy + 1) + 1 + _ii, vertsAroundEdge * (_yy + 1) + 0 + _ii);\n }\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n };\n}\n/**\n * Expands RLE data\n * @param {number[]} rleData data in format of run-length, x, y, z, run-length, x, y, z\n * @param {number[]} [padding] value to add each entry with.\n * @return {number[]} the expanded rleData\n */\n\n\nfunction expandRLEData(rleData, padding) {\n padding = padding || [];\n var data = [];\n\n for (var ii = 0; ii < rleData.length; ii += 4) {\n var runLength = rleData[ii];\n var element = rleData.slice(ii + 1, ii + 4);\n element.push.apply(element, padding);\n\n for (var jj = 0; jj < runLength; ++jj) {\n data.push.apply(data, element);\n }\n }\n\n return data;\n}\n/**\n * Creates 3D 'F' BufferInfo.\n * An 'F' is useful because you can easily tell which way it is oriented.\n * The created 'F' has position, normal, texcoord, and color buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function create3DFBufferInfo\n */\n\n/**\n * Creates 3D 'F' buffers.\n * An 'F' is useful because you can easily tell which way it is oriented.\n * The created 'F' has position, normal, texcoord, and color buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function create3DFBuffers\n */\n\n/**\n * Creates 3D 'F' vertices.\n * An 'F' is useful because you can easily tell which way it is oriented.\n * The created 'F' has position, normal, texcoord, and color arrays.\n *\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction create3DFVertices() {\n var positions = [// left column front\n 0, 0, 0, 0, 150, 0, 30, 0, 0, 0, 150, 0, 30, 150, 0, 30, 0, 0, // top rung front\n 30, 0, 0, 30, 30, 0, 100, 0, 0, 30, 30, 0, 100, 30, 0, 100, 0, 0, // middle rung front\n 30, 60, 0, 30, 90, 0, 67, 60, 0, 30, 90, 0, 67, 90, 0, 67, 60, 0, // left column back\n 0, 0, 30, 30, 0, 30, 0, 150, 30, 0, 150, 30, 30, 0, 30, 30, 150, 30, // top rung back\n 30, 0, 30, 100, 0, 30, 30, 30, 30, 30, 30, 30, 100, 0, 30, 100, 30, 30, // middle rung back\n 30, 60, 30, 67, 60, 30, 30, 90, 30, 30, 90, 30, 67, 60, 30, 67, 90, 30, // top\n 0, 0, 0, 100, 0, 0, 100, 0, 30, 0, 0, 0, 100, 0, 30, 0, 0, 30, // top rung front\n 100, 0, 0, 100, 30, 0, 100, 30, 30, 100, 0, 0, 100, 30, 30, 100, 0, 30, // under top rung\n 30, 30, 0, 30, 30, 30, 100, 30, 30, 30, 30, 0, 100, 30, 30, 100, 30, 0, // between top rung and middle\n 30, 30, 0, 30, 60, 30, 30, 30, 30, 30, 30, 0, 30, 60, 0, 30, 60, 30, // top of middle rung\n 30, 60, 0, 67, 60, 30, 30, 60, 30, 30, 60, 0, 67, 60, 0, 67, 60, 30, // front of middle rung\n 67, 60, 0, 67, 90, 30, 67, 60, 30, 67, 60, 0, 67, 90, 0, 67, 90, 30, // bottom of middle rung.\n 30, 90, 0, 30, 90, 30, 67, 90, 30, 30, 90, 0, 67, 90, 30, 67, 90, 0, // front of bottom\n 30, 90, 0, 30, 150, 30, 30, 90, 30, 30, 90, 0, 30, 150, 0, 30, 150, 30, // bottom\n 0, 150, 0, 0, 150, 30, 30, 150, 30, 0, 150, 0, 30, 150, 30, 30, 150, 0, // left side\n 0, 0, 0, 0, 0, 30, 0, 150, 30, 0, 0, 0, 0, 150, 30, 0, 150, 0];\n var texcoords = [// left column front\n 0.22, 0.19, 0.22, 0.79, 0.34, 0.19, 0.22, 0.79, 0.34, 0.79, 0.34, 0.19, // top rung front\n 0.34, 0.19, 0.34, 0.31, 0.62, 0.19, 0.34, 0.31, 0.62, 0.31, 0.62, 0.19, // middle rung front\n 0.34, 0.43, 0.34, 0.55, 0.49, 0.43, 0.34, 0.55, 0.49, 0.55, 0.49, 0.43, // left column back\n 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, // top rung back\n 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, // middle rung back\n 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, // top\n 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, // top rung front\n 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, // under top rung\n 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, // between top rung and middle\n 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, // top of middle rung\n 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, // front of middle rung\n 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, // bottom of middle rung.\n 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, // front of bottom\n 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, // bottom\n 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, // left side\n 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0];\n var normals = expandRLEData([// left column front\n // top rung front\n // middle rung front\n 18, 0, 0, 1, // left column back\n // top rung back\n // middle rung back\n 18, 0, 0, -1, // top\n 6, 0, 1, 0, // top rung front\n 6, 1, 0, 0, // under top rung\n 6, 0, -1, 0, // between top rung and middle\n 6, 1, 0, 0, // top of middle rung\n 6, 0, 1, 0, // front of middle rung\n 6, 1, 0, 0, // bottom of middle rung.\n 6, 0, -1, 0, // front of bottom\n 6, 1, 0, 0, // bottom\n 6, 0, -1, 0, // left side\n 6, -1, 0, 0]);\n var colors = expandRLEData([// left column front\n // top rung front\n // middle rung front\n 18, 200, 70, 120, // left column back\n // top rung back\n // middle rung back\n 18, 80, 70, 200, // top\n 6, 70, 200, 210, // top rung front\n 6, 200, 200, 70, // under top rung\n 6, 210, 100, 70, // between top rung and middle\n 6, 210, 160, 70, // top of middle rung\n 6, 70, 180, 210, // front of middle rung\n 6, 100, 70, 210, // bottom of middle rung.\n 6, 76, 210, 100, // front of bottom\n 6, 140, 210, 80, // bottom\n 6, 90, 130, 110, // left side\n 6, 160, 160, 220], [255]);\n var numVerts = positions.length / 3;\n var arrays = {\n position: createAugmentedTypedArray(3, numVerts),\n texcoord: createAugmentedTypedArray(2, numVerts),\n normal: createAugmentedTypedArray(3, numVerts),\n color: createAugmentedTypedArray(4, numVerts, Uint8Array),\n indices: createAugmentedTypedArray(3, numVerts / 3, Uint16Array)\n };\n arrays.position.push(positions);\n arrays.texcoord.push(texcoords);\n arrays.normal.push(normals);\n arrays.color.push(colors);\n\n for (var ii = 0; ii < numVerts; ++ii) {\n arrays.indices.push(ii);\n }\n\n return arrays;\n}\n/**\n * Creates cresent BufferInfo.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} verticalRadius The vertical radius of the cresent.\n * @param {number} outerRadius The outer radius of the cresent.\n * @param {number} innerRadius The inner radius of the cresent.\n * @param {number} thickness The thickness of the cresent.\n * @param {number} subdivisionsDown number of steps around the cresent.\n * @param {number} subdivisionsThick number of vertically on the cresent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCresentBufferInfo\n */\n\n/**\n * Creates cresent buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} verticalRadius The vertical radius of the cresent.\n * @param {number} outerRadius The outer radius of the cresent.\n * @param {number} innerRadius The inner radius of the cresent.\n * @param {number} thickness The thickness of the cresent.\n * @param {number} subdivisionsDown number of steps around the cresent.\n * @param {number} subdivisionsThick number of vertically on the cresent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCresentBuffers\n */\n\n/**\n * Creates cresent vertices.\n *\n * @param {number} verticalRadius The vertical radius of the cresent.\n * @param {number} outerRadius The outer radius of the cresent.\n * @param {number} innerRadius The inner radius of the cresent.\n * @param {number} thickness The thickness of the cresent.\n * @param {number} subdivisionsDown number of steps around the cresent.\n * @param {number} subdivisionsThick number of vertically on the cresent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createCresentVertices(verticalRadius, outerRadius, innerRadius, thickness, subdivisionsDown, startOffset, endOffset) {\n if (subdivisionsDown <= 0) {\n throw Error('subdivisionDown must be > 0');\n }\n\n startOffset = startOffset || 0;\n endOffset = endOffset || 1;\n var subdivisionsThick = 2;\n var offsetRange = endOffset - startOffset;\n var numVertices = (subdivisionsDown + 1) * 2 * (2 + subdivisionsThick);\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices);\n\n function lerp(a, b, s) {\n return a + (b - a) * s;\n }\n\n function createArc(arcRadius, x, normalMult, normalAdd, uMult, uAdd) {\n for (var z = 0; z <= subdivisionsDown; z++) {\n var uBack = x / (subdivisionsThick - 1);\n var v = z / subdivisionsDown;\n var xBack = (uBack - 0.5) * 2;\n var angle = (startOffset + v * offsetRange) * Math.PI;\n var s = Math.sin(angle);\n var c = Math.cos(angle);\n var radius = lerp(verticalRadius, arcRadius, s);\n var px = xBack * thickness;\n var py = c * verticalRadius;\n var pz = s * radius;\n positions.push(px, py, pz);\n var n = v3.add(v3.multiply([0, s, c], normalMult), normalAdd);\n normals.push(n);\n texcoords.push(uBack * uMult + uAdd, v);\n }\n } // Generate the individual vertices in our vertex buffer.\n\n\n for (var x = 0; x < subdivisionsThick; x++) {\n var uBack = (x / (subdivisionsThick - 1) - 0.5) * 2;\n createArc(outerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0);\n createArc(outerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 0);\n createArc(innerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0);\n createArc(innerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 1);\n } // Do outer surface.\n\n\n var indices = createAugmentedTypedArray(3, subdivisionsDown * 2 * (2 + subdivisionsThick), Uint16Array);\n\n function createSurface(leftArcOffset, rightArcOffset) {\n for (var z = 0; z < subdivisionsDown; ++z) {\n // Make triangle 1 of quad.\n indices.push(leftArcOffset + z + 0, leftArcOffset + z + 1, rightArcOffset + z + 0); // Make triangle 2 of quad.\n\n indices.push(leftArcOffset + z + 1, rightArcOffset + z + 1, rightArcOffset + z + 0);\n }\n }\n\n var numVerticesDown = subdivisionsDown + 1; // front\n\n createSurface(numVerticesDown * 0, numVerticesDown * 4); // right\n\n createSurface(numVerticesDown * 5, numVerticesDown * 7); // back\n\n createSurface(numVerticesDown * 6, numVerticesDown * 2); // left\n\n createSurface(numVerticesDown * 3, numVerticesDown * 1);\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n };\n}\n/**\n * Creates cylinder BufferInfo. The cylinder will be created around the origin\n * along the y-axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of cylinder.\n * @param {number} height Height of cylinder.\n * @param {number} radialSubdivisions The number of subdivisions around the cylinder.\n * @param {number} verticalSubdivisions The number of subdivisions down the cylinder.\n * @param {boolean} [topCap] Create top cap. Default = true.\n * @param {boolean} [bottomCap] Create bottom cap. Default = true.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCylinderBufferInfo\n */\n\n/**\n * Creates cylinder buffers. The cylinder will be created around the origin\n * along the y-axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of cylinder.\n * @param {number} height Height of cylinder.\n * @param {number} radialSubdivisions The number of subdivisions around the cylinder.\n * @param {number} verticalSubdivisions The number of subdivisions down the cylinder.\n * @param {boolean} [topCap] Create top cap. Default = true.\n * @param {boolean} [bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCylinderBuffers\n */\n\n/**\n * Creates cylinder vertices. The cylinder will be created around the origin\n * along the y-axis.\n *\n * @param {number} radius Radius of cylinder.\n * @param {number} height Height of cylinder.\n * @param {number} radialSubdivisions The number of subdivisions around the cylinder.\n * @param {number} verticalSubdivisions The number of subdivisions down the cylinder.\n * @param {boolean} [topCap] Create top cap. Default = true.\n * @param {boolean} [bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createCylinderVertices(radius, height, radialSubdivisions, verticalSubdivisions, topCap, bottomCap) {\n return createTruncatedConeVertices(radius, radius, height, radialSubdivisions, verticalSubdivisions, topCap, bottomCap);\n}\n/**\n * Creates BufferInfo for a torus\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of center of torus circle.\n * @param {number} thickness radius of torus ring.\n * @param {number} radialSubdivisions The number of subdivisions around the torus.\n * @param {number} bodySubdivisions The number of subdivisions around the body torus.\n * @param {boolean} [startAngle] start angle in radians. Default = 0.\n * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createTorusBufferInfo\n */\n\n/**\n * Creates buffers for a torus\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of center of torus circle.\n * @param {number} thickness radius of torus ring.\n * @param {number} radialSubdivisions The number of subdivisions around the torus.\n * @param {number} bodySubdivisions The number of subdivisions around the body torus.\n * @param {boolean} [startAngle] start angle in radians. Default = 0.\n * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createTorusBuffers\n */\n\n/**\n * Creates vertices for a torus\n *\n * @param {number} radius radius of center of torus circle.\n * @param {number} thickness radius of torus ring.\n * @param {number} radialSubdivisions The number of subdivisions around the torus.\n * @param {number} bodySubdivisions The number of subdivisions around the body torus.\n * @param {boolean} [startAngle] start angle in radians. Default = 0.\n * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createTorusVertices(radius, thickness, radialSubdivisions, bodySubdivisions, startAngle, endAngle) {\n if (radialSubdivisions < 3) {\n throw Error('radialSubdivisions must be 3 or greater');\n }\n\n if (bodySubdivisions < 3) {\n throw Error('verticalSubdivisions must be 3 or greater');\n }\n\n startAngle = startAngle || 0;\n endAngle = endAngle || Math.PI * 2;\n var range = endAngle - startAngle;\n var radialParts = radialSubdivisions + 1;\n var bodyParts = bodySubdivisions + 1;\n var numVertices = radialParts * bodyParts;\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices);\n var indices = createAugmentedTypedArray(3, radialSubdivisions * bodySubdivisions * 2, Uint16Array);\n\n for (var slice = 0; slice < bodyParts; ++slice) {\n var v = slice / bodySubdivisions;\n var sliceAngle = v * Math.PI * 2;\n var sliceSin = Math.sin(sliceAngle);\n var ringRadius = radius + sliceSin * thickness;\n var ny = Math.cos(sliceAngle);\n var y = ny * thickness;\n\n for (var ring = 0; ring < radialParts; ++ring) {\n var u = ring / radialSubdivisions;\n var ringAngle = startAngle + u * range;\n var xSin = Math.sin(ringAngle);\n var zCos = Math.cos(ringAngle);\n var x = xSin * ringRadius;\n var z = zCos * ringRadius;\n var nx = xSin * sliceSin;\n var nz = zCos * sliceSin;\n positions.push(x, y, z);\n normals.push(nx, ny, nz);\n texcoords.push(u, 1 - v);\n }\n }\n\n for (var _slice = 0; _slice < bodySubdivisions; ++_slice) {\n // eslint-disable-line\n for (var _ring = 0; _ring < radialSubdivisions; ++_ring) {\n // eslint-disable-line\n var nextRingIndex = 1 + _ring;\n var nextSliceIndex = 1 + _slice;\n indices.push(radialParts * _slice + _ring, radialParts * nextSliceIndex + _ring, radialParts * _slice + nextRingIndex);\n indices.push(radialParts * nextSliceIndex + _ring, radialParts * nextSliceIndex + nextRingIndex, radialParts * _slice + nextRingIndex);\n }\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n };\n}\n/**\n * Creates a disc BufferInfo. The disc will be in the xz plane, centered at\n * the origin. When creating, at least 3 divisions, or pie\n * pieces, need to be specified, otherwise the triangles making\n * up the disc will be degenerate. You can also specify the\n * number of radial pieces `stacks`. A value of 1 for\n * stacks will give you a simple disc of pie pieces. If you\n * want to create an annulus you can set `innerRadius` to a\n * value > 0. Finally, `stackPower` allows you to have the widths\n * increase or decrease as you move away from the center. This\n * is particularly useful when using the disc as a ground plane\n * with a fixed camera such that you don't need the resolution\n * of small triangles near the perimeter. For example, a value\n * of 2 will produce stacks whose ouside radius increases with\n * the square of the stack index. A value of 1 will give uniform\n * stacks.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of the ground plane.\n * @param {number} divisions Number of triangles in the ground plane (at least 3).\n * @param {number} [stacks] Number of radial divisions (default=1).\n * @param {number} [innerRadius] Default 0.\n * @param {number} [stackPower] Power to raise stack size to for decreasing width.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createDiscBufferInfo\n */\n\n/**\n * Creates disc buffers. The disc will be in the xz plane, centered at\n * the origin. When creating, at least 3 divisions, or pie\n * pieces, need to be specified, otherwise the triangles making\n * up the disc will be degenerate. You can also specify the\n * number of radial pieces `stacks`. A value of 1 for\n * stacks will give you a simple disc of pie pieces. If you\n * want to create an annulus you can set `innerRadius` to a\n * value > 0. Finally, `stackPower` allows you to have the widths\n * increase or decrease as you move away from the center. This\n * is particularly useful when using the disc as a ground plane\n * with a fixed camera such that you don't need the resolution\n * of small triangles near the perimeter. For example, a value\n * of 2 will produce stacks whose ouside radius increases with\n * the square of the stack index. A value of 1 will give uniform\n * stacks.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of the ground plane.\n * @param {number} divisions Number of triangles in the ground plane (at least 3).\n * @param {number} [stacks] Number of radial divisions (default=1).\n * @param {number} [innerRadius] Default 0.\n * @param {number} [stackPower] Power to raise stack size to for decreasing width.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createDiscBuffers\n */\n\n/**\n * Creates disc vertices. The disc will be in the xz plane, centered at\n * the origin. When creating, at least 3 divisions, or pie\n * pieces, need to be specified, otherwise the triangles making\n * up the disc will be degenerate. You can also specify the\n * number of radial pieces `stacks`. A value of 1 for\n * stacks will give you a simple disc of pie pieces. If you\n * want to create an annulus you can set `innerRadius` to a\n * value > 0. Finally, `stackPower` allows you to have the widths\n * increase or decrease as you move away from the center. This\n * is particularly useful when using the disc as a ground plane\n * with a fixed camera such that you don't need the resolution\n * of small triangles near the perimeter. For example, a value\n * of 2 will produce stacks whose ouside radius increases with\n * the square of the stack index. A value of 1 will give uniform\n * stacks.\n *\n * @param {number} radius Radius of the ground plane.\n * @param {number} divisions Number of triangles in the ground plane (at least 3).\n * @param {number} [stacks] Number of radial divisions (default=1).\n * @param {number} [innerRadius] Default 0.\n * @param {number} [stackPower] Power to raise stack size to for decreasing width.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction createDiscVertices(radius, divisions, stacks, innerRadius, stackPower) {\n if (divisions < 3) {\n throw Error('divisions must be at least 3');\n }\n\n stacks = stacks ? stacks : 1;\n stackPower = stackPower ? stackPower : 1;\n innerRadius = innerRadius ? innerRadius : 0; // Note: We don't share the center vertex because that would\n // mess up texture coordinates.\n\n var numVertices = (divisions + 1) * (stacks + 1);\n var positions = createAugmentedTypedArray(3, numVertices);\n var normals = createAugmentedTypedArray(3, numVertices);\n var texcoords = createAugmentedTypedArray(2, numVertices);\n var indices = createAugmentedTypedArray(3, stacks * divisions * 2, Uint16Array);\n var firstIndex = 0;\n var radiusSpan = radius - innerRadius;\n var pointsPerStack = divisions + 1; // Build the disk one stack at a time.\n\n for (var stack = 0; stack <= stacks; ++stack) {\n var stackRadius = innerRadius + radiusSpan * Math.pow(stack / stacks, stackPower);\n\n for (var i = 0; i <= divisions; ++i) {\n var theta = 2.0 * Math.PI * i / divisions;\n var x = stackRadius * Math.cos(theta);\n var z = stackRadius * Math.sin(theta);\n positions.push(x, 0, z);\n normals.push(0, 1, 0);\n texcoords.push(1 - i / divisions, stack / stacks);\n\n if (stack > 0 && i !== divisions) {\n // a, b, c and d are the indices of the vertices of a quad. unless\n // the current stack is the one closest to the center, in which case\n // the vertices a and b connect to the center vertex.\n var a = firstIndex + (i + 1);\n var b = firstIndex + i;\n var c = firstIndex + i - pointsPerStack;\n var d = firstIndex + (i + 1) - pointsPerStack; // Make a quad of the vertices a, b, c, d.\n\n indices.push(a, b, c);\n indices.push(a, c, d);\n }\n }\n\n firstIndex += divisions + 1;\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices\n };\n}\n/**\n * creates a random integer between 0 and range - 1 inclusive.\n * @param {number} range\n * @return {number} random value between 0 and range - 1 inclusive.\n */\n\n\nfunction randInt(range) {\n return Math.random() * range | 0;\n}\n/**\n * Used to supply random colors\n * @callback RandomColorFunc\n * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed\n * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha\n * @return {number} a number from 0 to 255\n * @memberOf module:twgl/primitives\n */\n\n/**\n * @typedef {Object} RandomVerticesOptions\n * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices\n * @property {module:twgl/primitives.RandomColorFunc} [rand] A function to generate random numbers\n * @memberOf module:twgl/primitives\n */\n\n/**\n * Creates an augmentedTypedArray of random vertex colors.\n * If the vertices are indexed (have an indices array) then will\n * just make random colors. Otherwise assumes they are triangles\n * and makes one random color for every 3 vertices.\n * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions.\n * @param {module:twgl/primitives.RandomVerticesOptions} [options] options.\n * @return {Object.} same vertices as passed in with `color` added.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction makeRandomVertexColors(vertices, options) {\n options = options || {};\n var numElements = vertices.position.numElements;\n var vcolors = createAugmentedTypedArray(4, numElements, Uint8Array);\n\n var rand = options.rand || function (ndx, channel) {\n return channel < 3 ? randInt(256) : 255;\n };\n\n vertices.color = vcolors;\n\n if (vertices.indices) {\n // just make random colors if index\n for (var ii = 0; ii < numElements; ++ii) {\n vcolors.push(rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3));\n }\n } else {\n // make random colors per triangle\n var numVertsPerColor = options.vertsPerColor || 3;\n var numSets = numElements / numVertsPerColor;\n\n for (var _ii2 = 0; _ii2 < numSets; ++_ii2) {\n // eslint-disable-line\n var color = [rand(_ii2, 0), rand(_ii2, 1), rand(_ii2, 2), rand(_ii2, 3)];\n\n for (var jj = 0; jj < numVertsPerColor; ++jj) {\n vcolors.push(color);\n }\n }\n }\n\n return vertices;\n}\n/**\n * creates a function that calls fn to create vertices and then\n * creates a buffers for them\n */\n\n\nfunction createBufferFunc(fn) {\n return function (gl) {\n var arrays = fn.apply(this, Array.prototype.slice.call(arguments, 1));\n return attributes.createBuffersFromArrays(gl, arrays);\n };\n}\n/**\n * creates a function that calls fn to create vertices and then\n * creates a bufferInfo object for them\n */\n\n\nfunction createBufferInfoFunc(fn) {\n return function (gl) {\n var arrays = fn.apply(null, Array.prototype.slice.call(arguments, 1));\n return attributes.createBufferInfoFromArrays(gl, arrays);\n };\n}\n\nvar arraySpecPropertyNames = [\"numComponents\", \"size\", \"type\", \"normalize\", \"stride\", \"offset\", \"attrib\", \"name\", \"attribName\"];\n/**\n * Copy elements from one array to another\n *\n * @param {Array|TypedArray} src source array\n * @param {Array|TypedArray} dst dest array\n * @param {number} dstNdx index in dest to copy src\n * @param {number} [offset] offset to add to copied values\n */\n\nfunction copyElements(src, dst, dstNdx, offset) {\n offset = offset || 0;\n var length = src.length;\n\n for (var ii = 0; ii < length; ++ii) {\n dst[dstNdx + ii] = src[ii] + offset;\n }\n}\n/**\n * Creates an array of the same time\n *\n * @param {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} srcArray array who's type to copy\n * @param {number} length size of new array\n * @return {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} array with same type as srcArray\n */\n\n\nfunction createArrayOfSameType(srcArray, length) {\n var arraySrc = getArray(srcArray);\n var newArray = new arraySrc.constructor(length);\n var newArraySpec = newArray; // If it appears to have been augmented make new one augemented\n\n if (arraySrc.numComponents && arraySrc.numElements) {\n augmentTypedArray(newArray, arraySrc.numComponents);\n } // If it was a fullspec make new one a fullspec\n\n\n if (srcArray.data) {\n newArraySpec = {\n data: newArray\n };\n helper.copyNamedProperties(arraySpecPropertyNames, srcArray, newArraySpec);\n }\n\n return newArraySpec;\n}\n/**\n * Concatinates sets of vertices\n *\n * Assumes the vertices match in composition. For example\n * if one set of vertices has positions, normals, and indices\n * all sets of vertices must have positions, normals, and indices\n * and of the same type.\n *\n * Example:\n *\n * const cubeVertices = twgl.primtiives.createCubeVertices(2);\n * const sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10);\n * // move the sphere 2 units up\n * twgl.primitives.reorientVertices(\n * sphereVertices, twgl.m4.translation([0, 2, 0]));\n * // merge the sphere with the cube\n * const cubeSphereVertices = twgl.primitives.concatVertices(\n * [cubeVertices, sphereVertices]);\n * // turn them into WebGL buffers and attrib data\n * const bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices);\n *\n * @param {module:twgl.Arrays[]} arrays Array of arrays of vertices\n * @return {module:twgl.Arrays} The concatinated vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction concatVertices(arrayOfArrays) {\n var names = {};\n var baseName; // get names of all arrays.\n // and numElements for each set of vertices\n\n var _loop = function _loop(ii) {\n var arrays = arrayOfArrays[ii];\n Object.keys(arrays).forEach(function (name) {\n // eslint-disable-line\n if (!names[name]) {\n names[name] = [];\n }\n\n if (!baseName && name !== 'indices') {\n baseName = name;\n }\n\n var arrayInfo = arrays[name];\n var numComponents = getNumComponents(arrayInfo, name);\n var array = getArray(arrayInfo);\n var numElements = array.length / numComponents;\n names[name].push(numElements);\n });\n };\n\n for (var ii = 0; ii < arrayOfArrays.length; ++ii) {\n _loop(ii);\n } // compute length of combined array\n // and return one for reference\n\n\n function getLengthOfCombinedArrays(name) {\n var length = 0;\n var arraySpec;\n\n for (var ii = 0; ii < arrayOfArrays.length; ++ii) {\n var arrays = arrayOfArrays[ii];\n var arrayInfo = arrays[name];\n var array = getArray(arrayInfo);\n length += array.length;\n\n if (!arraySpec || arrayInfo.data) {\n arraySpec = arrayInfo;\n }\n }\n\n return {\n length: length,\n spec: arraySpec\n };\n }\n\n function copyArraysToNewArray(name, base, newArray) {\n var baseIndex = 0;\n var offset = 0;\n\n for (var ii = 0; ii < arrayOfArrays.length; ++ii) {\n var arrays = arrayOfArrays[ii];\n var arrayInfo = arrays[name];\n var array = getArray(arrayInfo);\n\n if (name === 'indices') {\n copyElements(array, newArray, offset, baseIndex);\n baseIndex += base[ii];\n } else {\n copyElements(array, newArray, offset);\n }\n\n offset += array.length;\n }\n }\n\n var base = names[baseName];\n var newArrays = {};\n Object.keys(names).forEach(function (name) {\n var info = getLengthOfCombinedArrays(name);\n var newArraySpec = createArrayOfSameType(info.spec, info.length);\n copyArraysToNewArray(name, base, getArray(newArraySpec));\n newArrays[name] = newArraySpec;\n });\n return newArrays;\n}\n/**\n * Creates a duplicate set of vertices\n *\n * This is useful for calling reorientVertices when you\n * also want to keep the original available\n *\n * @param {module:twgl.Arrays} arrays of vertices\n * @return {module:twgl.Arrays} The dupilicated vertices.\n * @memberOf module:twgl/primitives\n */\n\n\nfunction duplicateVertices(arrays) {\n var newArrays = {};\n Object.keys(arrays).forEach(function (name) {\n var arraySpec = arrays[name];\n var srcArray = getArray(arraySpec);\n var newArraySpec = createArrayOfSameType(arraySpec, srcArray.length);\n copyElements(srcArray, getArray(newArraySpec), 0);\n newArrays[name] = newArraySpec;\n });\n return newArrays;\n}\n\nvar create3DFBufferInfo = createBufferInfoFunc(create3DFVertices);\nexports.create3DFBufferInfo = create3DFBufferInfo;\nvar create3DFBuffers = createBufferFunc(create3DFVertices);\nexports.create3DFBuffers = create3DFBuffers;\nvar createCubeBufferInfo = createBufferInfoFunc(createCubeVertices);\nexports.createCubeBufferInfo = createCubeBufferInfo;\nvar createCubeBuffers = createBufferFunc(createCubeVertices);\nexports.createCubeBuffers = createCubeBuffers;\nvar createPlaneBufferInfo = createBufferInfoFunc(createPlaneVertices);\nexports.createPlaneBufferInfo = createPlaneBufferInfo;\nvar createPlaneBuffers = createBufferFunc(createPlaneVertices);\nexports.createPlaneBuffers = createPlaneBuffers;\nvar createSphereBufferInfo = createBufferInfoFunc(createSphereVertices);\nexports.createSphereBufferInfo = createSphereBufferInfo;\nvar createSphereBuffers = createBufferFunc(createSphereVertices);\nexports.createSphereBuffers = createSphereBuffers;\nvar createTruncatedConeBufferInfo = createBufferInfoFunc(createTruncatedConeVertices);\nexports.createTruncatedConeBufferInfo = createTruncatedConeBufferInfo;\nvar createTruncatedConeBuffers = createBufferFunc(createTruncatedConeVertices);\nexports.createTruncatedConeBuffers = createTruncatedConeBuffers;\nvar createXYQuadBufferInfo = createBufferInfoFunc(createXYQuadVertices);\nexports.createXYQuadBufferInfo = createXYQuadBufferInfo;\nvar createXYQuadBuffers = createBufferFunc(createXYQuadVertices);\nexports.createXYQuadBuffers = createXYQuadBuffers;\nvar createCresentBufferInfo = createBufferInfoFunc(createCresentVertices);\nexports.createCresentBufferInfo = createCresentBufferInfo;\nvar createCresentBuffers = createBufferFunc(createCresentVertices);\nexports.createCresentBuffers = createCresentBuffers;\nvar createCylinderBufferInfo = createBufferInfoFunc(createCylinderVertices);\nexports.createCylinderBufferInfo = createCylinderBufferInfo;\nvar createCylinderBuffers = createBufferFunc(createCylinderVertices);\nexports.createCylinderBuffers = createCylinderBuffers;\nvar createTorusBufferInfo = createBufferInfoFunc(createTorusVertices);\nexports.createTorusBufferInfo = createTorusBufferInfo;\nvar createTorusBuffers = createBufferFunc(createTorusVertices);\nexports.createTorusBuffers = createTorusBuffers;\nvar createDiscBufferInfo = createBufferInfoFunc(createDiscVertices);\nexports.createDiscBufferInfo = createDiscBufferInfo;\nvar createDiscBuffers = createBufferFunc(createDiscVertices);\nexports.createDiscBuffers = createDiscBuffers;\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nvar _exportNames = {\n addExtensionsToContext: true,\n getContext: true,\n getWebGLContext: true,\n resizeCanvasToDisplaySize: true,\n setDefaults: true\n};\nexports.addExtensionsToContext = addExtensionsToContext;\nexports.getContext = getContext;\nexports.getWebGLContext = getWebGLContext;\nexports.resizeCanvasToDisplaySize = resizeCanvasToDisplaySize;\nexports.setDefaults = setDefaults;\n\nvar attributes = _interopRequireWildcard(__webpack_require__(7));\n\nObject.keys(attributes).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = attributes[key];\n});\n\nvar textures = _interopRequireWildcard(__webpack_require__(8));\n\nObject.keys(textures).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = textures[key];\n});\n\nvar helper = _interopRequireWildcard(__webpack_require__(0));\n\nvar utils = _interopRequireWildcard(__webpack_require__(4));\n\nObject.keys(utils).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = utils[key];\n});\n\nvar _draw = __webpack_require__(12);\n\nObject.keys(_draw).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = _draw[key];\n});\n\nvar _framebuffers = __webpack_require__(13);\n\nObject.keys(_framebuffers).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = _framebuffers[key];\n});\n\nvar _programs = __webpack_require__(5);\n\nObject.keys(_programs).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = _programs[key];\n});\n\nvar _typedarrays = __webpack_require__(1);\n\nObject.keys(_typedarrays).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = _typedarrays[key];\n});\n\nvar _vertexArrays = __webpack_require__(14);\n\nObject.keys(_vertexArrays).forEach(function (key) {\n if (key === \"default\" || key === \"__esModule\") return;\n if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;\n exports[key] = _vertexArrays[key];\n});\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * The main TWGL module.\n *\n * For most use cases you shouldn't need anything outside this module.\n * Exceptions between the stuff added to twgl-full (v3, m4, primitives)\n *\n * @module twgl\n * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray\n * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays\n * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo\n * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo\n * @borrows module:twgl/draw.drawObjectList as drawObjectList\n * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo\n * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo\n * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo\n * @borrows module:twgl/programs.createProgramInfo as createProgramInfo\n * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo\n * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock\n * @borrows module:twgl/programs.setUniformBlock as setUniformBlock\n * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms\n * @borrows module:twgl/programs.setUniforms as setUniforms\n * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes\n * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray\n * @borrows module:twgl/textures.createTexture as createTexture\n * @borrows module:twgl/textures.resizeTexture as resizeTexture\n * @borrows module:twgl/textures.createTextures as createTextures\n */\n// make sure we don't see a global gl\nvar gl = undefined; // eslint-disable-line\n\nvar defaults = {\n addExtensionsToContext: true\n};\n/**\n * Various default settings for twgl.\n *\n * Note: You can call this any number of times. Example:\n *\n * twgl.setDefaults({ textureColor: [1, 0, 0, 1] });\n * twgl.setDefaults({ attribPrefix: 'a_' });\n *\n * is equivalent to\n *\n * twgl.setDefaults({\n * textureColor: [1, 0, 0, 1],\n * attribPrefix: 'a_',\n * });\n *\n * @typedef {Object} Defaults\n * @property {string} attribPrefix The prefix to stick on attributes\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using unprefixed names.\n *\n * In otherwords I'll create arrays of geometry like this\n *\n * const arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * Default: `\"\"`\n *\n * @property {number[]} textureColor Array of 4 values in the range 0 to 1\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * Default: `[0.5, 0.75, 1, 1]`\n *\n * @property {string} crossOrigin\n *\n * If not undefined sets the crossOrigin attribute on images\n * that twgl creates when downloading images for textures.\n *\n * Also see {@link module:twgl.TextureOptions}.\n *\n * @property {bool} addExtensionsToContext\n *\n * If true, then, when twgl will try to add any supported WebGL extensions\n * directly to the context under their normal GL names. For example\n * if ANGLE_instances_arrays exists then twgl would enable it,\n * add the functions `vertexAttribDivisor`, `drawArraysInstanced`,\n * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR`\n * to the `WebGLRenderingContext`.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Sets various defaults for twgl.\n *\n * In the interest of terseness which is kind of the point\n * of twgl I've integrated a few of the older functions here\n *\n * @param {module:twgl.Defaults} newDefaults The default settings.\n * @memberOf module:twgl\n */\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line\n\n textures.setTextureDefaults_(newDefaults); // eslint-disable-line\n}\n\nvar prefixRE = /^(.*?)_/;\n\nfunction addExtensionToContext(gl, extensionName) {\n utils.glEnumToString(gl, 0);\n var ext = gl.getExtension(extensionName);\n\n if (ext) {\n var enums = {};\n var fnSuffix = prefixRE.exec(extensionName)[1];\n var enumSuffix = '_' + fnSuffix;\n\n for (var key in ext) {\n var value = ext[key];\n var isFunc = typeof value === 'function';\n var suffix = isFunc ? fnSuffix : enumSuffix;\n var name = key; // examples of where this is not true are WEBGL_compressed_texture_s3tc\n // and WEBGL_compressed_texture_pvrtc\n\n if (key.endsWith(suffix)) {\n name = key.substring(0, key.length - suffix.length);\n }\n\n if (gl[name] !== undefined) {\n if (!isFunc && gl[name] !== value) {\n helper.warn(name, gl[name], value, key);\n }\n } else {\n if (isFunc) {\n gl[name] = function (origFn) {\n return function () {\n return origFn.apply(ext, arguments);\n };\n }(value);\n } else {\n gl[name] = value;\n enums[name] = value;\n }\n }\n } // pass the modified enums to glEnumToString\n\n\n enums.constructor = {\n name: ext.constructor.name\n };\n utils.glEnumToString(enums, 0);\n }\n\n return ext;\n}\n/*\n * If you're wondering why the code doesn't just iterate\n * over all extensions using `gl.getExtensions` is that it's possible\n * some future extension is incompatible with this code. Rather than\n * have thing suddenly break it seems better to manually add to this\n * list.\n *\n */\n\n\nvar supportedExtensions = ['ANGLE_instanced_arrays', 'EXT_blend_minmax', 'EXT_color_buffer_float', 'EXT_color_buffer_half_float', 'EXT_disjoint_timer_query', 'EXT_disjoint_timer_query_webgl2', 'EXT_frag_depth', 'EXT_sRGB', 'EXT_shader_texture_lod', 'EXT_texture_filter_anisotropic', 'OES_element_index_uint', 'OES_standard_derivatives', 'OES_texture_float', 'OES_texture_float_linear', 'OES_texture_half_float', 'OES_texture_half_float_linear', 'OES_vertex_array_object', 'WEBGL_color_buffer_float', 'WEBGL_compressed_texture_atc', 'WEBGL_compressed_texture_etc1', 'WEBGL_compressed_texture_pvrtc', 'WEBGL_compressed_texture_s3tc', 'WEBGL_compressed_texture_s3tc_srgb', 'WEBGL_depth_texture', 'WEBGL_draw_buffers'];\n/**\n * Attempts to enable all of the following extensions\n * and add their functions and constants to the\n * `WebGLRenderingContext` using their normal non-extension like names.\n *\n * ANGLE_instanced_arrays\n * EXT_blend_minmax\n * EXT_color_buffer_float\n * EXT_color_buffer_half_float\n * EXT_disjoint_timer_query\n * EXT_disjoint_timer_query_webgl2\n * EXT_frag_depth\n * EXT_sRGB\n * EXT_shader_texture_lod\n * EXT_texture_filter_anisotropic\n * OES_element_index_uint\n * OES_standard_derivatives\n * OES_texture_float\n * OES_texture_float_linear\n * OES_texture_half_float\n * OES_texture_half_float_linear\n * OES_vertex_array_object\n * WEBGL_color_buffer_float\n * WEBGL_compressed_texture_atc\n * WEBGL_compressed_texture_etc1\n * WEBGL_compressed_texture_pvrtc\n * WEBGL_compressed_texture_s3tc\n * WEBGL_compressed_texture_s3tc_srgb\n * WEBGL_depth_texture\n * WEBGL_draw_buffers\n *\n * For example if `ANGLE_instanced_arrays` exists then the functions\n * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor`\n * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the\n * `WebGLRenderingContext`.\n *\n * Note that if you want to know if the extension exists you should\n * probably call `gl.getExtension` for each extension. Alternatively\n * you can check for the existance of the functions or constants that\n * are expected to be added. For example\n *\n * if (gl.drawBuffers) {\n * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2\n * ....\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @memberOf module:twgl\n */\n\nfunction addExtensionsToContext(gl) {\n for (var ii = 0; ii < supportedExtensions.length; ++ii) {\n addExtensionToContext(gl, supportedExtensions[ii]);\n }\n}\n/**\n * Creates a webgl context.\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n */\n\n\nfunction create3DContext(canvas, opt_attribs) {\n var names = [\"webgl\", \"experimental-webgl\"];\n var context = null;\n\n for (var ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n\n break;\n }\n }\n\n return context;\n}\n/**\n * Gets a WebGL1 context.\n *\n * Note: Will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextCreationAttirbutes} [opt_attribs] optional webgl context creation attributes\n * @memberOf module:twgl\n */\n\n\nfunction getWebGLContext(canvas, opt_attribs) {\n var gl = create3DContext(canvas, opt_attribs);\n return gl;\n}\n/**\n * Creates a webgl context.\n *\n * Will return a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * twgl.isWebGL2(gl);\n *\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n */\n\n\nfunction createContext(canvas, opt_attribs) {\n var names = [\"webgl2\", \"webgl\", \"experimental-webgl\"];\n var context = null;\n\n for (var ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n\n break;\n }\n }\n\n return context;\n}\n/**\n * Gets a WebGL context. Will create a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * function isWebGL2(gl) {\n * return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0 \") == 0;\n * }\n *\n * Note: For a WebGL1 context will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextCreationAttirbutes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n */\n\n\nfunction getContext(canvas, opt_attribs) {\n var gl = createContext(canvas, opt_attribs);\n return gl;\n}\n/**\n * Resize a canvas to match the size it's displayed.\n * @param {HTMLCanvasElement} canvas The canvas to resize.\n * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to.\n * @return {boolean} true if the canvas was resized.\n * @memberOf module:twgl\n */\n\n\nfunction resizeCanvasToDisplaySize(canvas, multiplier) {\n multiplier = multiplier || 1;\n multiplier = Math.max(0, multiplier);\n var width = canvas.clientWidth * multiplier | 0;\n var height = canvas.clientHeight * multiplier | 0;\n\n if (canvas.width !== width || canvas.height !== height) {\n canvas.width = width;\n canvas.height = height;\n return true;\n }\n\n return false;\n}\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.drawBufferInfo = drawBufferInfo;\nexports.drawObjectList = drawObjectList;\n\nvar programs = _interopRequireWildcard(__webpack_require__(5));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * Drawing related functions\n *\n * For backward compatibily they are available at both `twgl.draw` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/draw\n */\n\n/**\n * Calls `gl.drawElements` or `gl.drawArrays`, whichever is appropriate\n *\n * normally you'd call `gl.drawElements` or `gl.drawArrays` yourself\n * but calling this means if you switch from indexed data to non-indexed\n * data you don't have to remember to update your draw call.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or\n * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @param {enum} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES`\n * @param {number} [count] An optional count. Defaults to bufferInfo.numElements\n * @param {number} [offset] An optional offset. Defaults to 0.\n * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called\n * @memberOf module:twgl/draw\n */\nfunction drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) {\n type = type === undefined ? gl.TRIANGLES : type;\n var indices = bufferInfo.indices;\n var elementType = bufferInfo.elementType;\n var numElements = count === undefined ? bufferInfo.numElements : count;\n offset = offset === undefined ? 0 : offset;\n\n if (elementType || indices) {\n if (instanceCount !== undefined) {\n gl.drawElementsInstanced(type, numElements, elementType === undefined ? gl.UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount);\n } else {\n gl.drawElements(type, numElements, elementType === undefined ? gl.UNSIGNED_SHORT : bufferInfo.elementType, offset);\n }\n } else {\n if (instanceCount !== undefined) {\n gl.drawArraysInstanced(type, offset, numElements, instanceCount);\n } else {\n gl.drawArrays(type, offset, numElements);\n }\n }\n}\n/**\n * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}.\n *\n * You need either a `BufferInfo` or a `VertexArrayInfo`.\n *\n * @typedef {Object} DrawObject\n * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In otherwords `undefined` = `true`\n * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc...\n * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays}\n * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @property {Object} uniforms The values for the uniforms.\n * You can pass multiple objects by putting them in an array. For example\n *\n * var sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * var localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * var drawObj = {\n * ...\n * uniforms: [sharedUniforms, localUniforms],\n * };\n *\n * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0.\n * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElemnts`. Defaults to bufferInfo.numElements.\n * @property {number} [instanceCount] the number of instances. Defaults to undefined.\n * @memberOf module:twgl\n */\n\n/**\n * Draws a list of objects\n * @param {DrawObject[]} objectsToDraw an array of objects to draw.\n * @memberOf module:twgl/draw\n */\n\n\nfunction drawObjectList(gl, objectsToDraw) {\n var lastUsedProgramInfo = null;\n var lastUsedBufferInfo = null;\n objectsToDraw.forEach(function (object) {\n if (object.active === false) {\n return;\n }\n\n var programInfo = object.programInfo;\n var bufferInfo = object.vertexArrayInfo || object.bufferInfo;\n var bindBuffers = false;\n var type = object.type === undefined ? gl.TRIANGLES : object.type;\n\n if (programInfo !== lastUsedProgramInfo) {\n lastUsedProgramInfo = programInfo;\n gl.useProgram(programInfo.program); // We have to rebind buffers when changing programs because we\n // only bind buffers the program uses. So if 2 programs use the same\n // bufferInfo but the 1st one uses only positions the when the\n // we switch to the 2nd one some of the attributes will not be on.\n\n bindBuffers = true;\n } // Setup all the needed attributes.\n\n\n if (bindBuffers || bufferInfo !== lastUsedBufferInfo) {\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n\n lastUsedBufferInfo = bufferInfo;\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n } // Set the uniforms.\n\n\n programs.setUniforms(programInfo, object.uniforms); // Draw\n\n drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount);\n });\n\n if (lastUsedBufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n}\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.bindFramebufferInfo = bindFramebufferInfo;\nexports.createFramebufferInfo = createFramebufferInfo;\nexports.resizeFramebufferInfo = resizeFramebufferInfo;\n\nvar textures = _interopRequireWildcard(__webpack_require__(8));\n\nvar helper = _interopRequireWildcard(__webpack_require__(0));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * Framebuffer related functions\n *\n * For backward compatibily they are available at both `twgl.framebuffer` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/framebuffers\n */\n// make sure we don't see a global gl\nvar gl = undefined; // eslint-disable-line\n\nvar UNSIGNED_BYTE = 0x1401;\n/* PixelFormat */\n\nvar DEPTH_COMPONENT = 0x1902;\nvar RGBA = 0x1908;\n/* Framebuffer Object. */\n\nvar RGBA4 = 0x8056;\nvar RGB5_A1 = 0x8057;\nvar RGB565 = 0x8D62;\nvar DEPTH_COMPONENT16 = 0x81A5;\nvar STENCIL_INDEX = 0x1901;\nvar STENCIL_INDEX8 = 0x8D48;\nvar DEPTH_STENCIL = 0x84F9;\nvar COLOR_ATTACHMENT0 = 0x8CE0;\nvar DEPTH_ATTACHMENT = 0x8D00;\nvar STENCIL_ATTACHMENT = 0x8D20;\nvar DEPTH_STENCIL_ATTACHMENT = 0x821A;\n/* TextureWrapMode */\n\nvar REPEAT = 0x2901; // eslint-disable-line\n\nvar CLAMP_TO_EDGE = 0x812F;\nvar MIRRORED_REPEAT = 0x8370; // eslint-disable-line\n\n/* TextureMagFilter */\n\nvar NEAREST = 0x2600; // eslint-disable-line\n\nvar LINEAR = 0x2601;\n/* TextureMinFilter */\n\nvar NEAREST_MIPMAP_NEAREST = 0x2700; // eslint-disable-line\n\nvar LINEAR_MIPMAP_NEAREST = 0x2701; // eslint-disable-line\n\nvar NEAREST_MIPMAP_LINEAR = 0x2702; // eslint-disable-line\n\nvar LINEAR_MIPMAP_LINEAR = 0x2703; // eslint-disable-line\n\n/**\n * The options for a framebuffer attachment.\n *\n * Note: For a `format` that is a texture include all the texture\n * options from {@link module:twgl.TextureOptions} for example\n * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions}\n * `auto` defaults to `false` for attachment textures but `min` and `mag` default\n * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE`\n *\n * @typedef {Object} AttachmentOptions\n * @property {number} [attach] The attachment point. Defaults\n * to `gl.COLOR_ATTACTMENT0 + ndx` unless type is a depth or stencil type\n * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending\n * on the format or attachment type.\n * @property {number} [format] The format. If one of `gl.RGBA4`,\n * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`,\n * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a\n * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA`\n * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`.\n * @property {number} [target] The texture target for `gl.framebufferTexture2D`.\n * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps.\n * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0.\n * @property {WebGLObject} [attachment] An existing renderbuffer or texture.\n * If provided will attach this Object. This allows you to share\n * attachemnts across framebuffers.\n * @memberOf module:twgl\n */\n\nvar defaultAttachments = [{\n format: RGBA,\n type: UNSIGNED_BYTE,\n min: LINEAR,\n wrap: CLAMP_TO_EDGE\n}, {\n format: DEPTH_STENCIL\n}];\nvar attachmentsByFormat = {};\nattachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT;\n\nfunction getAttachmentPointForFormat(format) {\n return attachmentsByFormat[format];\n}\n\nvar renderbufferFormats = {};\nrenderbufferFormats[RGBA4] = true;\nrenderbufferFormats[RGB5_A1] = true;\nrenderbufferFormats[RGB565] = true;\nrenderbufferFormats[DEPTH_STENCIL] = true;\nrenderbufferFormats[DEPTH_COMPONENT16] = true;\nrenderbufferFormats[STENCIL_INDEX] = true;\nrenderbufferFormats[STENCIL_INDEX8] = true;\n\nfunction isRenderbufferFormat(format) {\n return renderbufferFormats[format];\n}\n/**\n * @typedef {Object} FramebufferInfo\n * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo\n * @property {WebGLObject[]} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}.\n * @memberOf module:twgl\n */\n\n/**\n * Creates a framebuffer and attachments.\n *\n * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * Passing in a specific size\n *\n * const width = 256;\n * const height = 256;\n * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height);\n *\n * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`.\n * [WebGL only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6).\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an\n * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Defautt = size of drawingBuffer\n * @return {module:twgl.FramebufferInfo} the framebuffer and attachments.\n * @memberOf module:twgl/framebuffers\n */\n\n\nfunction createFramebufferInfo(gl, attachments, width, height) {\n var target = gl.FRAMEBUFFER;\n var fb = gl.createFramebuffer();\n gl.bindFramebuffer(target, fb);\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n attachments = attachments || defaultAttachments;\n var colorAttachmentCount = 0;\n var framebufferInfo = {\n framebuffer: fb,\n attachments: [],\n width: width,\n height: height\n };\n attachments.forEach(function (attachmentOptions) {\n var attachment = attachmentOptions.attachment;\n var format = attachmentOptions.format;\n var attachmentPoint = getAttachmentPointForFormat(format);\n\n if (!attachmentPoint) {\n attachmentPoint = COLOR_ATTACHMENT0 + colorAttachmentCount++;\n }\n\n if (!attachment) {\n if (isRenderbufferFormat(format)) {\n attachment = gl.createRenderbuffer();\n gl.bindRenderbuffer(gl.RENDERBUFFER, attachment);\n gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height);\n } else {\n var textureOptions = Object.assign({}, attachmentOptions);\n textureOptions.width = width;\n textureOptions.height = height;\n\n if (textureOptions.auto === undefined) {\n textureOptions.auto = false;\n textureOptions.min = textureOptions.min || textureOptions.minMag || gl.LINEAR;\n textureOptions.mag = textureOptions.mag || textureOptions.minMag || gl.LINEAR;\n textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || gl.CLAMP_TO_EDGE;\n textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || gl.CLAMP_TO_EDGE;\n }\n\n attachment = textures.createTexture(gl, textureOptions);\n }\n }\n\n if (helper.isRenderbuffer(gl, attachment)) {\n gl.framebufferRenderbuffer(target, attachmentPoint, gl.RENDERBUFFER, attachment);\n } else if (helper.isTexture(gl, attachment)) {\n gl.framebufferTexture2D(target, attachmentPoint, attachmentOptions.texTarget || gl.TEXTURE_2D, attachment, attachmentOptions.level || 0);\n } else {\n throw \"unknown attachment type\";\n }\n\n framebufferInfo.attachments.push(attachment);\n });\n return framebufferInfo;\n}\n/**\n * Resizes the attachments of a framebuffer.\n *\n * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo}\n * because TWGL has no idea the format/type of each attachment.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments\n * twgl.resizeFramebufferInfo(gl, fbi);\n * }\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments to match\n * twgl.resizeFramebufferInfo(gl, fbi, attachments);\n * }\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Defautt = size of drawingBuffer\n * @memberOf module:twgl/framebuffers\n */\n\n\nfunction resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) {\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n framebufferInfo.width = width;\n framebufferInfo.height = height;\n attachments = attachments || defaultAttachments;\n attachments.forEach(function (attachmentOptions, ndx) {\n var attachment = framebufferInfo.attachments[ndx];\n var format = attachmentOptions.format;\n\n if (helper.isRenderbuffer(gl, attachment)) {\n gl.bindRenderbuffer(gl.RENDERBUFFER, attachment);\n gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height);\n } else if (helper.isTexture(gl, attachment)) {\n textures.resizeTexture(gl, attachment, attachmentOptions, width, height);\n } else {\n throw \"unknown attachment type\";\n }\n });\n}\n/**\n * Binds a framebuffer\n *\n * This function pretty much soley exists because I spent hours\n * trying to figure out why something I wrote wasn't working only\n * to realize I forget to set the viewport dimensions.\n * My hope is this function will fix that.\n *\n * It is effectively the same as\n *\n * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer);\n * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height);\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * If not passed will bind the canvas.\n * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used.\n * @memberOf module:twgl/framebuffers\n */\n\n\nfunction bindFramebufferInfo(gl, framebufferInfo, target) {\n target = target || gl.FRAMEBUFFER;\n\n if (framebufferInfo) {\n gl.bindFramebuffer(target, framebufferInfo.framebuffer);\n gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height);\n } else {\n gl.bindFramebuffer(target, null);\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n}\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\nexports.createVertexArrayInfo = createVertexArrayInfo;\nexports.createVAOAndSetAttributes = createVAOAndSetAttributes;\nexports.createVAOFromBufferInfo = createVAOFromBufferInfo;\n\nvar programs = _interopRequireWildcard(__webpack_require__(5));\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }\n\n/*\n * Copyright 2015, Gregg Tavares.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following disclaimer\n * in the documentation and/or other materials provided with the\n * distribution.\n * * Neither the name of Gregg Tavares. nor the names of his\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * vertex array object related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibily they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/vertexArrays\n */\n\n/**\n * @typedef {Object} VertexArrayInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object\n * @memberOf module:twgl\n */\n\n/**\n * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects\n * assign buffers to specific attributes at creation time. That means they can only be used with programs\n * who's attributes use the same attribute locations for the same purposes.\n *\n * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo}\n * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match.\n *\n * also\n *\n * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object\n * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES**\n * will affect the Vertex Array Object state.\n *\n * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n *\n * You need to make sure every attribute that will be used is bound. So for example assume shader 1\n * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo\n * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't\n * now attribute D's location.\n *\n * So, you can pass in both shader 1 and shader 2's programInfo\n *\n * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVertexArrayInfo(gl, programInfos, bufferInfo) {\n var vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n\n if (!programInfos.length) {\n programInfos = [programInfos];\n }\n\n programInfos.forEach(function (programInfo) {\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n });\n gl.bindVertexArray(null);\n return {\n numElements: bufferInfo.numElements,\n elementType: bufferInfo.elementType,\n vertexArrayObject: vao\n };\n}\n/**\n * Creates a vertex array object and then sets the attributes on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} attribs AttribInfos mapped by attribute name.\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n * @memberOf module:twgl/vertexArrays\n */\n\n\nfunction createVAOAndSetAttributes(gl, setters, attribs, indices) {\n var vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n programs.setAttributes(setters, attribs);\n\n if (indices) {\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices);\n } // We unbind this because otherwise any change to ELEMENT_ARRAY_BUFFER\n // like when creating buffers for other stuff will mess up this VAO's binding\n\n\n gl.bindVertexArray(null);\n return vao;\n}\n/**\n * Creates a vertex array object and then sets the attributes\n * on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {Object.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n * @memberOf module:twgl/vertexArrays\n */\n\n\nfunction createVAOFromBufferInfo(gl, programInfo, bufferInfo) {\n return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices);\n}\n\n/***/ })\n/******/ ]);\n});","// Generated by CoffeeScript 1.7.1\nvar UnicodeTrie, inflate;\n\ninflate = require('tiny-inflate');\n\nUnicodeTrie = (function() {\n var DATA_BLOCK_LENGTH, DATA_GRANULARITY, DATA_MASK, INDEX_1_OFFSET, INDEX_2_BLOCK_LENGTH, INDEX_2_BMP_LENGTH, INDEX_2_MASK, INDEX_SHIFT, LSCP_INDEX_2_LENGTH, LSCP_INDEX_2_OFFSET, OMITTED_BMP_INDEX_1_LENGTH, SHIFT_1, SHIFT_1_2, SHIFT_2, UTF8_2B_INDEX_2_LENGTH, UTF8_2B_INDEX_2_OFFSET;\n\n SHIFT_1 = 6 + 5;\n\n SHIFT_2 = 5;\n\n SHIFT_1_2 = SHIFT_1 - SHIFT_2;\n\n OMITTED_BMP_INDEX_1_LENGTH = 0x10000 >> SHIFT_1;\n\n INDEX_2_BLOCK_LENGTH = 1 << SHIFT_1_2;\n\n INDEX_2_MASK = INDEX_2_BLOCK_LENGTH - 1;\n\n INDEX_SHIFT = 2;\n\n DATA_BLOCK_LENGTH = 1 << SHIFT_2;\n\n DATA_MASK = DATA_BLOCK_LENGTH - 1;\n\n LSCP_INDEX_2_OFFSET = 0x10000 >> SHIFT_2;\n\n LSCP_INDEX_2_LENGTH = 0x400 >> SHIFT_2;\n\n INDEX_2_BMP_LENGTH = LSCP_INDEX_2_OFFSET + LSCP_INDEX_2_LENGTH;\n\n UTF8_2B_INDEX_2_OFFSET = INDEX_2_BMP_LENGTH;\n\n UTF8_2B_INDEX_2_LENGTH = 0x800 >> 6;\n\n INDEX_1_OFFSET = UTF8_2B_INDEX_2_OFFSET + UTF8_2B_INDEX_2_LENGTH;\n\n DATA_GRANULARITY = 1 << INDEX_SHIFT;\n\n function UnicodeTrie(data) {\n var isBuffer, uncompressedLength, view;\n isBuffer = typeof data.readUInt32BE === 'function' && typeof data.slice === 'function';\n if (isBuffer || data instanceof Uint8Array) {\n if (isBuffer) {\n this.highStart = data.readUInt32BE(0);\n this.errorValue = data.readUInt32BE(4);\n uncompressedLength = data.readUInt32BE(8);\n data = data.slice(12);\n } else {\n view = new DataView(data.buffer);\n this.highStart = view.getUint32(0);\n this.errorValue = view.getUint32(4);\n uncompressedLength = view.getUint32(8);\n data = data.subarray(12);\n }\n data = inflate(data, new Uint8Array(uncompressedLength));\n data = inflate(data, new Uint8Array(uncompressedLength));\n this.data = new Uint32Array(data.buffer);\n } else {\n this.data = data.data, this.highStart = data.highStart, this.errorValue = data.errorValue;\n }\n }\n\n UnicodeTrie.prototype.get = function(codePoint) {\n var index;\n if (codePoint < 0 || codePoint > 0x10ffff) {\n return this.errorValue;\n }\n if (codePoint < 0xd800 || (codePoint > 0xdbff && codePoint <= 0xffff)) {\n index = (this.data[codePoint >> SHIFT_2] << INDEX_SHIFT) + (codePoint & DATA_MASK);\n return this.data[index];\n }\n if (codePoint <= 0xffff) {\n index = (this.data[LSCP_INDEX_2_OFFSET + ((codePoint - 0xd800) >> SHIFT_2)] << INDEX_SHIFT) + (codePoint & DATA_MASK);\n return this.data[index];\n }\n if (codePoint < this.highStart) {\n index = this.data[(INDEX_1_OFFSET - OMITTED_BMP_INDEX_1_LENGTH) + (codePoint >> SHIFT_1)];\n index = this.data[index + ((codePoint >> SHIFT_2) & INDEX_2_MASK)];\n index = (index << INDEX_SHIFT) + (codePoint & DATA_MASK);\n return this.data[index];\n }\n return this.data[this.data.length - DATA_GRANULARITY];\n };\n\n return UnicodeTrie;\n\n})();\n\nmodule.exports = UnicodeTrie;\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar punycode = require('punycode');\nvar util = require('./util');\n\nexports.parse = urlParse;\nexports.resolve = urlResolve;\nexports.resolveObject = urlResolveObject;\nexports.format = urlFormat;\n\nexports.Url = Url;\n\nfunction Url() {\n this.protocol = null;\n this.slashes = null;\n this.auth = null;\n this.host = null;\n this.port = null;\n this.hostname = null;\n this.hash = null;\n this.search = null;\n this.query = null;\n this.pathname = null;\n this.path = null;\n this.href = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n\n// define these here so at least they only have to be\n// compiled once on the first module load.\nvar protocolPattern = /^([a-z0-9.+-]+:)/i,\n portPattern = /:[0-9]*$/,\n\n // Special case for a simple path URL\n simplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/,\n\n // RFC 2396: characters reserved for delimiting URLs.\n // We actually just auto-escape these.\n delims = ['<', '>', '\"', '`', ' ', '\\r', '\\n', '\\t'],\n\n // RFC 2396: characters not allowed for various reasons.\n unwise = ['{', '}', '|', '\\\\', '^', '`'].concat(delims),\n\n // Allowed by RFCs, but cause of XSS attacks. Always escape these.\n autoEscape = ['\\''].concat(unwise),\n // Characters that are never ever allowed in a hostname.\n // Note that any invalid chars are also handled, but these\n // are the ones that are *expected* to be seen, so we fast-path\n // them.\n nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),\n hostEndingChars = ['/', '?', '#'],\n hostnameMaxLen = 255,\n hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,\n hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,\n // protocols that can allow \"unsafe\" and \"unwise\" chars.\n unsafeProtocol = {\n 'javascript': true,\n 'javascript:': true\n },\n // protocols that never have a hostname.\n hostlessProtocol = {\n 'javascript': true,\n 'javascript:': true\n },\n // protocols that always contain a // bit.\n slashedProtocol = {\n 'http': true,\n 'https': true,\n 'ftp': true,\n 'gopher': true,\n 'file': true,\n 'http:': true,\n 'https:': true,\n 'ftp:': true,\n 'gopher:': true,\n 'file:': true\n },\n querystring = require('querystring');\n\nfunction urlParse(url, parseQueryString, slashesDenoteHost) {\n if (url && util.isObject(url) && url instanceof Url) return url;\n\n var u = new Url;\n u.parse(url, parseQueryString, slashesDenoteHost);\n return u;\n}\n\nUrl.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {\n if (!util.isString(url)) {\n throw new TypeError(\"Parameter 'url' must be a string, not \" + typeof url);\n }\n\n // Copy chrome, IE, opera backslash-handling behavior.\n // Back slashes before the query string get converted to forward slashes\n // See: https://code.google.com/p/chromium/issues/detail?id=25916\n var queryIndex = url.indexOf('?'),\n splitter =\n (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',\n uSplit = url.split(splitter),\n slashRegex = /\\\\/g;\n uSplit[0] = uSplit[0].replace(slashRegex, '/');\n url = uSplit.join(splitter);\n\n var rest = url;\n\n // trim before proceeding.\n // This is to support parse stuff like \" http://foo.com \\n\"\n rest = rest.trim();\n\n if (!slashesDenoteHost && url.split('#').length === 1) {\n // Try fast path regexp\n var simplePath = simplePathPattern.exec(rest);\n if (simplePath) {\n this.path = rest;\n this.href = rest;\n this.pathname = simplePath[1];\n if (simplePath[2]) {\n this.search = simplePath[2];\n if (parseQueryString) {\n this.query = querystring.parse(this.search.substr(1));\n } else {\n this.query = this.search.substr(1);\n }\n } else if (parseQueryString) {\n this.search = '';\n this.query = {};\n }\n return this;\n }\n }\n\n var proto = protocolPattern.exec(rest);\n if (proto) {\n proto = proto[0];\n var lowerProto = proto.toLowerCase();\n this.protocol = lowerProto;\n rest = rest.substr(proto.length);\n }\n\n // figure out if it's got a host\n // user@server is *always* interpreted as a hostname, and url\n // resolution will treat //foo/bar as host=foo,path=bar because that's\n // how the browser resolves relative URLs.\n if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n var slashes = rest.substr(0, 2) === '//';\n if (slashes && !(proto && hostlessProtocol[proto])) {\n rest = rest.substr(2);\n this.slashes = true;\n }\n }\n\n if (!hostlessProtocol[proto] &&\n (slashes || (proto && !slashedProtocol[proto]))) {\n\n // there's a hostname.\n // the first instance of /, ?, ;, or # ends the host.\n //\n // If there is an @ in the hostname, then non-host chars *are* allowed\n // to the left of the last @ sign, unless some host-ending character\n // comes *before* the @-sign.\n // URLs are obnoxious.\n //\n // ex:\n // http://a@b@c/ => user:a@b host:c\n // http://a@b?@c => user:a host:c path:/?@c\n\n // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n // Review our test case against browsers more comprehensively.\n\n // find the first instance of any hostEndingChars\n var hostEnd = -1;\n for (var i = 0; i < hostEndingChars.length; i++) {\n var hec = rest.indexOf(hostEndingChars[i]);\n if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n hostEnd = hec;\n }\n\n // at this point, either we have an explicit point where the\n // auth portion cannot go past, or the last @ char is the decider.\n var auth, atSign;\n if (hostEnd === -1) {\n // atSign can be anywhere.\n atSign = rest.lastIndexOf('@');\n } else {\n // atSign must be in auth portion.\n // http://a@b/c@d => host:b auth:a path:/c@d\n atSign = rest.lastIndexOf('@', hostEnd);\n }\n\n // Now we have a portion which is definitely the auth.\n // Pull that off.\n if (atSign !== -1) {\n auth = rest.slice(0, atSign);\n rest = rest.slice(atSign + 1);\n this.auth = decodeURIComponent(auth);\n }\n\n // the host is the remaining to the left of the first non-host char\n hostEnd = -1;\n for (var i = 0; i < nonHostChars.length; i++) {\n var hec = rest.indexOf(nonHostChars[i]);\n if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))\n hostEnd = hec;\n }\n // if we still have not hit it, then the entire thing is a host.\n if (hostEnd === -1)\n hostEnd = rest.length;\n\n this.host = rest.slice(0, hostEnd);\n rest = rest.slice(hostEnd);\n\n // pull out port.\n this.parseHost();\n\n // we've indicated that there is a hostname,\n // so even if it's empty, it has to be present.\n this.hostname = this.hostname || '';\n\n // if hostname begins with [ and ends with ]\n // assume that it's an IPv6 address.\n var ipv6Hostname = this.hostname[0] === '[' &&\n this.hostname[this.hostname.length - 1] === ']';\n\n // validate a little.\n if (!ipv6Hostname) {\n var hostparts = this.hostname.split(/\\./);\n for (var i = 0, l = hostparts.length; i < l; i++) {\n var part = hostparts[i];\n if (!part) continue;\n if (!part.match(hostnamePartPattern)) {\n var newpart = '';\n for (var j = 0, k = part.length; j < k; j++) {\n if (part.charCodeAt(j) > 127) {\n // we replace non-ASCII char with a temporary placeholder\n // we need this to make sure size of hostname is not\n // broken by replacing non-ASCII by nothing\n newpart += 'x';\n } else {\n newpart += part[j];\n }\n }\n // we test again with ASCII char only\n if (!newpart.match(hostnamePartPattern)) {\n var validParts = hostparts.slice(0, i);\n var notHost = hostparts.slice(i + 1);\n var bit = part.match(hostnamePartStart);\n if (bit) {\n validParts.push(bit[1]);\n notHost.unshift(bit[2]);\n }\n if (notHost.length) {\n rest = '/' + notHost.join('.') + rest;\n }\n this.hostname = validParts.join('.');\n break;\n }\n }\n }\n }\n\n if (this.hostname.length > hostnameMaxLen) {\n this.hostname = '';\n } else {\n // hostnames are always lower case.\n this.hostname = this.hostname.toLowerCase();\n }\n\n if (!ipv6Hostname) {\n // IDNA Support: Returns a punycoded representation of \"domain\".\n // It only converts parts of the domain name that\n // have non-ASCII characters, i.e. it doesn't matter if\n // you call it with a domain that already is ASCII-only.\n this.hostname = punycode.toASCII(this.hostname);\n }\n\n var p = this.port ? ':' + this.port : '';\n var h = this.hostname || '';\n this.host = h + p;\n this.href += this.host;\n\n // strip [ and ] from the hostname\n // the host field still retains them, though\n if (ipv6Hostname) {\n this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n if (rest[0] !== '/') {\n rest = '/' + rest;\n }\n }\n }\n\n // now rest is set to the post-host stuff.\n // chop off any delim chars.\n if (!unsafeProtocol[lowerProto]) {\n\n // First, make 100% sure that any \"autoEscape\" chars get\n // escaped, even if encodeURIComponent doesn't think they\n // need to be.\n for (var i = 0, l = autoEscape.length; i < l; i++) {\n var ae = autoEscape[i];\n if (rest.indexOf(ae) === -1)\n continue;\n var esc = encodeURIComponent(ae);\n if (esc === ae) {\n esc = escape(ae);\n }\n rest = rest.split(ae).join(esc);\n }\n }\n\n\n // chop off from the tail first.\n var hash = rest.indexOf('#');\n if (hash !== -1) {\n // got a fragment string.\n this.hash = rest.substr(hash);\n rest = rest.slice(0, hash);\n }\n var qm = rest.indexOf('?');\n if (qm !== -1) {\n this.search = rest.substr(qm);\n this.query = rest.substr(qm + 1);\n if (parseQueryString) {\n this.query = querystring.parse(this.query);\n }\n rest = rest.slice(0, qm);\n } else if (parseQueryString) {\n // no query string, but parseQueryString still requested\n this.search = '';\n this.query = {};\n }\n if (rest) this.pathname = rest;\n if (slashedProtocol[lowerProto] &&\n this.hostname && !this.pathname) {\n this.pathname = '/';\n }\n\n //to support http.request\n if (this.pathname || this.search) {\n var p = this.pathname || '';\n var s = this.search || '';\n this.path = p + s;\n }\n\n // finally, reconstruct the href based on what has been validated.\n this.href = this.format();\n return this;\n};\n\n// format a parsed object into a url string\nfunction urlFormat(obj) {\n // ensure it's an object, and not a string url.\n // If it's an obj, this is a no-op.\n // this way, you can call url_format() on strings\n // to clean up potentially wonky urls.\n if (util.isString(obj)) obj = urlParse(obj);\n if (!(obj instanceof Url)) return Url.prototype.format.call(obj);\n return obj.format();\n}\n\nUrl.prototype.format = function() {\n var auth = this.auth || '';\n if (auth) {\n auth = encodeURIComponent(auth);\n auth = auth.replace(/%3A/i, ':');\n auth += '@';\n }\n\n var protocol = this.protocol || '',\n pathname = this.pathname || '',\n hash = this.hash || '',\n host = false,\n query = '';\n\n if (this.host) {\n host = auth + this.host;\n } else if (this.hostname) {\n host = auth + (this.hostname.indexOf(':') === -1 ?\n this.hostname :\n '[' + this.hostname + ']');\n if (this.port) {\n host += ':' + this.port;\n }\n }\n\n if (this.query &&\n util.isObject(this.query) &&\n Object.keys(this.query).length) {\n query = querystring.stringify(this.query);\n }\n\n var search = this.search || (query && ('?' + query)) || '';\n\n if (protocol && protocol.substr(-1) !== ':') protocol += ':';\n\n // only the slashedProtocols get the //. Not mailto:, xmpp:, etc.\n // unless they had them to begin with.\n if (this.slashes ||\n (!protocol || slashedProtocol[protocol]) && host !== false) {\n host = '//' + (host || '');\n if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;\n } else if (!host) {\n host = '';\n }\n\n if (hash && hash.charAt(0) !== '#') hash = '#' + hash;\n if (search && search.charAt(0) !== '?') search = '?' + search;\n\n pathname = pathname.replace(/[?#]/g, function(match) {\n return encodeURIComponent(match);\n });\n search = search.replace('#', '%23');\n\n return protocol + host + pathname + search + hash;\n};\n\nfunction urlResolve(source, relative) {\n return urlParse(source, false, true).resolve(relative);\n}\n\nUrl.prototype.resolve = function(relative) {\n return this.resolveObject(urlParse(relative, false, true)).format();\n};\n\nfunction urlResolveObject(source, relative) {\n if (!source) return relative;\n return urlParse(source, false, true).resolveObject(relative);\n}\n\nUrl.prototype.resolveObject = function(relative) {\n if (util.isString(relative)) {\n var rel = new Url();\n rel.parse(relative, false, true);\n relative = rel;\n }\n\n var result = new Url();\n var tkeys = Object.keys(this);\n for (var tk = 0; tk < tkeys.length; tk++) {\n var tkey = tkeys[tk];\n result[tkey] = this[tkey];\n }\n\n // hash is always overridden, no matter what.\n // even href=\"\" will remove it.\n result.hash = relative.hash;\n\n // if the relative url is empty, then there's nothing left to do here.\n if (relative.href === '') {\n result.href = result.format();\n return result;\n }\n\n // hrefs like //foo/bar always cut to the protocol.\n if (relative.slashes && !relative.protocol) {\n // take everything except the protocol from relative\n var rkeys = Object.keys(relative);\n for (var rk = 0; rk < rkeys.length; rk++) {\n var rkey = rkeys[rk];\n if (rkey !== 'protocol')\n result[rkey] = relative[rkey];\n }\n\n //urlParse appends trailing / to urls like http://www.example.com\n if (slashedProtocol[result.protocol] &&\n result.hostname && !result.pathname) {\n result.path = result.pathname = '/';\n }\n\n result.href = result.format();\n return result;\n }\n\n if (relative.protocol && relative.protocol !== result.protocol) {\n // if it's a known url protocol, then changing\n // the protocol does weird things\n // first, if it's not file:, then we MUST have a host,\n // and if there was a path\n // to begin with, then we MUST have a path.\n // if it is file:, then the host is dropped,\n // because that's known to be hostless.\n // anything else is assumed to be absolute.\n if (!slashedProtocol[relative.protocol]) {\n var keys = Object.keys(relative);\n for (var v = 0; v < keys.length; v++) {\n var k = keys[v];\n result[k] = relative[k];\n }\n result.href = result.format();\n return result;\n }\n\n result.protocol = relative.protocol;\n if (!relative.host && !hostlessProtocol[relative.protocol]) {\n var relPath = (relative.pathname || '').split('/');\n while (relPath.length && !(relative.host = relPath.shift()));\n if (!relative.host) relative.host = '';\n if (!relative.hostname) relative.hostname = '';\n if (relPath[0] !== '') relPath.unshift('');\n if (relPath.length < 2) relPath.unshift('');\n result.pathname = relPath.join('/');\n } else {\n result.pathname = relative.pathname;\n }\n result.search = relative.search;\n result.query = relative.query;\n result.host = relative.host || '';\n result.auth = relative.auth;\n result.hostname = relative.hostname || relative.host;\n result.port = relative.port;\n // to support http.request\n if (result.pathname || result.search) {\n var p = result.pathname || '';\n var s = result.search || '';\n result.path = p + s;\n }\n result.slashes = result.slashes || relative.slashes;\n result.href = result.format();\n return result;\n }\n\n var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),\n isRelAbs = (\n relative.host ||\n relative.pathname && relative.pathname.charAt(0) === '/'\n ),\n mustEndAbs = (isRelAbs || isSourceAbs ||\n (result.host && relative.pathname)),\n removeAllDots = mustEndAbs,\n srcPath = result.pathname && result.pathname.split('/') || [],\n relPath = relative.pathname && relative.pathname.split('/') || [],\n psychotic = result.protocol && !slashedProtocol[result.protocol];\n\n // if the url is a non-slashed url, then relative\n // links like ../.. should be able\n // to crawl up to the hostname, as well. This is strange.\n // result.protocol has already been set by now.\n // Later on, put the first path part into the host field.\n if (psychotic) {\n result.hostname = '';\n result.port = null;\n if (result.host) {\n if (srcPath[0] === '') srcPath[0] = result.host;\n else srcPath.unshift(result.host);\n }\n result.host = '';\n if (relative.protocol) {\n relative.hostname = null;\n relative.port = null;\n if (relative.host) {\n if (relPath[0] === '') relPath[0] = relative.host;\n else relPath.unshift(relative.host);\n }\n relative.host = null;\n }\n mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');\n }\n\n if (isRelAbs) {\n // it's absolute.\n result.host = (relative.host || relative.host === '') ?\n relative.host : result.host;\n result.hostname = (relative.hostname || relative.hostname === '') ?\n relative.hostname : result.hostname;\n result.search = relative.search;\n result.query = relative.query;\n srcPath = relPath;\n // fall through to the dot-handling below.\n } else if (relPath.length) {\n // it's relative\n // throw away the existing file, and take the new path instead.\n if (!srcPath) srcPath = [];\n srcPath.pop();\n srcPath = srcPath.concat(relPath);\n result.search = relative.search;\n result.query = relative.query;\n } else if (!util.isNullOrUndefined(relative.search)) {\n // just pull out the search.\n // like href='?foo'.\n // Put this after the other two cases because it simplifies the booleans\n if (psychotic) {\n result.hostname = result.host = srcPath.shift();\n //occationaly the auth can get stuck only in host\n //this especially happens in cases like\n //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n var authInHost = result.host && result.host.indexOf('@') > 0 ?\n result.host.split('@') : false;\n if (authInHost) {\n result.auth = authInHost.shift();\n result.host = result.hostname = authInHost.shift();\n }\n }\n result.search = relative.search;\n result.query = relative.query;\n //to support http.request\n if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n result.path = (result.pathname ? result.pathname : '') +\n (result.search ? result.search : '');\n }\n result.href = result.format();\n return result;\n }\n\n if (!srcPath.length) {\n // no path at all. easy.\n // we've already handled the other stuff above.\n result.pathname = null;\n //to support http.request\n if (result.search) {\n result.path = '/' + result.search;\n } else {\n result.path = null;\n }\n result.href = result.format();\n return result;\n }\n\n // if a url ENDs in . or .., then it must get a trailing slash.\n // however, if it ends in anything else non-slashy,\n // then it must NOT get a trailing slash.\n var last = srcPath.slice(-1)[0];\n var hasTrailingSlash = (\n (result.host || relative.host || srcPath.length > 1) &&\n (last === '.' || last === '..') || last === '');\n\n // strip single dots, resolve double dots to parent dir\n // if the path tries to go above the root, `up` ends up > 0\n var up = 0;\n for (var i = srcPath.length; i >= 0; i--) {\n last = srcPath[i];\n if (last === '.') {\n srcPath.splice(i, 1);\n } else if (last === '..') {\n srcPath.splice(i, 1);\n up++;\n } else if (up) {\n srcPath.splice(i, 1);\n up--;\n }\n }\n\n // if the path is allowed to go above the root, restore leading ..s\n if (!mustEndAbs && !removeAllDots) {\n for (; up--; up) {\n srcPath.unshift('..');\n }\n }\n\n if (mustEndAbs && srcPath[0] !== '' &&\n (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {\n srcPath.unshift('');\n }\n\n if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {\n srcPath.push('');\n }\n\n var isAbsolute = srcPath[0] === '' ||\n (srcPath[0] && srcPath[0].charAt(0) === '/');\n\n // put the host back\n if (psychotic) {\n result.hostname = result.host = isAbsolute ? '' :\n srcPath.length ? srcPath.shift() : '';\n //occationaly the auth can get stuck only in host\n //this especially happens in cases like\n //url.resolveObject('mailto:local1@domain1', 'local2@domain2')\n var authInHost = result.host && result.host.indexOf('@') > 0 ?\n result.host.split('@') : false;\n if (authInHost) {\n result.auth = authInHost.shift();\n result.host = result.hostname = authInHost.shift();\n }\n }\n\n mustEndAbs = mustEndAbs || (result.host && srcPath.length);\n\n if (mustEndAbs && !isAbsolute) {\n srcPath.unshift('');\n }\n\n if (!srcPath.length) {\n result.pathname = null;\n result.path = null;\n } else {\n result.pathname = srcPath.join('/');\n }\n\n //to support request.http\n if (!util.isNull(result.pathname) || !util.isNull(result.search)) {\n result.path = (result.pathname ? result.pathname : '') +\n (result.search ? result.search : '');\n }\n result.auth = relative.auth || result.auth;\n result.slashes = result.slashes || relative.slashes;\n result.href = result.format();\n return result;\n};\n\nUrl.prototype.parseHost = function() {\n var host = this.host;\n var port = portPattern.exec(host);\n if (port) {\n port = port[0];\n if (port !== ':') {\n this.port = port.substr(1);\n }\n host = host.substr(0, host.length - port.length);\n }\n if (host) this.hostname = host;\n};\n","'use strict';\n\nmodule.exports = {\n isString: function(arg) {\n return typeof(arg) === 'string';\n },\n isObject: function(arg) {\n return typeof(arg) === 'object' && arg !== null;\n },\n isNull: function(arg) {\n return arg === null;\n },\n isNullOrUndefined: function(arg) {\n return arg == null;\n }\n};\n","\n/**\n * Module exports.\n */\n\nmodule.exports = deprecate;\n\n/**\n * Mark that a method should not be used.\n * Returns a modified function which warns once by default.\n *\n * If `localStorage.noDeprecation = true` is set, then it is a no-op.\n *\n * If `localStorage.throwDeprecation = true` is set, then deprecated functions\n * will throw an Error when invoked.\n *\n * If `localStorage.traceDeprecation = true` is set, then deprecated functions\n * will invoke `console.trace()` instead of `console.error()`.\n *\n * @param {Function} fn - the function to deprecate\n * @param {String} msg - the string to print to the console when `fn` is invoked\n * @returns {Function} a new \"deprecated\" version of `fn`\n * @api public\n */\n\nfunction deprecate (fn, msg) {\n if (config('noDeprecation')) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (config('throwDeprecation')) {\n throw new Error(msg);\n } else if (config('traceDeprecation')) {\n console.trace(msg);\n } else {\n console.warn(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n}\n\n/**\n * Checks `localStorage` for boolean values for the given `name`.\n *\n * @param {String} name\n * @returns {Boolean}\n * @api private\n */\n\nfunction config (name) {\n // accessing global.localStorage can trigger a DOMException in sandboxed iframes\n try {\n if (!global.localStorage) return false;\n } catch (_) {\n return false;\n }\n var val = global.localStorage[name];\n if (null == val) return false;\n return String(val).toLowerCase() === 'true';\n}\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar __DEV__ = process.env.NODE_ENV !== 'production';\n\nvar warning = function() {};\n\nif (__DEV__) {\n var printWarning = function printWarning(format, args) {\n var len = arguments.length;\n args = new Array(len > 1 ? len - 1 : 0);\n for (var key = 1; key < len; key++) {\n args[key - 1] = arguments[key];\n }\n var argIndex = 0;\n var message = 'Warning: ' +\n format.replace(/%s/g, function() {\n return args[argIndex++];\n });\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) {}\n }\n\n warning = function(condition, format, args) {\n var len = arguments.length;\n args = new Array(len > 2 ? len - 2 : 0);\n for (var key = 2; key < len; key++) {\n args[key - 2] = arguments[key];\n }\n if (format === undefined) {\n throw new Error(\n '`warning(condition, format, ...args)` requires a warning ' +\n 'message argument'\n );\n }\n if (!condition) {\n printWarning.apply(null, [format].concat(args));\n }\n };\n}\n\nmodule.exports = warning;\n","\"use strict\";\n\nfunction encodeSync(audioData, opts) {\n opts = opts || {};\n\n audioData = toAudioData(audioData);\n\n if (audioData === null) {\n throw new TypeError(\"Invalid AudioData\");\n }\n\n var floatingPoint = !!(opts.floatingPoint || opts.float);\n var bitDepth = floatingPoint ? 32 : ((opts.bitDepth|0) || 16);\n var bytes = bitDepth >> 3;\n var length = audioData.length * audioData.numberOfChannels * bytes;\n var dataView = new DataView(new Uint8Array(44 + length).buffer);\n var writer = createWriter(dataView);\n\n var format = {\n formatId: floatingPoint ? 0x0003 : 0x0001,\n floatingPoint: floatingPoint,\n numberOfChannels: audioData.numberOfChannels,\n sampleRate: audioData.sampleRate,\n bitDepth: bitDepth\n };\n\n writeHeader(writer, format, dataView.buffer.byteLength - 8);\n\n var err = writeData(writer, format, length, audioData, opts);\n\n if (err instanceof Error) {\n throw err;\n }\n\n return dataView.buffer;\n}\n\nfunction encode(audioData, opts) {\n return new Promise(function(resolve) {\n resolve(encodeSync(audioData, opts));\n });\n}\n\nfunction toAudioData(data) {\n var audioData = {};\n\n if (typeof data.sampleRate !== \"number\") {\n return null;\n }\n if (!Array.isArray(data.channelData)) {\n return null;\n }\n if (!(data.channelData[0] instanceof Float32Array)) {\n return null;\n }\n\n audioData.numberOfChannels = data.channelData.length;\n audioData.length = data.channelData[0].length|0;\n audioData.sampleRate = data.sampleRate|0;\n audioData.channelData = data.channelData;\n\n return audioData;\n}\n\nfunction writeHeader(writer, format, length) {\n var bytes = format.bitDepth >> 3;\n\n writer.string(\"RIFF\");\n writer.uint32(length);\n writer.string(\"WAVE\");\n\n writer.string(\"fmt \");\n writer.uint32(16);\n writer.uint16(format.floatingPoint ? 0x0003 : 0x0001);\n writer.uint16(format.numberOfChannels);\n writer.uint32(format.sampleRate);\n writer.uint32(format.sampleRate * format.numberOfChannels * bytes);\n writer.uint16(format.numberOfChannels * bytes);\n writer.uint16(format.bitDepth);\n}\n\nfunction writeData(writer, format, length, audioData, opts) {\n var bitDepth = format.bitDepth;\n var encoderOption = format.floatingPoint ? \"f\" : opts.symmetric ? \"s\" : \"\";\n var methodName = \"pcm\" + bitDepth + encoderOption;\n\n if (!writer[methodName]) {\n return new TypeError(\"Not supported bit depth: \" + bitDepth);\n }\n\n var write = writer[methodName].bind(writer);\n var numberOfChannels = format.numberOfChannels;\n var channelData = audioData.channelData;\n\n writer.string(\"data\");\n writer.uint32(length);\n\n for (var i = 0, imax = audioData.length; i < imax; i++) {\n for (var ch = 0; ch < numberOfChannels; ch++) {\n write(channelData[ch][i]);\n }\n }\n}\n\nfunction createWriter(dataView) {\n var pos = 0;\n\n return {\n int16: function(value) {\n dataView.setInt16(pos, value, true);\n pos += 2;\n },\n uint16: function(value) {\n dataView.setUint16(pos, value, true);\n pos += 2;\n },\n uint32: function(value) {\n dataView.setUint32(pos, value, true);\n pos += 4;\n },\n string: function(value) {\n for (var i = 0, imax = value.length; i < imax; i++) {\n dataView.setUint8(pos++, value.charCodeAt(i));\n }\n },\n pcm8: function(value) {\n value = Math.max(-1, Math.min(value, +1));\n value = (value * 0.5 + 0.5) * 255;\n value = Math.round(value)|0;\n dataView.setUint8(pos, value, true);\n pos += 1;\n },\n pcm8s: function(value) {\n value = Math.round(value * 128) + 128;\n value = Math.max(0, Math.min(value, 255));\n dataView.setUint8(pos, value, true);\n pos += 1;\n },\n pcm16: function(value) {\n value = Math.max(-1, Math.min(value, +1));\n value = value < 0 ? value * 32768 : value * 32767;\n value = Math.round(value)|0;\n dataView.setInt16(pos, value, true);\n pos += 2;\n },\n pcm16s: function(value) {\n value = Math.round(value * 32768);\n value = Math.max(-32768, Math.min(value, 32767));\n dataView.setInt16(pos, value, true);\n pos += 2;\n },\n pcm24: function(value) {\n value = Math.max(-1, Math.min(value, +1));\n value = value < 0 ? 0x1000000 + value * 8388608 : value * 8388607;\n value = Math.round(value)|0;\n\n var x0 = (value >> 0) & 0xFF;\n var x1 = (value >> 8) & 0xFF;\n var x2 = (value >> 16) & 0xFF;\n\n dataView.setUint8(pos + 0, x0);\n dataView.setUint8(pos + 1, x1);\n dataView.setUint8(pos + 2, x2);\n pos += 3;\n },\n pcm24s: function(value) {\n value = Math.round(value * 8388608);\n value = Math.max(-8388608, Math.min(value, 8388607));\n\n var x0 = (value >> 0) & 0xFF;\n var x1 = (value >> 8) & 0xFF;\n var x2 = (value >> 16) & 0xFF;\n\n dataView.setUint8(pos + 0, x0);\n dataView.setUint8(pos + 1, x1);\n dataView.setUint8(pos + 2, x2);\n pos += 3;\n },\n pcm32: function(value) {\n value = Math.max(-1, Math.min(value, +1));\n value = value < 0 ? value * 2147483648 : value * 2147483647;\n value = Math.round(value)|0;\n dataView.setInt32(pos, value, true);\n pos += 4;\n },\n pcm32s: function(value) {\n value = Math.round(value * 2147483648);\n value = Math.max(-2147483648, Math.min(value, +2147483647));\n dataView.setInt32(pos, value, true);\n pos += 4;\n },\n pcm32f: function(value) {\n dataView.setFloat32(pos, value, true);\n pos += 4;\n }\n };\n}\n\nmodule.exports.encode = encode;\nmodule.exports.encode.sync = encodeSync;\n","module.exports = function() {\n\tthrow new Error(\"define cannot be used indirect\");\n};\n","/* globals __webpack_amd_options__ */\nmodule.exports = __webpack_amd_options__;\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","module.exports = function(originalModule) {\n\tif (!originalModule.webpackPolyfill) {\n\t\tvar module = Object.create(originalModule);\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"exports\", {\n\t\t\tenumerable: true\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","module.exports = function() {\n return require(\"!!/home/afy/WebstormProjects/s3onegpio/scratch-gui/node_modules/worker-loader/dist/workers/InlineWorker.js\")(\"/******/ (function(modules) { // webpackBootstrap\\n/******/ \\t// The module cache\\n/******/ \\tvar installedModules = {};\\n/******/\\n/******/ \\t// The require function\\n/******/ \\tfunction __webpack_require__(moduleId) {\\n/******/\\n/******/ \\t\\t// Check if module is in cache\\n/******/ \\t\\tif(installedModules[moduleId]) {\\n/******/ \\t\\t\\treturn installedModules[moduleId].exports;\\n/******/ \\t\\t}\\n/******/ \\t\\t// Create a new module (and put it into the cache)\\n/******/ \\t\\tvar module = installedModules[moduleId] = {\\n/******/ \\t\\t\\ti: moduleId,\\n/******/ \\t\\t\\tl: false,\\n/******/ \\t\\t\\texports: {}\\n/******/ \\t\\t};\\n/******/\\n/******/ \\t\\t// Execute the module function\\n/******/ \\t\\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\\n/******/\\n/******/ \\t\\t// Flag the module as loaded\\n/******/ \\t\\tmodule.l = true;\\n/******/\\n/******/ \\t\\t// Return the exports of the module\\n/******/ \\t\\treturn module.exports;\\n/******/ \\t}\\n/******/\\n/******/\\n/******/ \\t// expose the modules object (__webpack_modules__)\\n/******/ \\t__webpack_require__.m = modules;\\n/******/\\n/******/ \\t// expose the module cache\\n/******/ \\t__webpack_require__.c = installedModules;\\n/******/\\n/******/ \\t// define getter function for harmony exports\\n/******/ \\t__webpack_require__.d = function(exports, name, getter) {\\n/******/ \\t\\tif(!__webpack_require__.o(exports, name)) {\\n/******/ \\t\\t\\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\\n/******/ \\t\\t}\\n/******/ \\t};\\n/******/\\n/******/ \\t// define __esModule on exports\\n/******/ \\t__webpack_require__.r = function(exports) {\\n/******/ \\t\\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\\n/******/ \\t\\t\\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\\n/******/ \\t\\t}\\n/******/ \\t\\tObject.defineProperty(exports, '__esModule', { value: true });\\n/******/ \\t};\\n/******/\\n/******/ \\t// create a fake namespace object\\n/******/ \\t// mode & 1: value is a module id, require it\\n/******/ \\t// mode & 2: merge all properties of value into the ns\\n/******/ \\t// mode & 4: return value when already ns object\\n/******/ \\t// mode & 8|1: behave like require\\n/******/ \\t__webpack_require__.t = function(value, mode) {\\n/******/ \\t\\tif(mode & 1) value = __webpack_require__(value);\\n/******/ \\t\\tif(mode & 8) return value;\\n/******/ \\t\\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\\n/******/ \\t\\tvar ns = Object.create(null);\\n/******/ \\t\\t__webpack_require__.r(ns);\\n/******/ \\t\\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\\n/******/ \\t\\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\\n/******/ \\t\\treturn ns;\\n/******/ \\t};\\n/******/\\n/******/ \\t// getDefaultExport function for compatibility with non-harmony modules\\n/******/ \\t__webpack_require__.n = function(module) {\\n/******/ \\t\\tvar getter = module && module.__esModule ?\\n/******/ \\t\\t\\tfunction getDefault() { return module['default']; } :\\n/******/ \\t\\t\\tfunction getModuleExports() { return module; };\\n/******/ \\t\\t__webpack_require__.d(getter, 'a', getter);\\n/******/ \\t\\treturn getter;\\n/******/ \\t};\\n/******/\\n/******/ \\t// Object.prototype.hasOwnProperty.call\\n/******/ \\t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\\n/******/\\n/******/ \\t// __webpack_public_path__\\n/******/ \\t__webpack_require__.p = \\\"\\\";\\n/******/\\n/******/\\n/******/ \\t// Load entry module and return exports\\n/******/ \\treturn __webpack_require__(__webpack_require__.s = \\\"./node_modules/babel-loader/lib/index.js?!./node_modules/scratch-storage/src/FetchWorkerTool.worker.js\\\");\\n/******/ })\\n/************************************************************************/\\n/******/ ({\\n\\n/***/ \\\"./node_modules/babel-loader/lib/index.js?!./node_modules/scratch-storage/src/FetchWorkerTool.worker.js\\\":\\n/*!************************************************************************************************************!*\\\\\\n !*** ./node_modules/babel-loader/lib??ref--4!./node_modules/scratch-storage/src/FetchWorkerTool.worker.js ***!\\n \\\\************************************************************************************************************/\\n/*! no static exports found */\\n/***/ (function(module, exports) {\\n\\n/* eslint-env worker */\\nvar jobsActive = 0;\\nvar complete = [];\\nvar intervalId = null;\\n/**\\n * Register a step function.\\n *\\n * Step checks if there are completed jobs and if there are sends them to the\\n * parent. Then it checks the jobs count. If there are no further jobs, clear\\n * the step.\\n */\\n\\nvar registerStep = function registerStep() {\\n intervalId = setInterval(function () {\\n if (complete.length) {\\n // Send our chunk of completed requests and instruct postMessage to\\n // transfer the buffers instead of copying them.\\n postMessage(complete.slice(), // Instruct postMessage that these buffers in the sent message\\n // should use their Transferable trait. After the postMessage\\n // call the \\\"buffers\\\" will still be in complete if you looked,\\n // but they will all be length 0 as the data they reference has\\n // been sent to the window. This lets us send a lot of data\\n // without the normal postMessage behaviour of making a copy of\\n // all of the data for the window.\\n complete.map(function (response) {\\n return response.buffer;\\n }).filter(Boolean));\\n complete.length = 0;\\n }\\n\\n if (jobsActive === 0) {\\n clearInterval(intervalId);\\n intervalId = null;\\n }\\n }, 1);\\n};\\n/**\\n * Receive a job from the parent and fetch the requested data.\\n * @param {object} options.job A job id, url, and options descriptor to perform.\\n */\\n\\n\\nvar onMessage = function onMessage(_ref) {\\n var job = _ref.data;\\n\\n if (jobsActive === 0 && !intervalId) {\\n registerStep();\\n }\\n\\n jobsActive++;\\n fetch(job.url, job.options).then(function (response) {\\n return response.arrayBuffer();\\n }).then(function (buffer) {\\n return complete.push({\\n id: job.id,\\n buffer: buffer\\n });\\n }).catch(function (error) {\\n return complete.push({\\n id: job.id,\\n error: error\\n });\\n }).then(function () {\\n return jobsActive--;\\n });\\n};\\n\\nif (self.fetch) {\\n postMessage({\\n support: {\\n fetch: true\\n }\\n });\\n self.addEventListener('message', onMessage);\\n} else {\\n postMessage({\\n support: {\\n fetch: false\\n }\\n });\\n self.addEventListener('message', function (_ref2) {\\n var job = _ref2.data;\\n postMessage([{\\n id: job.id,\\n error: new Error('fetch is unavailable')\\n }]);\\n });\\n}\\n\\n/***/ })\\n\\n/******/ });\\n//# sourceMappingURL=326c5f98902ccd335b5b.worker.js.map\", __webpack_public_path__ + \"326c5f98902ccd335b5b.worker.js\");\n};","'use strict';\n\n// http://stackoverflow.com/questions/10343913/how-to-create-a-web-worker-from-a-string\n\nvar URL = window.URL || window.webkitURL;\n\nmodule.exports = function (content, url) {\n try {\n try {\n var blob;\n\n try {\n // BlobBuilder = Deprecated, but widely implemented\n var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;\n\n blob = new BlobBuilder();\n\n blob.append(content);\n\n blob = blob.getBlob();\n } catch (e) {\n // The proposed API\n blob = new Blob([content]);\n }\n\n return new Worker(URL.createObjectURL(blob));\n } catch (e) {\n return new Worker('data:application/javascript,' + encodeURIComponent(content));\n }\n } catch (e) {\n if (!url) {\n throw Error('Inline worker is not supported');\n }\n\n return new Worker(url);\n }\n};","\"use strict\";\nvar window = require(\"global/window\")\nvar isFunction = require(\"is-function\")\nvar parseHeaders = require(\"parse-headers\")\nvar xtend = require(\"xtend\")\n\nmodule.exports = createXHR\n// Allow use of default import syntax in TypeScript\nmodule.exports.default = createXHR;\ncreateXHR.XMLHttpRequest = window.XMLHttpRequest || noop\ncreateXHR.XDomainRequest = \"withCredentials\" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest\n\nforEachArray([\"get\", \"put\", \"post\", \"patch\", \"head\", \"delete\"], function(method) {\n createXHR[method === \"delete\" ? \"del\" : method] = function(uri, options, callback) {\n options = initParams(uri, options, callback)\n options.method = method.toUpperCase()\n return _createXHR(options)\n }\n})\n\nfunction forEachArray(array, iterator) {\n for (var i = 0; i < array.length; i++) {\n iterator(array[i])\n }\n}\n\nfunction isEmpty(obj){\n for(var i in obj){\n if(obj.hasOwnProperty(i)) return false\n }\n return true\n}\n\nfunction initParams(uri, options, callback) {\n var params = uri\n\n if (isFunction(options)) {\n callback = options\n if (typeof uri === \"string\") {\n params = {uri:uri}\n }\n } else {\n params = xtend(options, {uri: uri})\n }\n\n params.callback = callback\n return params\n}\n\nfunction createXHR(uri, options, callback) {\n options = initParams(uri, options, callback)\n return _createXHR(options)\n}\n\nfunction _createXHR(options) {\n if(typeof options.callback === \"undefined\"){\n throw new Error(\"callback argument missing\")\n }\n\n var called = false\n var callback = function cbOnce(err, response, body){\n if(!called){\n called = true\n options.callback(err, response, body)\n }\n }\n\n function readystatechange() {\n if (xhr.readyState === 4) {\n setTimeout(loadFunc, 0)\n }\n }\n\n function getBody() {\n // Chrome with requestType=blob throws errors arround when even testing access to responseText\n var body = undefined\n\n if (xhr.response) {\n body = xhr.response\n } else {\n body = xhr.responseText || getXml(xhr)\n }\n\n if (isJson) {\n try {\n body = JSON.parse(body)\n } catch (e) {}\n }\n\n return body\n }\n\n function errorFunc(evt) {\n clearTimeout(timeoutTimer)\n if(!(evt instanceof Error)){\n evt = new Error(\"\" + (evt || \"Unknown XMLHttpRequest Error\") )\n }\n evt.statusCode = 0\n return callback(evt, failureResponse)\n }\n\n // will load the data & process the response in a special response object\n function loadFunc() {\n if (aborted) return\n var status\n clearTimeout(timeoutTimer)\n if(options.useXDR && xhr.status===undefined) {\n //IE8 CORS GET successful response doesn't have a status field, but body is fine\n status = 200\n } else {\n status = (xhr.status === 1223 ? 204 : xhr.status)\n }\n var response = failureResponse\n var err = null\n\n if (status !== 0){\n response = {\n body: getBody(),\n statusCode: status,\n method: method,\n headers: {},\n url: uri,\n rawRequest: xhr\n }\n if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE\n response.headers = parseHeaders(xhr.getAllResponseHeaders())\n }\n } else {\n err = new Error(\"Internal XMLHttpRequest Error\")\n }\n return callback(err, response, response.body)\n }\n\n var xhr = options.xhr || null\n\n if (!xhr) {\n if (options.cors || options.useXDR) {\n xhr = new createXHR.XDomainRequest()\n }else{\n xhr = new createXHR.XMLHttpRequest()\n }\n }\n\n var key\n var aborted\n var uri = xhr.url = options.uri || options.url\n var method = xhr.method = options.method || \"GET\"\n var body = options.body || options.data\n var headers = xhr.headers = options.headers || {}\n var sync = !!options.sync\n var isJson = false\n var timeoutTimer\n var failureResponse = {\n body: undefined,\n headers: {},\n statusCode: 0,\n method: method,\n url: uri,\n rawRequest: xhr\n }\n\n if (\"json\" in options && options.json !== false) {\n isJson = true\n headers[\"accept\"] || headers[\"Accept\"] || (headers[\"Accept\"] = \"application/json\") //Don't override existing accept header declared by user\n if (method !== \"GET\" && method !== \"HEAD\") {\n headers[\"content-type\"] || headers[\"Content-Type\"] || (headers[\"Content-Type\"] = \"application/json\") //Don't override existing accept header declared by user\n body = JSON.stringify(options.json === true ? body : options.json)\n }\n }\n\n xhr.onreadystatechange = readystatechange\n xhr.onload = loadFunc\n xhr.onerror = errorFunc\n // IE9 must have onprogress be set to a unique function.\n xhr.onprogress = function () {\n // IE must die\n }\n xhr.onabort = function(){\n aborted = true;\n }\n xhr.ontimeout = errorFunc\n xhr.open(method, uri, !sync, options.username, options.password)\n //has to be after open\n if(!sync) {\n xhr.withCredentials = !!options.withCredentials\n }\n // Cannot set timeout with sync request\n // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly\n // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent\n if (!sync && options.timeout > 0 ) {\n timeoutTimer = setTimeout(function(){\n if (aborted) return\n aborted = true//IE9 may still call readystatechange\n xhr.abort(\"timeout\")\n var e = new Error(\"XMLHttpRequest timeout\")\n e.code = \"ETIMEDOUT\"\n errorFunc(e)\n }, options.timeout )\n }\n\n if (xhr.setRequestHeader) {\n for(key in headers){\n if(headers.hasOwnProperty(key)){\n xhr.setRequestHeader(key, headers[key])\n }\n }\n } else if (options.headers && !isEmpty(options.headers)) {\n throw new Error(\"Headers cannot be set on an XDomainRequest object\")\n }\n\n if (\"responseType\" in options) {\n xhr.responseType = options.responseType\n }\n\n if (\"beforeSend\" in options &&\n typeof options.beforeSend === \"function\"\n ) {\n options.beforeSend(xhr)\n }\n\n // Microsoft Edge browser sends \"undefined\" when send is called with undefined value.\n // XMLHttpRequest spec says to pass null as body to indicate no body\n // See https://github.com/naugtur/xhr/issues/100.\n xhr.send(body || null)\n\n return xhr\n\n\n}\n\nfunction getXml(xhr) {\n // xhr.responseXML will throw Exception \"InvalidStateError\" or \"DOMException\"\n // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML.\n try {\n if (xhr.responseType === \"document\") {\n return xhr.responseXML\n }\n var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === \"parsererror\"\n if (xhr.responseType === \"\" && !firefoxBugTakenEffect) {\n return xhr.responseXML\n }\n } catch (e) {}\n\n return null\n}\n\nfunction noop() {}\n","module.exports = extend\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction extend() {\n var target = {}\n\n for (var i = 0; i < arguments.length; i++) {\n var source = arguments[i]\n\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n target[key] = source[key]\n }\n }\n }\n\n return target\n}\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./action-menu.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./action-menu.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./action-menu.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport bindAll from 'lodash.bindall';\nimport ReactTooltip from 'react-tooltip';\n\nimport styles from './action-menu.css';\n\nconst CLOSE_DELAY = 300; // ms\n\nclass ActionMenu extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'clickDelayer',\n 'handleClosePopover',\n 'handleToggleOpenState',\n 'handleTouchStart',\n 'handleTouchOutside',\n 'setButtonRef',\n 'setContainerRef'\n ]);\n this.state = {\n isOpen: false,\n forceHide: false\n };\n this.mainTooltipId = `tooltip-${Math.random()}`;\n }\n componentDidMount () {\n // Touch start on the main button is caught to trigger open and not click\n this.buttonRef.addEventListener('touchstart', this.handleTouchStart);\n // Touch start on document is used to trigger close if it is outside\n document.addEventListener('touchstart', this.handleTouchOutside);\n }\n shouldComponentUpdate (newProps, newState) {\n // This check prevents re-rendering while the project is updating.\n // @todo check only the state and the title because it is enough to know\n // if anything substantial has changed\n // This is needed because of the sloppy way the props are passed as a new object,\n // which should be refactored.\n return newState.isOpen !== this.state.isOpen ||\n newState.forceHide !== this.state.forceHide ||\n newProps.title !== this.props.title;\n }\n componentWillUnmount () {\n this.buttonRef.removeEventListener('touchstart', this.handleTouchStart);\n document.removeEventListener('touchstart', this.handleTouchOutside);\n }\n handleClosePopover () {\n this.closeTimeoutId = setTimeout(() => {\n this.setState({isOpen: false});\n this.closeTimeoutId = null;\n }, CLOSE_DELAY);\n }\n handleToggleOpenState () {\n // Mouse enter back in after timeout was started prevents it from closing.\n if (this.closeTimeoutId) {\n clearTimeout(this.closeTimeoutId);\n this.closeTimeoutId = null;\n } else if (!this.state.isOpen) {\n this.setState({\n isOpen: true,\n forceHide: false\n });\n }\n }\n handleTouchOutside (e) {\n if (this.state.isOpen && !this.containerRef.contains(e.target)) {\n this.setState({isOpen: false});\n ReactTooltip.hide();\n }\n }\n clickDelayer (fn) {\n // Return a wrapped action that manages the menu closing.\n // @todo we may be able to use react-transition for this in the future\n // for now all this work is to ensure the menu closes BEFORE the\n // (possibly slow) action is started.\n return event => {\n ReactTooltip.hide();\n if (fn) fn(event);\n // Blur the button so it does not keep focus after being clicked\n // This prevents keyboard events from triggering the button\n this.buttonRef.blur();\n this.setState({forceHide: true, isOpen: false}, () => {\n setTimeout(() => this.setState({forceHide: false}));\n });\n };\n }\n handleTouchStart (e) {\n // Prevent this touch from becoming a click if menu is closed\n if (!this.state.isOpen) {\n e.preventDefault();\n this.handleToggleOpenState();\n }\n }\n setButtonRef (ref) {\n this.buttonRef = ref;\n }\n setContainerRef (ref) {\n this.containerRef = ref;\n }\n render () {\n const {\n className,\n img: mainImg,\n title: mainTitle,\n moreButtons,\n tooltipPlace,\n onClick\n } = this.props;\n\n return (\n \n \n \n \n \n
\n
\n {(moreButtons || []).map(({img, title, onClick: handleClick,\n fileAccept, fileChange, fileInput, fileMultiple}, keyId) => {\n const isComingSoon = !handleClick;\n const hasFileInput = fileInput;\n const tooltipId = `${this.mainTooltipId}-${title}`;\n return (\n
\n \n \n {hasFileInput ? (\n ) : null}\n \n \n
\n );\n })}\n
\n
\n \n );\n }\n}\n\nActionMenu.propTypes = {\n className: PropTypes.string,\n img: PropTypes.string,\n moreButtons: PropTypes.arrayOf(PropTypes.shape({\n img: PropTypes.string,\n title: PropTypes.node.isRequired,\n onClick: PropTypes.func, // Optional, \"coming soon\" if no callback provided\n fileAccept: PropTypes.string, // Optional, only for file upload\n fileChange: PropTypes.func, // Optional, only for file upload\n fileInput: PropTypes.func, // Optional, only for file upload\n fileMultiple: PropTypes.bool // Optional, only for file upload\n })),\n onClick: PropTypes.func.isRequired,\n title: PropTypes.node.isRequired,\n tooltipPlace: PropTypes.string\n};\n\nexport default ActionMenu;\n","module.exports = __webpack_public_path__ + \"static/assets/385aa4b73a425883b4f9e91501a52299.svg\";","module.exports = __webpack_public_path__ + \"static/assets/c3421543ab6c9e154f4294257ce0d078.svg\";","module.exports = __webpack_public_path__ + \"static/assets/e587d9d7e9a2f1f28041ba5c15db7a40.svg\";","module.exports = __webpack_public_path__ + \"static/assets/94b06fb716871f81bec601724e29a457.svg\";","module.exports = __webpack_public_path__ + \"static/assets/551aae506dfa65ce3b45713b5300a678.svg\";","module.exports = __webpack_public_path__ + \"static/assets/497f797eeffe5fa7e6a626abc0db08a1.svg\";","module.exports = __webpack_public_path__ + \"static/assets/301439e2e5ab88b658368ee525e6752b.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./alert.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./alert.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./alert.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport {FormattedMessage} from 'react-intl';\n\nimport Box from '../box/box.jsx';\nimport CloseButton from '../close-button/close-button.jsx';\nimport Spinner from '../spinner/spinner.jsx';\nimport {AlertLevels} from '../../lib/alerts/index.jsx';\n\nimport styles from './alert.css';\n\nconst closeButtonColors = {\n [AlertLevels.SUCCESS]: CloseButton.COLOR_GREEN,\n [AlertLevels.WARN]: CloseButton.COLOR_ORANGE\n};\n\nconst AlertComponent = ({\n content,\n closeButton,\n extensionName,\n iconSpinner,\n iconURL,\n level,\n showDownload,\n showSaveNow,\n onCloseAlert,\n onDownload,\n onSaveNow,\n onReconnect,\n showReconnect\n}) => (\n \n {/* TODO: implement Rtl handling */}\n {(iconSpinner || iconURL) && (\n
\n {iconSpinner && (\n \n )}\n {iconURL && (\n \n )}\n
\n )}\n
\n {extensionName ? (\n \n ) : content}\n
\n
\n {showSaveNow && (\n \n \n \n )}\n {showDownload && (\n \n \n \n )}\n {showReconnect && (\n \n \n \n )}\n {closeButton && (\n \n \n \n )}\n
\n \n);\n\nAlertComponent.propTypes = {\n closeButton: PropTypes.bool,\n content: PropTypes.oneOfType([PropTypes.element, PropTypes.string]),\n extensionName: PropTypes.string,\n iconSpinner: PropTypes.bool,\n iconURL: PropTypes.string,\n level: PropTypes.string,\n onCloseAlert: PropTypes.func.isRequired,\n onDownload: PropTypes.func,\n onReconnect: PropTypes.func,\n onSaveNow: PropTypes.func,\n showDownload: PropTypes.func,\n showReconnect: PropTypes.bool,\n showSaveNow: PropTypes.bool\n};\n\nAlertComponent.defaultProps = {\n level: AlertLevels.WARN\n};\n\nexport default AlertComponent;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./alerts.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./alerts.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./alerts.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Box from '../box/box.jsx';\nimport Alert from '../../containers/alert.jsx';\n\nimport styles from './alerts.css';\n\nconst AlertsComponent = ({\n alertsList,\n className,\n onCloseAlert\n}) => (\n \n \n {alertsList.map((a, index) => (\n \n ))}\n \n \n);\n\nAlertsComponent.propTypes = {\n alertsList: PropTypes.arrayOf(PropTypes.object),\n className: PropTypes.string,\n onCloseAlert: PropTypes.func\n};\n\nexport default AlertsComponent;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./inline-message.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./inline-message.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./inline-message.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nimport Spinner from '../spinner/spinner.jsx';\nimport {AlertLevels} from '../../lib/alerts/index.jsx';\n\nimport styles from './inline-message.css';\n\nconst InlineMessageComponent = ({\n content,\n iconSpinner,\n level\n}) => (\n \n {/* TODO: implement Rtl handling */}\n {iconSpinner && (\n \n )}\n {content}\n \n);\n\nInlineMessageComponent.propTypes = {\n content: PropTypes.element,\n iconSpinner: PropTypes.bool,\n level: PropTypes.string\n};\n\nInlineMessageComponent.defaultProps = {\n level: AlertLevels.INFO\n};\n\nexport default InlineMessageComponent;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./asset-panel.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./asset-panel.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./asset-panel.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\n\nimport Box from '../box/box.jsx';\nimport Selector from './selector.jsx';\nimport styles from './asset-panel.css';\n\nconst AssetPanel = props => (\n \n \n \n {props.children}\n \n \n);\n\nAssetPanel.propTypes = {\n ...Selector.propTypes\n};\n\nexport default AssetPanel;\n","module.exports = __webpack_public_path__ + \"static/assets/44e4859e354c81d66c73f741df2e5ec7.svg\";","module.exports = __webpack_public_path__ + \"static/assets/c9528ee4be1a12380a6c9caf73bd99e9.svg\";","module.exports = __webpack_public_path__ + \"static/assets/9cfdd378e4cc977fe663ca932e530ec6.svg\";","module.exports = __webpack_public_path__ + \"static/assets/35c6867250ec4f430624bc9e2e7072d7.svg\";","module.exports = __webpack_public_path__ + \"static/assets/38ac2210b486d930f72c951ad081e4c0.svg\";","module.exports = __webpack_public_path__ + \"static/assets/63e5827c1506216bd7c9927a4e5eb558.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./selector.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./selector.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./selector.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport SpriteSelectorItem from '../../containers/sprite-selector-item.jsx';\nimport Box from '../box/box.jsx';\nimport ActionMenu from '../action-menu/action-menu.jsx';\nimport SortableAsset from './sortable-asset.jsx';\nimport SortableHOC from '../../lib/sortable-hoc.jsx';\nimport DragConstants from '../../lib/drag-constants';\n\nimport styles from './selector.css';\n\nconst Selector = props => {\n const {\n buttons,\n containerRef,\n dragType,\n isRtl,\n items,\n selectedItemIndex,\n draggingIndex,\n draggingType,\n ordering,\n onAddSortable,\n onRemoveSortable,\n onDeleteClick,\n onDuplicateClick,\n onExportClick,\n onItemClick\n } = props;\n\n const isRelevantDrag = draggingType === dragType;\n\n let newButtonSection = null;\n\n if (buttons.length > 0) {\n const {img, title, onClick} = buttons[0];\n const moreButtons = buttons.slice(1);\n newButtonSection = (\n \n \n \n );\n }\n\n return (\n \n \n {items.map((item, index) => (\n \n \n \n ))}\n \n {newButtonSection}\n \n );\n};\n\nSelector.propTypes = {\n buttons: PropTypes.arrayOf(PropTypes.shape({\n title: PropTypes.string.isRequired,\n img: PropTypes.string.isRequired,\n onClick: PropTypes.func\n })),\n containerRef: PropTypes.func,\n dragType: PropTypes.oneOf(Object.keys(DragConstants)),\n draggingIndex: PropTypes.number,\n draggingType: PropTypes.oneOf(Object.keys(DragConstants)),\n isRtl: PropTypes.bool,\n items: PropTypes.arrayOf(PropTypes.shape({\n url: PropTypes.string,\n name: PropTypes.string.isRequired\n })),\n onAddSortable: PropTypes.func,\n onDeleteClick: PropTypes.func,\n onDuplicateClick: PropTypes.func,\n onExportClick: PropTypes.func,\n onItemClick: PropTypes.func.isRequired,\n onRemoveSortable: PropTypes.func,\n ordering: PropTypes.arrayOf(PropTypes.number),\n selectedItemIndex: PropTypes.number.isRequired\n};\n\nexport default SortableHOC(Selector);\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport bindAll from 'lodash.bindall';\n\nclass SortableAsset extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'setRef'\n ]);\n }\n componentDidMount () {\n this.props.onAddSortable(this.ref);\n }\n componentWillUnmount () {\n this.props.onRemoveSortable(this.ref);\n }\n setRef (ref) {\n this.ref = ref;\n }\n render () {\n return (\n \n {this.props.children}\n \n );\n }\n}\n\nSortableAsset.propTypes = {\n children: PropTypes.node.isRequired,\n className: PropTypes.string,\n index: PropTypes.number.isRequired,\n onAddSortable: PropTypes.func.isRequired,\n onRemoveSortable: PropTypes.func.isRequired\n};\n\nexport default SortableAsset;\n","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport Box from '../box/box.jsx';\nimport styles from './audio-trimmer.css';\nimport SelectionHandle from './selection-handle.jsx';\nimport Playhead from './playhead.jsx';\n\nconst AudioSelector = props => (\n \n {props.trimStart === null ? null : (\n \n \n \n \n \n )}\n {props.playhead ? (\n \n ) : null}\n \n);\n\nAudioSelector.propTypes = {\n containerRef: PropTypes.func,\n onNewSelectionMouseDown: PropTypes.func.isRequired,\n onTrimEndMouseDown: PropTypes.func.isRequired,\n onTrimStartMouseDown: PropTypes.func.isRequired,\n playhead: PropTypes.number,\n trimEnd: PropTypes.number,\n trimStart: PropTypes.number\n};\n\nexport default AudioSelector;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./audio-trimmer.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./audio-trimmer.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./audio-trimmer.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport Box from '../box/box.jsx';\nimport styles from './audio-trimmer.css';\nimport SelectionHandle from './selection-handle.jsx';\nimport Playhead from './playhead.jsx';\n\nconst AudioTrimmer = props => (\n \n {props.trimStart === null ? null : (\n \n \n \n \n )}\n {props.playhead ? (\n \n ) : null}\n {props.trimEnd === null ? null : (\n \n \n \n \n )}\n \n);\n\nAudioTrimmer.propTypes = {\n containerRef: PropTypes.func,\n onTrimEndMouseDown: PropTypes.func.isRequired,\n onTrimStartMouseDown: PropTypes.func.isRequired,\n playhead: PropTypes.number,\n trimEnd: PropTypes.number,\n trimStart: PropTypes.number\n};\n\nexport default AudioTrimmer;\n","module.exports = __webpack_public_path__ + \"static/assets/610fb87d66b6749aeb96d475ceb62940.svg\";","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport styles from './audio-trimmer.css';\n\nconst Playhead = props => (\n
\n \n
\n);\n\nPlayhead.propTypes = {\n playbackPosition: PropTypes.number\n};\n\nexport default Playhead;\n","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport Box from '../box/box.jsx';\nimport styles from './audio-trimmer.css';\nimport handleIcon from './icon--handle.svg';\n\nconst SelectionHandle = props => (\n \n \n \n \n \n \n \n \n);\n\nSelectionHandle.propTypes = {\n handleStyle: PropTypes.string,\n onMouseDown: PropTypes.func\n};\n\nexport default SelectionHandle;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./backpack.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./backpack.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./backpack.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport {FormattedMessage} from 'react-intl';\nimport DragConstants from '../../lib/drag-constants';\nimport {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx';\nimport SpriteSelectorItem from '../../containers/sprite-selector-item.jsx';\nimport styles from './backpack.css';\n\n// TODO make sprite selector item not require onClick\nconst noop = () => {};\n\nconst dragTypeMap = { // Keys correspond with the backpack-server item types\n costume: DragConstants.BACKPACK_COSTUME,\n sound: DragConstants.BACKPACK_SOUND,\n script: DragConstants.BACKPACK_CODE,\n sprite: DragConstants.BACKPACK_SPRITE\n};\n\nconst Backpack = ({\n blockDragOver,\n containerRef,\n contents,\n dragOver,\n error,\n expanded,\n loading,\n showMore,\n onToggle,\n onDelete,\n onMouseEnter,\n onMouseLeave,\n onMore\n}) => (\n
\n \n {onToggle ? (\n \n ) : (\n \n \n \n )}\n
\n {expanded ? (\n \n {error ? (\n
\n \n
\n ) : (\n loading ? (\n
\n \n
\n ) : (\n contents.length > 0 ? (\n
\n {contents.map(item => (\n \n ))}\n {showMore && (\n \n \n \n )}\n
\n ) : (\n
\n \n
\n )\n )\n )}\n \n ) : null}\n \n);\n\nBackpack.propTypes = {\n blockDragOver: PropTypes.bool,\n containerRef: PropTypes.func,\n contents: PropTypes.arrayOf(PropTypes.shape({\n id: PropTypes.string,\n thumbnailUrl: PropTypes.string,\n type: PropTypes.string,\n name: PropTypes.string\n })),\n dragOver: PropTypes.bool,\n error: PropTypes.bool,\n expanded: PropTypes.bool,\n loading: PropTypes.bool,\n onDelete: PropTypes.func,\n onMore: PropTypes.func,\n onMouseEnter: PropTypes.func,\n onMouseLeave: PropTypes.func,\n onToggle: PropTypes.func,\n showMore: PropTypes.bool\n};\n\nBackpack.defaultProps = {\n blockDragOver: false,\n contents: [],\n dragOver: false,\n expanded: false,\n loading: false,\n showMore: false,\n onMore: null,\n onToggle: null\n};\n\nexport default Backpack;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./blocks.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./blocks.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./blocks.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport React from 'react';\nimport Box from '../box/box.jsx';\nimport styles from './blocks.css';\n\nconst BlocksComponent = props => {\n const {\n containerRef,\n dragOver,\n ...componentProps\n } = props;\n return (\n \n );\n};\nBlocksComponent.propTypes = {\n containerRef: PropTypes.func,\n dragOver: PropTypes.bool\n};\nexport default BlocksComponent;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./box.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./box.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./box.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport stylePropType from 'react-style-proptype';\nimport styles from './box.css';\n\nconst getRandomColor = (function () {\n // In \"DEBUG\" mode this is used to output a random background color for each\n // box. The function gives the same \"random\" set for each seed, allowing re-\n // renders of the same content to give the same random display.\n const random = (function (seed) {\n let mW = seed;\n let mZ = 987654321;\n const mask = 0xffffffff;\n return function () {\n mZ = ((36969 * (mZ & 65535)) + (mZ >> 16)) & mask;\n mW = ((18000 * (mW & 65535)) + (mW >> 16)) & mask;\n let result = ((mZ << 16) + mW) & mask;\n result /= 4294967296;\n return result + 1;\n };\n }(601));\n return function () {\n const r = Math.max(parseInt(random() * 100, 10) % 256, 1);\n const g = Math.max(parseInt(random() * 100, 10) % 256, 1);\n const b = Math.max(parseInt(random() * 100, 10) % 256, 1);\n return `rgb(${r},${g},${b})`;\n };\n}());\n\nconst Box = props => {\n const {\n alignContent,\n alignItems,\n alignSelf,\n basis,\n children,\n className,\n componentRef,\n direction,\n element,\n grow,\n height,\n justifyContent,\n width,\n wrap,\n shrink,\n style,\n ...componentProps\n } = props;\n return React.createElement(element, {\n className: classNames(className, styles.box),\n ref: componentRef,\n style: Object.assign(\n {\n alignContent: alignContent,\n alignItems: alignItems,\n alignSelf: alignSelf,\n flexBasis: basis,\n flexDirection: direction,\n flexGrow: grow,\n flexShrink: shrink,\n flexWrap: wrap,\n justifyContent: justifyContent,\n width: width,\n height: height\n },\n process.env.DEBUG ? {\n backgroundColor: getRandomColor(),\n outline: `1px solid black`\n } : {},\n style\n ),\n ...componentProps\n }, children);\n};\nBox.propTypes = {\n /** Defines how the browser distributes space between and around content items vertically within this box. */\n alignContent: PropTypes.oneOf([\n 'flex-start', 'flex-end', 'center', 'space-between', 'space-around', 'stretch'\n ]),\n /** Defines how the browser distributes space between and around flex items horizontally within this box. */\n alignItems: PropTypes.oneOf([\n 'flex-start', 'flex-end', 'center', 'baseline', 'stretch'\n ]),\n /** Specifies how this box should be aligned inside of its container (requires the container to be flexable). */\n alignSelf: PropTypes.oneOf([\n 'auto', 'flex-start', 'flex-end', 'center', 'baseline', 'stretch'\n ]),\n /** Specifies the initial length of this box */\n basis: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.oneOf(['auto'])\n ]),\n /** Specifies the the HTML nodes which will be child elements of this box. */\n children: PropTypes.node,\n /** Specifies the class name that will be set on this box */\n className: PropTypes.string,\n /**\n * A callback function whose first parameter is the underlying dom elements.\n * This call back will be executed immediately after the component is mounted or unmounted\n */\n componentRef: PropTypes.func,\n /** https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction */\n direction: PropTypes.oneOf([\n 'row', 'row-reverse', 'column', 'column-reverse'\n ]),\n /** Specifies the type of HTML element of this box. Defaults to div. */\n element: PropTypes.string,\n /** Specifies the flex grow factor of a flex item. */\n grow: PropTypes.number,\n /** The height in pixels (if specified as a number) or a string if different units are required. */\n height: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.string\n ]),\n /** https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content */\n justifyContent: PropTypes.oneOf([\n 'flex-start', 'flex-end', 'center', 'space-between', 'space-around'\n ]),\n /** Specifies the flex shrink factor of a flex item. */\n shrink: PropTypes.number,\n /** An object whose keys are css property names and whose values correspond the the css property. */\n style: stylePropType,\n /** The width in pixels (if specified as a number) or a string if different units are required. */\n width: PropTypes.oneOfType([\n PropTypes.number,\n PropTypes.string\n ]),\n /** How whitespace should wrap within this block. */\n wrap: PropTypes.oneOf([\n 'nowrap', 'wrap', 'wrap-reverse'\n ])\n};\nBox.defaultProps = {\n element: 'div',\n style: {}\n};\nexport default Box;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./browser-modal.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./browser-modal.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./browser-modal.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactModal from 'react-modal';\nimport Box from '../box/box.jsx';\nimport {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl';\n\nimport styles from './browser-modal.css';\nimport unhappyBrowser from './unsupported-browser.svg';\n\nconst messages = defineMessages({\n label: {\n id: 'gui.unsupportedBrowser.label',\n defaultMessage: 'Browser is not supported',\n description: ''\n },\n error: {\n id: 'gui.unsupportedBrowser.errorLabel',\n defaultMessage: 'An Error Occurred',\n description: 'Heading shown when there is an unhandled exception in an unsupported browser'\n }\n});\n\nconst BrowserModal = ({intl, ...props}) => {\n const label = props.error ? messages.error : messages.label;\n return (\n \n
\n \n \n \n\n \n

\n \n

\n

\n { /* eslint-disable max-len */ }\n {\n props.error ? : \n }\n { /* eslint-enable max-len */ }\n

\n\n \n \n \n \n\n \n
\n \n \n \n )\n }}\n />\n
\n
\n
\n \n );\n};\n\nBrowserModal.propTypes = {\n error: PropTypes.bool,\n intl: intlShape.isRequired,\n isRtl: PropTypes.bool,\n onBack: PropTypes.func.isRequired\n};\n\nBrowserModal.defaultProps = {\n error: false\n};\n\nconst WrappedBrowserModal = injectIntl(BrowserModal);\n\nWrappedBrowserModal.setAppElement = ReactModal.setAppElement;\n\nexport default WrappedBrowserModal;\n","module.exports = __webpack_public_path__ + \"static/assets/89a5687599f173f2b910aa5fcd862b42.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./button.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./button.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./button.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport styles from './button.css';\n\nconst ButtonComponent = ({\n className,\n disabled,\n iconClassName,\n iconSrc,\n onClick,\n children,\n ...props\n}) => {\n\n if (disabled) {\n onClick = function () {};\n }\n\n const icon = iconSrc && (\n \n );\n\n return (\n \n {icon}\n
{children}
\n \n );\n};\n\nButtonComponent.propTypes = {\n children: PropTypes.node,\n className: PropTypes.string,\n disabled: PropTypes.bool,\n iconClassName: PropTypes.string,\n iconSrc: PropTypes.string,\n onClick: PropTypes.func\n};\n\nexport default ButtonComponent;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./camera-modal.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./camera-modal.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./camera-modal.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport {defineMessages, injectIntl, intlShape} from 'react-intl';\nimport Box from '../box/box.jsx';\nimport Modal from '../../containers/modal.jsx';\nimport styles from './camera-modal.css';\nimport backIcon from './icon--back.svg';\nimport cameraIcon from '../action-menu/icon--camera.svg';\n\nconst messages = defineMessages({\n cameraModalTitle: {\n defaultMessage: 'Take a Photo',\n description: 'Title for prompt to take a picture (to add as a new costume).',\n id: 'gui.cameraModal.cameraModalTitle'\n },\n loadingCameraMessage: {\n defaultMessage: 'Loading Camera...',\n description: 'Notification to the user that the camera is loading',\n id: 'gui.cameraModal.loadingCameraMessage'\n },\n permissionRequest: {\n defaultMessage: 'We need your permission to use your camera',\n description: 'Notification to the user that the app needs camera access',\n id: 'gui.cameraModal.permissionRequest'\n },\n retakePhoto: {\n defaultMessage: 'Retake Photo',\n description: 'A button that allows the user to take the picture again, replacing the old one',\n id: 'gui.cameraModal.retakePhoto'\n },\n save: {\n defaultMessage: 'Save',\n description: 'A button that allows the user to save the photo they took as a costume',\n id: 'gui.cameraModal.save'\n },\n takePhotoButton: {\n defaultMessage: 'Take Photo',\n description: 'A button to take a photo',\n id: 'gui.cameraModal.takePhoto'\n },\n loadingCaption: {\n defaultMessage: 'Loading...',\n description: 'A caption for a disabled button while the video from the camera is still loading',\n id: 'gui.cameraModal.loadingCaption'\n },\n enableCameraCaption: {\n defaultMessage: 'Enable Camera',\n description: 'A caption for a disabled button prompting the user to enable camera access',\n id: 'gui.cameraModal.enableCameraCaption'\n }\n});\n\nconst CameraModal = ({intl, ...props}) => (\n \n \n \n
\n {props.access ? intl.formatMessage(messages.loadingCameraMessage) :\n `↖️ \\u00A0${intl.formatMessage(messages.permissionRequest)}`}\n
\n \n {props.capture ? (\n
\n ) : null}\n \n {props.capture ?\n \n \n {intl.formatMessage(messages.retakePhoto)}\n \n {intl.formatMessage(messages.save)}\n \n :\n \n \n \n \n
\n {props.access ?\n \n {props.loaded ?\n intl.formatMessage(messages.takePhotoButton) :\n intl.formatMessage(messages.loadingCaption)}\n :\n \n {intl.formatMessage(messages.enableCameraCaption)}\n \n }\n
\n\n
\n }\n \n \n);\n\nCameraModal.propTypes = {\n access: PropTypes.bool,\n canvasRef: PropTypes.func.isRequired,\n capture: PropTypes.string,\n intl: intlShape.isRequired,\n loaded: PropTypes.bool,\n onBack: PropTypes.func.isRequired,\n onCancel: PropTypes.func.isRequired,\n onCapture: PropTypes.func.isRequired,\n onSubmit: PropTypes.func.isRequired\n};\n\nexport default injectIntl(CameraModal);\n","module.exports = __webpack_public_path__ + \"static/assets/21988681fa28c8ce37982ca26463a6f5.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./card.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./card.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./card.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React, {Fragment} from 'react';\nimport classNames from 'classnames';\nimport {FormattedMessage} from 'react-intl';\nimport Draggable from 'react-draggable';\n\nimport styles from './card.css';\n\nimport shrinkIcon from './icon--shrink.svg';\nimport expandIcon from './icon--expand.svg';\n\nimport rightArrow from './icon--next.svg';\nimport leftArrow from './icon--prev.svg';\n\nimport helpIcon from '../../lib/assets/icon--tutorials.svg';\nimport closeIcon from './icon--close.svg';\n\nimport {translateVideo} from '../../lib/libraries/decks/translate-video.js';\nimport {translateImage} from '../../lib/libraries/decks/translate-image.js';\n\nconst CardHeader = ({onCloseCards, onShrinkExpandCards, onShowAll, totalSteps, step, expanded}) => (\n
\n \n \n \n
\n {totalSteps > 1 ? (\n
\n {Array(totalSteps).fill(0)\n .map((_, i) => (\n \n ))}\n
\n ) : null}\n
\n \n \n {expanded ?\n :\n \n }\n
\n \n \n \n
\n \n \n);\n\nclass VideoStep extends React.Component {\n\n componentDidMount () {\n const script = document.createElement('script');\n script.src = `https://fast.wistia.com/embed/medias/${this.props.video}.jsonp`;\n script.async = true;\n script.setAttribute('id', 'wistia-video-content');\n document.body.appendChild(script);\n\n const script2 = document.createElement('script');\n script2.src = 'https://fast.wistia.com/assets/external/E-v1.js';\n script2.async = true;\n script2.setAttribute('id', 'wistia-video-api');\n document.body.appendChild(script2);\n }\n\n // We use the Wistia API here to update or pause the video dynamically:\n // https://wistia.com/support/developers/player-api\n componentDidUpdate (prevProps) {\n // Ensure the wistia API is loaded and available\n if (!(window.Wistia && window.Wistia.api)) return;\n\n // Get a handle on the currently loaded video\n const video = window.Wistia.api(prevProps.video);\n\n // Reset the video source if a new video has been chosen from the library\n if (prevProps.video !== this.props.video) {\n video.replaceWith(this.props.video);\n }\n\n // Pause the video if the modal is being shrunken\n if (!this.props.expanded) {\n video.pause();\n }\n }\n\n componentWillUnmount () {\n const script = document.getElementById('wistia-video-content');\n script.parentNode.removeChild(script);\n\n const script2 = document.getElementById('wistia-video-api');\n script2.parentNode.removeChild(script2);\n }\n\n render () {\n return (\n
\n \n  \n
\n \n );\n }\n}\n\nVideoStep.propTypes = {\n expanded: PropTypes.bool.isRequired,\n video: PropTypes.string.isRequired\n};\n\nconst ImageStep = ({title, image}) => (\n \n
\n {title}\n
\n
\n \n
\n
\n);\n\nImageStep.propTypes = {\n image: PropTypes.string.isRequired,\n title: PropTypes.node.isRequired\n};\n\nconst NextPrevButtons = ({isRtl, onNextStep, onPrevStep, expanded}) => (\n \n {onNextStep ? (\n
\n
\n \n \n
\n
\n ) : null}\n {onPrevStep ? (\n
\n
\n \n \n
\n
\n ) : null}\n
\n);\n\nNextPrevButtons.propTypes = {\n expanded: PropTypes.bool.isRequired,\n isRtl: PropTypes.bool,\n onNextStep: PropTypes.func,\n onPrevStep: PropTypes.func\n};\nCardHeader.propTypes = {\n expanded: PropTypes.bool.isRequired,\n onCloseCards: PropTypes.func.isRequired,\n onShowAll: PropTypes.func.isRequired,\n onShrinkExpandCards: PropTypes.func.isRequired,\n step: PropTypes.number,\n totalSteps: PropTypes.number\n};\n\nconst PreviewsStep = ({deckIds, content, onActivateDeckFactory, onShowAll}) => (\n \n
\n \n
\n
\n {deckIds.slice(0, 2).map(id => (\n \n \n
{content[id].name}
\n
\n ))}\n \n
\n \n \n
\n \n
\n);\n\nPreviewsStep.propTypes = {\n content: PropTypes.shape({\n id: PropTypes.shape({\n name: PropTypes.node.isRequired,\n img: PropTypes.string.isRequired,\n steps: PropTypes.arrayOf(PropTypes.shape({\n title: PropTypes.node,\n image: PropTypes.string,\n video: PropTypes.string,\n deckIds: PropTypes.arrayOf(PropTypes.string)\n }))\n })\n }).isRequired,\n deckIds: PropTypes.arrayOf(PropTypes.string).isRequired,\n onActivateDeckFactory: PropTypes.func.isRequired,\n onShowAll: PropTypes.func.isRequired\n};\n\nconst Cards = props => {\n const {\n activeDeckId,\n content,\n dragging,\n isRtl,\n locale,\n onActivateDeckFactory,\n onCloseCards,\n onShrinkExpandCards,\n onDrag,\n onStartDrag,\n onEndDrag,\n onShowAll,\n onNextStep,\n onPrevStep,\n showVideos,\n step,\n expanded,\n ...posProps\n } = props;\n let {x, y} = posProps;\n\n if (activeDeckId === null) return;\n\n // Tutorial cards need to calculate their own dragging bounds\n // to allow for dragging the cards off the left, right and bottom\n // edges of the workspace.\n const cardHorizontalDragOffset = 400; // ~80% of card width\n const cardVerticalDragOffset = expanded ? 257 : 0; // ~80% of card height, if expanded\n const menuBarHeight = 48; // TODO: get pre-calculated from elsewhere?\n const wideCardWidth = 500;\n\n if (x === 0 && y === 0) {\n // initialize positions\n x = isRtl ? (-190 - wideCardWidth - cardHorizontalDragOffset) : 292;\n x += cardHorizontalDragOffset;\n // The tallest cards are about 320px high, and the default position is pinned\n // to near the bottom of the blocks palette to allow room to work above.\n const tallCardHeight = 320;\n const bottomMargin = 60; // To avoid overlapping the backpack region\n y = window.innerHeight - tallCardHeight - bottomMargin - menuBarHeight;\n }\n\n const steps = content[activeDeckId].steps;\n\n return (\n // Custom overlay to act as the bounding parent for the draggable, using values from above\n \n \n
\n
\n \n
\n {steps[step].deckIds ? (\n \n ) : (\n steps[step].video ? (\n showVideos ? (\n \n ) : ( // Else show the deck image and title\n \n )\n ) : (\n \n )\n )}\n {steps[step].trackingPixel && steps[step].trackingPixel}\n
\n 0 ? onPrevStep : null}\n />\n
\n
\n \n \n );\n};\n\nCards.propTypes = {\n activeDeckId: PropTypes.string.isRequired,\n content: PropTypes.shape({\n id: PropTypes.shape({\n name: PropTypes.node.isRequired,\n img: PropTypes.string.isRequired,\n steps: PropTypes.arrayOf(PropTypes.shape({\n title: PropTypes.node,\n image: PropTypes.string,\n video: PropTypes.string,\n deckIds: PropTypes.arrayOf(PropTypes.string)\n }))\n })\n }),\n dragging: PropTypes.bool.isRequired,\n expanded: PropTypes.bool.isRequired,\n isRtl: PropTypes.bool.isRequired,\n locale: PropTypes.string.isRequired,\n onActivateDeckFactory: PropTypes.func.isRequired,\n onCloseCards: PropTypes.func.isRequired,\n onDrag: PropTypes.func,\n onEndDrag: PropTypes.func,\n onNextStep: PropTypes.func.isRequired,\n onPrevStep: PropTypes.func.isRequired,\n onShowAll: PropTypes.func,\n onShrinkExpandCards: PropTypes.func.isRequired,\n onStartDrag: PropTypes.func,\n showVideos: PropTypes.bool,\n step: PropTypes.number.isRequired,\n x: PropTypes.number,\n y: PropTypes.number\n};\n\nCards.defaultProps = {\n showVideos: true\n};\n\nexport {\n Cards as default,\n // Others exported for testability\n ImageStep,\n VideoStep\n};\n","module.exports = __webpack_public_path__ + \"static/assets/a3e689235188ba10c5cfd75730cb88a7.svg\";","module.exports = __webpack_public_path__ + \"static/assets/04e28ba12fe914cf4f131dcb85ae82d6.svg\";","module.exports = __webpack_public_path__ + \"static/assets/a80790c977586cc0595b5fe2f0bcb39a.svg\";","module.exports = __webpack_public_path__ + \"static/assets/33592a76d0d0fdaa4a32b2ea41db5e16.svg\";","module.exports = __webpack_public_path__ + \"static/assets/76121b7f4eff7d7ca0d49a45479d3f3f.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./close-button.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./close-button.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./close-button.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\n\nimport styles from './close-button.css';\nimport closeIcon from './icon--close.svg';\nimport closeIconOrange from './icon--close-orange.svg';\nimport backIcon from '../../lib/assets/icon--back.svg';\n\nlet closeIcons = {};\n\nconst CloseButton = props => (\n \n {props.buttonType === 'back' ?\n :\n \n }\n \n);\n\nCloseButton.SIZE_SMALL = 'small';\nCloseButton.SIZE_LARGE = 'large';\n\nCloseButton.COLOR_NEUTRAL = 'neutral';\nCloseButton.COLOR_GREEN = 'green';\nCloseButton.COLOR_ORANGE = 'orange';\ncloseIcons = {\n [CloseButton.COLOR_NEUTRAL]: closeIcon,\n [CloseButton.COLOR_GREEN]: closeIcon, // TODO: temporary, need green icon\n [CloseButton.COLOR_ORANGE]: closeIconOrange\n};\n\n\nCloseButton.propTypes = {\n buttonType: PropTypes.oneOf(['back', 'close']),\n className: PropTypes.string,\n color: PropTypes.string,\n onClick: PropTypes.func.isRequired,\n size: PropTypes.oneOf([CloseButton.SIZE_SMALL, CloseButton.SIZE_LARGE])\n};\n\nCloseButton.defaultProps = {\n color: CloseButton.COLOR_NEUTRAL,\n size: CloseButton.SIZE_LARGE,\n buttonType: 'close'\n};\n\nexport default CloseButton;\n","module.exports = __webpack_public_path__ + \"static/assets/ee54d776d2cda9a3c537ac7e8f144037.svg\";","module.exports = __webpack_public_path__ + \"static/assets/cb666b99d3528f91b52f985dfb102afa.svg\";","module.exports = __webpack_public_path__ + \"static/assets/97926439955086f8ee4aabbd81580f17.png\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./coming-soon.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./coming-soon.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./coming-soon.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import bindAll from 'lodash.bindall';\nimport classNames from 'classnames';\nimport {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport ReactTooltip from 'react-tooltip';\n\nimport styles from './coming-soon.css';\n\nimport awwCatIcon from './aww-cat.png';\nimport coolCatIcon from './cool-cat.png';\n\nconst messages = defineMessages({\n message1: {\n defaultMessage: 'Don\\'t worry, we\\'re on it {emoji}',\n description: 'One of the \"coming soon\" random messages for yet-to-be-done features',\n id: 'gui.comingSoon.message1'\n },\n message2: {\n defaultMessage: 'Coming Soon...',\n description: 'One of the \"coming soon\" random messages for yet-to-be-done features',\n id: 'gui.comingSoon.message2'\n },\n message3: {\n defaultMessage: 'We\\'re working on it {emoji}',\n description: 'One of the \"coming soon\" random messages for yet-to-be-done features',\n id: 'gui.comingSoon.message3'\n }\n});\n\nclass ComingSoonContent extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'setHide',\n 'setShow',\n 'getRandomMessage'\n ]);\n this.state = {\n isShowing: false\n };\n }\n setShow () {\n // needed to set the opacity to 1, since the default is .9 on show\n this.setState({isShowing: true});\n }\n setHide () {\n this.setState({isShowing: false});\n }\n getRandomMessage () {\n // randomly chooses a messages from `messages` to display in the tooltip.\n const images = [awwCatIcon, coolCatIcon];\n const messageNumber = Math.floor(Math.random() * Object.keys(messages).length) + 1;\n const imageNumber = Math.floor(Math.random() * Object.keys(images).length);\n return (\n \n )\n }}\n />\n );\n }\n render () {\n return (\n \n );\n }\n}\n\nComingSoonContent.propTypes = {\n className: PropTypes.string,\n intl: intlShape,\n place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),\n tooltipId: PropTypes.string.isRequired\n};\n\nComingSoonContent.defaultProps = {\n place: 'bottom'\n};\n\nconst ComingSoon = injectIntl(ComingSoonContent);\n\nconst ComingSoonTooltip = props => (\n
\n \n {props.children}\n
\n \n \n);\n\nComingSoonTooltip.propTypes = {\n children: PropTypes.node.isRequired,\n className: PropTypes.string,\n delayHide: PropTypes.number,\n delayShow: PropTypes.number,\n place: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),\n tooltipClassName: PropTypes.string,\n tooltipId: PropTypes.string.isRequired\n};\n\nComingSoonTooltip.defaultProps = {\n delayHide: 0,\n delayShow: 0\n};\n\nexport {\n ComingSoon as ComingSoonComponent,\n ComingSoonTooltip\n};\n","module.exports = __webpack_public_path__ + \"static/assets/3e83d9d800459175308f0b45b117af16.png\";","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport keyMirror from 'keymirror';\nimport classNames from 'classnames';\n\nimport Box from '../box/box.jsx';\nimport Dots from './dots.jsx';\n\nimport closeIcon from '../close-button/icon--close.svg';\n\nimport radarIcon from './icons/searching.png';\nimport bluetoothIcon from './icons/bluetooth-white.svg';\nimport backIcon from './icons/back.svg';\n\nimport styles from './connection-modal.css';\n\nconst PHASES = keyMirror({\n prescan: null,\n pressbutton: null,\n notfound: null\n});\n\nconst AutoScanningStep = props => (\n \n \n
\n
\n {props.phase === PHASES.prescan && (\n \n \n \n \n )}\n {props.phase === PHASES.pressbutton && (\n \n \n \n \n )}\n {props.phase === PHASES.notfound && (\n \n \n \n )}\n
\n
\n
\n \n \n {props.phase === PHASES.prescan && (\n \n )}\n {props.phase === PHASES.pressbutton && (\n \n )}\n \n \n \n {props.phase === PHASES.prescan && (\n \n \n \n )}\n {props.phase === PHASES.pressbutton && (\n
\n \n \n \n \n \n \n
\n )}\n {props.phase === PHASES.notfound && (\n \n \n \n \n )}\n
\n
\n
\n);\n\nAutoScanningStep.propTypes = {\n connectionTipIconURL: PropTypes.string,\n onRefresh: PropTypes.func,\n onStartScan: PropTypes.func,\n phase: PropTypes.oneOf(Object.keys(PHASES))\n};\n\nAutoScanningStep.defaultProps = {\n phase: PHASES.prescan\n};\n\nexport {\n AutoScanningStep as default,\n PHASES\n};\n","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport Box from '../box/box.jsx';\nimport Dots from './dots.jsx';\nimport bluetoothIcon from './icons/bluetooth-white.svg';\nimport styles from './connection-modal.css';\nimport classNames from 'classnames';\n\nconst ConnectedStep = props => (\n \n \n \n
\n \n \n
\n
\n
\n \n \n \n \n \n
\n \n \n \n \n \n \n
\n
\n
\n);\n\nConnectedStep.propTypes = {\n connectionIconURL: PropTypes.string.isRequired,\n onCancel: PropTypes.func,\n onDisconnect: PropTypes.func\n};\n\nexport default ConnectedStep;\n","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\n\nimport Box from '../box/box.jsx';\nimport Dots from './dots.jsx';\n\nimport bluetoothIcon from './icons/bluetooth-white.svg';\nimport closeIcon from '../close-button/icon--close.svg';\n\nimport styles from './connection-modal.css';\n\nconst ConnectingStep = props => (\n \n \n \n
\n \n \n
\n
\n
\n \n \n {props.connectingMessage}\n \n \n
\n \n \n \n \n \n \n
\n
\n
\n);\n\nConnectingStep.propTypes = {\n connectingMessage: PropTypes.node.isRequired,\n connectionIconURL: PropTypes.string.isRequired,\n onDisconnect: PropTypes.func\n};\n\nexport default ConnectingStep;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./connection-modal.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./connection-modal.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./connection-modal.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport keyMirror from 'keymirror';\n\nimport Box from '../box/box.jsx';\nimport Modal from '../../containers/modal.jsx';\n\nimport ScanningStep from '../../containers/scanning-step.jsx';\nimport AutoScanningStep from '../../containers/auto-scanning-step.jsx';\nimport ConnectingStep from './connecting-step.jsx';\nimport ConnectedStep from './connected-step.jsx';\nimport ErrorStep from './error-step.jsx';\nimport UnavailableStep from './unavailable-step.jsx';\n\nimport styles from './connection-modal.css';\n\nconst PHASES = keyMirror({\n scanning: null,\n connecting: null,\n connected: null,\n error: null,\n unavailable: null\n});\n\nconst ConnectionModalComponent = props => (\n \n \n {props.phase === PHASES.scanning && !props.useAutoScan && }\n {props.phase === PHASES.scanning && props.useAutoScan && }\n {props.phase === PHASES.connecting && }\n {props.phase === PHASES.connected && }\n {props.phase === PHASES.error && }\n {props.phase === PHASES.unavailable && }\n \n \n);\n\nConnectionModalComponent.propTypes = {\n connectingMessage: PropTypes.node.isRequired,\n connectionSmallIconURL: PropTypes.string,\n connectionTipIconURL: PropTypes.string,\n name: PropTypes.node,\n onCancel: PropTypes.func.isRequired,\n onHelp: PropTypes.func.isRequired,\n phase: PropTypes.oneOf(Object.keys(PHASES)).isRequired,\n title: PropTypes.string.isRequired,\n useAutoScan: PropTypes.bool.isRequired\n};\n\nConnectionModalComponent.defaultProps = {\n connectingMessage: 'Connecting'\n};\n\nexport {\n ConnectionModalComponent as default,\n PHASES\n};\n","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\n\nimport Box from '../box/box.jsx';\nimport styles from './connection-modal.css';\n\nconst Dots = props => (\n \n \n {Array(props.total).fill(0)\n .map((_, i) => {\n let type = 'inactive';\n if (props.counter === i) type = 'active';\n if (props.success) type = 'success';\n if (props.error) type = 'error';\n return ();\n })}\n \n
\n);\n\nDots.propTypes = {\n className: PropTypes.string,\n counter: PropTypes.number,\n error: PropTypes.bool,\n success: PropTypes.bool,\n total: PropTypes.number\n};\n\nconst Dot = props => (\n \n);\n\nDot.propTypes = {\n type: PropTypes.string\n};\n\nexport default Dots;\n","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport React from 'react';\n\nimport Box from '../box/box.jsx';\nimport Dots from './dots.jsx';\nimport helpIcon from './icons/help.svg';\nimport backIcon from './icons/back.svg';\n\nimport styles from './connection-modal.css';\n\nconst ErrorStep = props => (\n \n \n \n
\n \n
\n
\n
\n \n
\n \n
\n \n \n \n \n \n \n \n \n \n \n \n
\n
\n);\n\nErrorStep.propTypes = {\n connectionIconURL: PropTypes.string.isRequired,\n onHelp: PropTypes.func,\n onScanning: PropTypes.func\n};\n\nexport default ErrorStep;\n","module.exports = __webpack_public_path__ + \"static/assets/42157e6edddc19588c3c2ff188703799.svg\";","module.exports = __webpack_public_path__ + \"static/assets/0fd9fd69a38ab79358df5a77b29702c8.svg\";","module.exports = __webpack_public_path__ + \"static/assets/8b8f2d052b4092ec47ad66c30c8b1642.svg\";","module.exports = __webpack_public_path__ + \"static/assets/4b6100c9f591be6470cdfd4697de0b54.svg\";","module.exports = __webpack_public_path__ + \"static/assets/71655cde34ae75f48cb8820abf4b31e7.svg\";","module.exports = __webpack_public_path__ + \"static/assets/05e05756b592740a3670417b4df19ca9.svg\";","module.exports = __webpack_public_path__ + \"static/assets/572a212c2e777e3a9061c97453497009.png\";","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport React from 'react';\nimport bindAll from 'lodash.bindall';\nimport Box from '../box/box.jsx';\n\nimport styles from './connection-modal.css';\n\nclass PeripheralTile extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'handleConnecting'\n ]);\n }\n handleConnecting () {\n this.props.onConnecting(this.props.peripheralId);\n }\n render () {\n return (\n \n \n \n \n \n \n \n \n {this.props.name}\n \n \n \n \n \n -80\n })}\n />\n -60\n })}\n />\n -40\n })}\n />\n -20\n })}\n />\n \n \n \n \n \n \n );\n }\n}\n\nPeripheralTile.propTypes = {\n connectionSmallIconURL: PropTypes.string,\n name: PropTypes.string,\n onConnecting: PropTypes.func,\n peripheralId: PropTypes.string,\n rssi: PropTypes.number\n};\n\nexport default PeripheralTile;\n","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\n\nimport Box from '../box/box.jsx';\nimport PeripheralTile from './peripheral-tile.jsx';\nimport Dots from './dots.jsx';\n\nimport radarIcon from './icons/searching.png';\nimport refreshIcon from './icons/refresh.svg';\n\nimport styles from './connection-modal.css';\n\nconst ScanningStep = props => (\n \n \n {props.scanning ? (\n props.peripheralList.length === 0 ? (\n
\n
\n \n \n
\n
\n ) : (\n
\n {props.peripheralList.map(peripheral =>\n ()\n )}\n
\n )\n ) : (\n \n \n \n )}\n
\n \n \n \n \n \n \n \n \n \n \n
\n);\n\nScanningStep.propTypes = {\n connectionSmallIconURL: PropTypes.string,\n onConnecting: PropTypes.func,\n onRefresh: PropTypes.func,\n peripheralList: PropTypes.arrayOf(PropTypes.shape({\n name: PropTypes.string,\n rssi: PropTypes.number,\n peripheralId: PropTypes.string\n })),\n scanning: PropTypes.bool.isRequired\n};\n\nScanningStep.defaultProps = {\n peripheralList: [],\n scanning: true\n};\n\nexport default ScanningStep;\n","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport React from 'react';\n\nimport Box from '../box/box.jsx';\nimport Dots from './dots.jsx';\nimport helpIcon from './icons/help.svg';\nimport backIcon from './icons/back.svg';\nimport bluetoothIcon from './icons/bluetooth.svg';\nimport scratchLinkIcon from './icons/scratchlink.svg';\n\nimport styles from './connection-modal.css';\n\nconst UnavailableStep = props => (\n \n \n
\n
\n
\n {'1'}\n
\n
\n \n
\n
\n \n
\n
\n
\n
\n {'2'}\n
\n
\n \n
\n
\n \n
\n
\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n);\n\nUnavailableStep.propTypes = {\n onHelp: PropTypes.func,\n onScanning: PropTypes.func\n};\n\nexport default UnavailableStep;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./context-menu.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./context-menu.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./context-menu.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport {ContextMenu, MenuItem} from 'react-contextmenu';\nimport classNames from 'classnames';\n\nimport styles from './context-menu.css';\n\nconst StyledContextMenu = props => (\n \n);\n\nconst StyledMenuItem = props => (\n \n);\n\nconst BorderedMenuItem = props => (\n \n);\n\nconst DangerousMenuItem = props => (\n \n);\n\n\nexport {\n BorderedMenuItem,\n DangerousMenuItem,\n StyledContextMenu as ContextMenu,\n StyledMenuItem as MenuItem\n};\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./controls.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./controls.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./controls.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {defineMessages, injectIntl, intlShape} from 'react-intl';\n\nimport GreenFlag from '../green-flag/green-flag.jsx';\nimport StopAll from '../stop-all/stop-all.jsx';\nimport TurboMode from '../turbo-mode/turbo-mode.jsx';\n\nimport styles from './controls.css';\n\nconst messages = defineMessages({\n goTitle: {\n id: 'gui.controls.go',\n defaultMessage: 'Go',\n description: 'Green flag button title'\n },\n stopTitle: {\n id: 'gui.controls.stop',\n defaultMessage: 'Stop',\n description: 'Stop button title'\n }\n});\n\nconst Controls = function (props) {\n const {\n active,\n className,\n intl,\n onGreenFlagClick,\n onStopAllClick,\n turbo,\n ...componentProps\n } = props;\n return (\n \n \n \n {turbo ? (\n \n ) : null}\n \n );\n};\n\nControls.propTypes = {\n active: PropTypes.bool,\n className: PropTypes.string,\n intl: intlShape.isRequired,\n onGreenFlagClick: PropTypes.func.isRequired,\n onStopAllClick: PropTypes.func.isRequired,\n turbo: PropTypes.bool\n};\n\nControls.defaultProps = {\n active: false,\n turbo: false\n};\n\nexport default injectIntl(Controls);\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./crash-message.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./crash-message.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./crash-message.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport Box from '../box/box.jsx';\nimport {FormattedMessage} from 'react-intl';\n\nimport styles from './crash-message.css';\nimport reloadIcon from './reload.svg';\n\nconst CrashMessage = props => (\n
\n \n \n

\n \n

\n

\n \n

\n {props.eventId && (\n

\n \n

\n )}\n \n \n \n
\n
\n);\n\nCrashMessage.propTypes = {\n eventId: PropTypes.string,\n onReload: PropTypes.func.isRequired\n};\n\nexport default CrashMessage;\n","module.exports = __webpack_public_path__ + \"static/assets/dd98971c2c185caf86144b6b5234d0fa.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./custom-procedures.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./custom-procedures.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./custom-procedures.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport Modal from '../../containers/modal.jsx';\nimport Box from '../box/box.jsx';\nimport {defineMessages, injectIntl, intlShape, FormattedMessage} from 'react-intl';\n\nimport booleanInputIcon from './icon--boolean-input.svg';\nimport textInputIcon from './icon--text-input.svg';\nimport labelIcon from './icon--label.svg';\n\nimport styles from './custom-procedures.css';\n\nconst messages = defineMessages({\n myblockModalTitle: {\n defaultMessage: 'Make a Block',\n description: 'Title for the modal where you create a custom block.',\n id: 'gui.customProcedures.myblockModalTitle'\n }\n});\n\nconst CustomProcedures = props => (\n \n \n \n
\n \n \n
\n \n
\n
\n \n
\n
\n \n \n
\n \n
\n
\n \n
\n \n \n \n
\n \n
\n \n \n
\n \n
\n \n \n \n \n \n \n \n \n
\n \n);\n\nCustomProcedures.propTypes = {\n componentRef: PropTypes.func.isRequired,\n intl: intlShape,\n onAddBoolean: PropTypes.func.isRequired,\n onAddLabel: PropTypes.func.isRequired,\n onAddTextNumber: PropTypes.func.isRequired,\n onCancel: PropTypes.func.isRequired,\n onOk: PropTypes.func.isRequired,\n onToggleWarp: PropTypes.func.isRequired,\n warp: PropTypes.bool.isRequired\n};\n\nexport default injectIntl(CustomProcedures);\n","module.exports = __webpack_public_path__ + \"static/assets/10811a978de201353d564df7ba1ddb58.svg\";","module.exports = __webpack_public_path__ + \"static/assets/8beb9da10f72d02b48baf0b24ac72449.svg\";","module.exports = __webpack_public_path__ + \"static/assets/2a70b21aaaed0619bdfcdec91db1ebe8.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./delete-button.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./delete-button.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./delete-button.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\n\nimport styles from './delete-button.css';\nimport deleteIcon from './icon--delete.svg';\n\nconst DeleteButton = props => (\n \n
\n \n
\n \n\n);\n\nDeleteButton.propTypes = {\n className: PropTypes.string,\n onClick: PropTypes.func.isRequired,\n tabIndex: PropTypes.number\n};\n\nDeleteButton.defaultProps = {\n tabIndex: 0\n};\n\nexport default DeleteButton;\n","module.exports = __webpack_public_path__ + \"static/assets/a5787bb7364d8131ed49a8f53037d7f4.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./dial.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./dial.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./dial.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport bindAll from 'lodash.bindall';\nimport React from 'react';\nimport {getEventXY} from '../../lib/touch-utils';\n\nimport styles from './dial.css';\n\nimport dialFace from './icon--dial.svg';\nimport dialHandle from './icon--handle.svg';\n\nclass Dial extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'handleMouseDown',\n 'handleMouseMove',\n 'containerRef',\n 'handleRef',\n 'unbindMouseEvents'\n ]);\n }\n\n componentDidMount () {\n // Manually add touch/mouse handlers so that preventDefault can be used\n // to prevent scrolling on touch.\n // Tracked as a react issue https://github.com/facebook/react/issues/6436\n this.handleElement.addEventListener('mousedown', this.handleMouseDown);\n this.handleElement.addEventListener('touchstart', this.handleMouseDown);\n }\n\n componentWillUnmount () {\n this.unbindMouseEvents();\n this.handleElement.removeEventListener('mousedown', this.handleMouseDown);\n this.handleElement.removeEventListener('touchstart', this.handleMouseDown);\n }\n\n /**\n * Get direction from dial center to mouse move event.\n * @param {Event} e - Mouse move event.\n * @returns {number} Direction in degrees, clockwise, 90=horizontal.\n */\n directionToMouseEvent (e) {\n const {x: mx, y: my} = getEventXY(e);\n const bbox = this.containerElement.getBoundingClientRect();\n const cy = bbox.top + (bbox.height / 2);\n const cx = bbox.left + (bbox.width / 2);\n const angle = Math.atan2(my - cy, mx - cx);\n const degrees = angle * (180 / Math.PI);\n return degrees + 90; // To correspond with scratch coordinate system\n }\n\n /**\n * Create SVG path data string for the dial \"gauge\", the overlaid arc slice.\n * @param {number} radius - The radius of the dial.\n * @param {number} direction - Direction in degrees, clockwise, 90=horizontal.\n * @returns {string} Path data string for the gauge.\n */\n gaugePath (radius, direction) {\n const rads = (direction) * (Math.PI / 180);\n const path = [];\n path.push(`M ${radius} 0`);\n path.push(`L ${radius} ${radius}`);\n path.push(`L ${radius + (radius * Math.sin(rads))} ${radius - (radius * Math.cos(rads))}`);\n path.push(`A ${radius} ${radius} 0 0 ${direction < 0 ? 1 : 0} ${radius} 0`);\n path.push(`Z`);\n return path.join(' ');\n }\n\n handleMouseMove (e) {\n this.props.onChange(this.directionToMouseEvent(e) + this.directionOffset);\n e.preventDefault();\n }\n\n unbindMouseEvents () {\n window.removeEventListener('mousemove', this.handleMouseMove);\n window.removeEventListener('mouseup', this.unbindMouseEvents);\n window.removeEventListener('touchmove', this.handleMouseMove);\n window.removeEventListener('touchend', this.unbindMouseEvents);\n }\n\n handleMouseDown (e) {\n // Because the drag handle is not a single point, there is some initial\n // difference between the current sprite direction and the direction to the mouse\n // Store this offset to prevent jumping when the mouse is moved.\n this.directionOffset = this.props.direction - this.directionToMouseEvent(e);\n window.addEventListener('mousemove', this.handleMouseMove);\n window.addEventListener('mouseup', this.unbindMouseEvents);\n window.addEventListener('touchmove', this.handleMouseMove);\n window.addEventListener('touchend', this.unbindMouseEvents);\n e.preventDefault();\n }\n\n containerRef (el) {\n this.containerElement = el;\n }\n\n handleRef (el) {\n this.handleElement = el;\n }\n\n render () {\n const {direction, radius} = this.props;\n return (\n
\n \n \n \n \n \n \n
\n \n );\n }\n}\n\nDial.propTypes = {\n direction: PropTypes.number,\n onChange: PropTypes.func.isRequired,\n radius: PropTypes.number\n};\n\nDial.defaultProps = {\n direction: 90, // degrees\n radius: 56 // px\n};\n\nexport default Dial;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./direction-picker.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./direction-picker.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./direction-picker.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Popover from 'react-popover';\nimport {injectIntl, intlShape, defineMessages, FormattedMessage} from 'react-intl';\n\nimport Label from '../forms/label.jsx';\nimport Input from '../forms/input.jsx';\nimport BufferedInputHOC from '../forms/buffered-input-hoc.jsx';\nimport Dial from './dial.jsx';\n\nimport styles from './direction-picker.css';\n\nimport allAroundIcon from './icon--all-around.svg';\nimport leftRightIcon from './icon--left-right.svg';\nimport dontRotateIcon from './icon--dont-rotate.svg';\n\nconst BufferedInput = BufferedInputHOC(Input);\n\nconst directionLabel = (\n \n);\n\nconst RotationStyles = {\n ALL_AROUND: 'all around',\n LEFT_RIGHT: 'left-right',\n DONT_ROTATE: \"don't rotate\"\n};\n\nconst messages = defineMessages({\n allAround: {\n id: 'gui.directionPicker.rotationStyles.allAround',\n description: 'Button to change to the all around rotation style',\n defaultMessage: 'All Around'\n },\n leftRight: {\n id: 'gui.directionPicker.rotationStyles.leftRight',\n description: 'Button to change to the left-right rotation style',\n defaultMessage: 'Left/Right'\n },\n dontRotate: {\n id: 'gui.directionPicker.rotationStyles.dontRotate',\n description: 'Button to change to the dont rotate rotation style',\n defaultMessage: 'Do not rotate'\n }\n});\n\nconst DirectionPicker = props => (\n \n \n \n
\n \n \n \n \n \n \n \n \n \n
\n \n }\n isOpen={props.popoverOpen}\n preferPlace=\"above\"\n onOuterAction={props.onClosePopover}\n >\n \n \n \n\n);\n\nDirectionPicker.propTypes = {\n direction: PropTypes.number,\n disabled: PropTypes.bool.isRequired,\n intl: intlShape,\n labelAbove: PropTypes.bool,\n onChangeDirection: PropTypes.func.isRequired,\n onClickAllAround: PropTypes.func.isRequired,\n onClickDontRotate: PropTypes.func.isRequired,\n onClickLeftRight: PropTypes.func.isRequired,\n onClosePopover: PropTypes.func.isRequired,\n onOpenPopover: PropTypes.func.isRequired,\n popoverOpen: PropTypes.bool.isRequired,\n rotationStyle: PropTypes.string\n};\n\nDirectionPicker.defaultProps = {\n labelAbove: false\n};\n\nconst WrappedDirectionPicker = injectIntl(DirectionPicker);\n\nexport {\n WrappedDirectionPicker as default,\n RotationStyles\n};\n","module.exports = __webpack_public_path__ + \"static/assets/85288751058f7704ffdb91f15d189260.svg\";","module.exports = __webpack_public_path__ + \"static/assets/3732270cfcc864cbbd939ae7213f1a5a.svg\";","module.exports = __webpack_public_path__ + \"static/assets/e7c972c634096b89b182b99441a20b1d.svg\";","module.exports = __webpack_public_path__ + \"static/assets/14120e6444ca2744dad272d8ca2a4646.svg\";","module.exports = __webpack_public_path__ + \"static/assets/148e4f4cfc7a1a253eb52c50bbb635a0.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./divider.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./divider.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./divider.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport styles from './divider.css';\n\nconst Divider = ({className}) => (\n
\n);\n\nDivider.propTypes = {\n className: PropTypes.string\n};\n\nexport default Divider;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./drag-layer.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./drag-layer.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./drag-layer.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import React from 'react';\nimport PropTypes from 'prop-types';\nimport styles from './drag-layer.css';\n\n/* eslint no-confusing-arrow: [\"error\", {\"allowParens\": true}] */\nconst DragLayer = ({dragging, img, currentOffset}) => (dragging ? (\n
\n \n \n
\n
\n) : null);\n\nDragLayer.propTypes = {\n currentOffset: PropTypes.shape({\n x: PropTypes.number.isRequired,\n y: PropTypes.number.isRequired\n }),\n dragging: PropTypes.bool.isRequired,\n img: PropTypes.string\n};\n\nexport default DragLayer;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./filter.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./filter.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./filter.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport filterIcon from './icon--filter.svg';\nimport xIcon from './icon--x.svg';\nimport styles from './filter.css';\n\nconst FilterComponent = props => {\n const {\n className,\n onChange,\n onClear,\n placeholderText,\n filterQuery,\n inputClassName\n } = props;\n return (\n 0\n })}\n >\n \n \n \n \n \n \n );\n};\n\nFilterComponent.propTypes = {\n className: PropTypes.string,\n filterQuery: PropTypes.string,\n inputClassName: PropTypes.string,\n onChange: PropTypes.func,\n onClear: PropTypes.func,\n placeholderText: PropTypes.string\n};\nFilterComponent.defaultProps = {\n placeholderText: 'Search'\n};\nexport default FilterComponent;\n","module.exports = __webpack_public_path__ + \"static/assets/a4451ef35d29c4997f7c8e837da8af44.svg\";","module.exports = __webpack_public_path__ + \"static/assets/9c49ade683c0f0d75796136ff5d1030f.svg\";","import bindAll from 'lodash.bindall';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\n/**\n * Higher Order Component to manage inputs that submit on blur and \n * @param {React.Component} Input text input that consumes onChange, onBlur, onKeyPress\n * @returns {React.Component} Buffered input that calls onSubmit on blur and \n */\nexport default function (Input) {\n class BufferedInput extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'handleChange',\n 'handleKeyPress',\n 'handleFlush'\n ]);\n this.state = {\n value: null\n };\n }\n handleKeyPress (e) {\n if (e.key === 'Enter') {\n this.handleFlush();\n e.target.blur();\n }\n }\n handleFlush () {\n const isNumeric = typeof this.props.value === 'number';\n const validatesNumeric = isNumeric ? !isNaN(this.state.value) : true;\n if (this.state.value !== null && validatesNumeric) {\n this.props.onSubmit(isNumeric ? Number(this.state.value) : this.state.value);\n }\n this.setState({value: null});\n }\n handleChange (e) {\n this.setState({value: e.target.value});\n }\n render () {\n const bufferedValue = this.state.value === null ? this.props.value : this.state.value;\n return (\n \n );\n }\n }\n\n BufferedInput.propTypes = {\n onSubmit: PropTypes.func.isRequired,\n value: PropTypes.oneOfType([PropTypes.string, PropTypes.number])\n };\n\n return BufferedInput;\n}\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./input.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./input.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./input.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\n\nimport styles from './input.css';\n\nconst Input = props => {\n const {small, ...componentProps} = props;\n return (\n \n );\n};\n\nInput.propTypes = {\n className: PropTypes.string,\n small: PropTypes.bool\n};\n\nInput.defaultProps = {\n small: false\n};\n\nexport default Input;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./label.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./label.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./label.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\n\nimport styles from './label.css';\n\nconst Label = props => (\n \n);\n\nLabel.propTypes = {\n above: PropTypes.bool,\n children: PropTypes.node,\n secondary: PropTypes.bool,\n text: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired\n};\n\nLabel.defaultProps = {\n above: false,\n secondary: false\n};\n\nexport default Label;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./green-flag.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./green-flag.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./green-flag.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport greenFlagIcon from './icon--green-flag.svg';\nimport styles from './green-flag.css';\n\nconst GreenFlagComponent = function (props) {\n const {\n active,\n className,\n onClick,\n title,\n ...componentProps\n } = props;\n return (\n \n );\n};\nGreenFlagComponent.propTypes = {\n active: PropTypes.bool,\n className: PropTypes.string,\n onClick: PropTypes.func.isRequired,\n title: PropTypes.string\n};\nGreenFlagComponent.defaultProps = {\n active: false,\n title: 'Go'\n};\nexport default GreenFlagComponent;\n","module.exports = __webpack_public_path__ + \"static/assets/2e0c4790f8f9cf28e3c346b9cef0fcb6.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./gui.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./gui.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./gui.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport omit from 'lodash.omit';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl';\nimport {connect} from 'react-redux';\nimport MediaQuery from 'react-responsive';\nimport {Tab, Tabs, TabList, TabPanel} from 'react-tabs';\nimport tabStyles from 'react-tabs/style/react-tabs.css';\nimport VM from 'scratch-vm';\nimport Renderer from 'scratch-render';\n\nimport Blocks from '../../containers/blocks.jsx';\nimport CostumeTab from '../../containers/costume-tab.jsx';\nimport TargetPane from '../../containers/target-pane.jsx';\nimport SoundTab from '../../containers/sound-tab.jsx';\nimport StageWrapper from '../../containers/stage-wrapper.jsx';\nimport Loader from '../loader/loader.jsx';\nimport Box from '../box/box.jsx';\nimport MenuBar from '../menu-bar/menu-bar.jsx';\nimport CostumeLibrary from '../../containers/costume-library.jsx';\nimport BackdropLibrary from '../../containers/backdrop-library.jsx';\nimport Watermark from '../../containers/watermark.jsx';\n\nimport Backpack from '../../containers/backpack.jsx';\nimport WebGlModal from '../../containers/webgl-modal.jsx';\nimport TipsLibrary from '../../containers/tips-library.jsx';\nimport Cards from '../../containers/cards.jsx';\nimport Alerts from '../../containers/alerts.jsx';\nimport DragLayer from '../../containers/drag-layer.jsx';\nimport ConnectionModal from '../../containers/connection-modal.jsx';\nimport TelemetryModal from '../telemetry-modal/telemetry-modal.jsx';\n\nimport layout, {STAGE_SIZE_MODES} from '../../lib/layout-constants';\nimport {resolveStageSize} from '../../lib/screen-utils';\n\nimport styles from './gui.css';\nimport addExtensionIcon from './icon--extensions.svg';\nimport codeIcon from './icon--code.svg';\nimport costumesIcon from './icon--costumes.svg';\nimport soundsIcon from './icon--sounds.svg';\n\nconst messages = defineMessages({\n addExtension: {\n id: 'gui.gui.addExtension',\n description: 'Button to add an extension in the target pane',\n defaultMessage: 'Add Extension'\n }\n});\n\n// Cache this value to only retrieve it once the first time.\n// Assume that it doesn't change for a session.\nlet isRendererSupported = null;\n\nconst GUIComponent = props => {\n const {\n accountNavOpen,\n activeTabIndex,\n alertsVisible,\n authorId,\n authorThumbnailUrl,\n authorUsername,\n basePath,\n backdropLibraryVisible,\n backpackHost,\n backpackVisible,\n blocksTabVisible,\n cardsVisible,\n canChangeLanguage,\n canCreateNew,\n canEditTitle,\n canManageFiles,\n canRemix,\n canSave,\n canCreateCopy,\n canShare,\n canUseCloud,\n children,\n connectionModalVisible,\n costumeLibraryVisible,\n costumesTabVisible,\n enableCommunity,\n intl,\n isCreating,\n isFullScreen,\n isPlayerOnly,\n isRtl,\n isShared,\n loading,\n logo,\n renderLogin,\n onClickAccountNav,\n onCloseAccountNav,\n onLogOut,\n onOpenRegistration,\n onToggleLoginOpen,\n onUpdateProjectTitle,\n onActivateCostumesTab,\n onActivateSoundsTab,\n onActivateTab,\n onClickLogo,\n onExtensionButtonClick,\n onProjectTelemetryEvent,\n onRequestCloseBackdropLibrary,\n onRequestCloseCostumeLibrary,\n onRequestCloseTelemetryModal,\n onSeeCommunity,\n onShare,\n onTelemetryModalCancel,\n onTelemetryModalOptIn,\n onTelemetryModalOptOut,\n showComingSoon,\n soundsTabVisible,\n stageSizeMode,\n targetIsStage,\n telemetryModalVisible,\n tipsLibraryVisible,\n vm,\n ...componentProps\n } = omit(props, 'dispatch');\n if (children) {\n return {children};\n }\n\n const tabClassNames = {\n tabs: styles.tabs,\n tab: classNames(tabStyles.reactTabsTab, styles.tab),\n tabList: classNames(tabStyles.reactTabsTabList, styles.tabList),\n tabPanel: classNames(tabStyles.reactTabsTabPanel, styles.tabPanel),\n tabPanelSelected: classNames(tabStyles.reactTabsTabPanelSelected, styles.isSelected),\n tabSelected: classNames(tabStyles.reactTabsTabSelected, styles.isSelected)\n };\n\n if (isRendererSupported === null) {\n isRendererSupported = Renderer.isSupported();\n }\n\n return ({isFullSize => {\n const stageSize = resolveStageSize(stageSizeMode, isFullSize);\n\n return isPlayerOnly ? (\n \n {alertsVisible ? (\n \n ) : null}\n \n ) : (\n \n {telemetryModalVisible ? (\n \n ) : null}\n {loading ? (\n \n ) : null}\n {isCreating ? (\n \n ) : null}\n {isRendererSupported ? null : (\n \n )}\n {tipsLibraryVisible ? (\n \n ) : null}\n {cardsVisible ? (\n \n ) : null}\n {alertsVisible ? (\n \n ) : null}\n {connectionModalVisible ? (\n \n ) : null}\n {costumeLibraryVisible ? (\n \n ) : null}\n {backdropLibraryVisible ? (\n \n ) : null}\n \n \n \n \n \n \n \n \n \n \n \n \n {targetIsStage ? (\n \n ) : (\n \n )}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {costumesTabVisible ? : null}\n \n \n {soundsTabVisible ? : null}\n \n \n {backpackVisible ? (\n \n ) : null}\n \n\n \n \n \n \n \n \n \n \n \n
\n );\n }});\n};\n\nGUIComponent.propTypes = {\n accountNavOpen: PropTypes.bool,\n activeTabIndex: PropTypes.number,\n authorId: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), // can be false\n authorThumbnailUrl: PropTypes.string,\n authorUsername: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), // can be false\n backdropLibraryVisible: PropTypes.bool,\n backpackHost: PropTypes.string,\n backpackVisible: PropTypes.bool,\n basePath: PropTypes.string,\n blocksTabVisible: PropTypes.bool,\n canChangeLanguage: PropTypes.bool,\n canCreateCopy: PropTypes.bool,\n canCreateNew: PropTypes.bool,\n canEditTitle: PropTypes.bool,\n canManageFiles: PropTypes.bool,\n canRemix: PropTypes.bool,\n canSave: PropTypes.bool,\n canShare: PropTypes.bool,\n canUseCloud: PropTypes.bool,\n cardsVisible: PropTypes.bool,\n children: PropTypes.node,\n costumeLibraryVisible: PropTypes.bool,\n costumesTabVisible: PropTypes.bool,\n enableCommunity: PropTypes.bool,\n intl: intlShape.isRequired,\n isCreating: PropTypes.bool,\n isFullScreen: PropTypes.bool,\n isPlayerOnly: PropTypes.bool,\n isRtl: PropTypes.bool,\n isShared: PropTypes.bool,\n loading: PropTypes.bool,\n logo: PropTypes.string,\n onActivateCostumesTab: PropTypes.func,\n onActivateSoundsTab: PropTypes.func,\n onActivateTab: PropTypes.func,\n onClickAccountNav: PropTypes.func,\n onClickLogo: PropTypes.func,\n onCloseAccountNav: PropTypes.func,\n onExtensionButtonClick: PropTypes.func,\n onLogOut: PropTypes.func,\n onOpenRegistration: PropTypes.func,\n onRequestCloseBackdropLibrary: PropTypes.func,\n onRequestCloseCostumeLibrary: PropTypes.func,\n onRequestCloseTelemetryModal: PropTypes.func,\n onSeeCommunity: PropTypes.func,\n onShare: PropTypes.func,\n onTabSelect: PropTypes.func,\n onTelemetryModalCancel: PropTypes.func,\n onTelemetryModalOptIn: PropTypes.func,\n onTelemetryModalOptOut: PropTypes.func,\n onToggleLoginOpen: PropTypes.func,\n onUpdateProjectTitle: PropTypes.func,\n renderLogin: PropTypes.func,\n showComingSoon: PropTypes.bool,\n soundsTabVisible: PropTypes.bool,\n stageSizeMode: PropTypes.oneOf(Object.keys(STAGE_SIZE_MODES)),\n targetIsStage: PropTypes.bool,\n telemetryModalVisible: PropTypes.bool,\n tipsLibraryVisible: PropTypes.bool,\n vm: PropTypes.instanceOf(VM).isRequired\n};\nGUIComponent.defaultProps = {\n backpackHost: null,\n backpackVisible: false,\n basePath: './',\n canChangeLanguage: true,\n canCreateNew: false,\n canEditTitle: false,\n canManageFiles: true,\n canRemix: false,\n canSave: false,\n canCreateCopy: false,\n canShare: false,\n canUseCloud: false,\n enableCommunity: false,\n isCreating: false,\n isShared: false,\n loading: false,\n onUpdateProjectTitle: () => {},\n showComingSoon: false,\n stageSizeMode: STAGE_SIZE_MODES.large\n};\n\nconst mapStateToProps = state => ({\n // This is the button's mode, as opposed to the actual current state\n stageSizeMode: state.scratchGui.stageSize.stageSize\n});\n\nexport default injectIntl(connect(\n mapStateToProps\n)(GUIComponent));\n","module.exports = __webpack_public_path__ + \"static/assets/257e3788c5fbfe56c151a97e97dc20d8.svg\";","module.exports = __webpack_public_path__ + \"static/assets/1dfe5425b42628b6f1df1f39e97a319f.svg\";","module.exports = __webpack_public_path__ + \"static/assets/5f4208a6b7257c456c018d57efc8a7e9.svg\";","module.exports = __webpack_public_path__ + \"static/assets/2258ea6dfe9ad15440ca55aca291698d.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./icon-button.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./icon-button.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./icon-button.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\nimport classNames from 'classnames';\nimport styles from './icon-button.css';\n\nconst IconButton = ({\n img,\n disabled,\n className,\n title,\n onClick\n}) => (\n \n \n
\n {title}\n
\n \n);\n\nIconButton.propTypes = {\n className: PropTypes.string,\n disabled: PropTypes.bool,\n img: PropTypes.string,\n onClick: PropTypes.func.isRequired,\n title: PropTypes.node.isRequired\n};\n\nexport default IconButton;\n","module.exports = __webpack_public_path__ + \"static/assets/1319094a51748798730f01d1dc0972ac.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./language-selector.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./language-selector.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./language-selector.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import PropTypes from 'prop-types';\nimport React from 'react';\n\nimport locales from 'scratch-l10n';\nimport styles from './language-selector.css';\n\n// supported languages to exclude from the menu, but allow as a URL option\nconst ignore = [];\n\nconst LanguageSelector = ({currentLocale, label, onChange}) => (\n \n {\n Object.keys(locales)\n .filter(l => !ignore.includes(l))\n .map(locale => (\n \n {locales[locale].name}\n \n ))\n }\n \n);\n\nLanguageSelector.propTypes = {\n currentLocale: PropTypes.string,\n label: PropTypes.string,\n onChange: PropTypes.func\n};\n\nexport default LanguageSelector;\n","module.exports = __webpack_public_path__ + \"static/assets/dfe35552790fb5ff38c78a43f5e62f30.svg\";","module.exports = __webpack_public_path__ + \"static/assets/1bb0adb555e07593962e9fc28ec7566d.svg\";","module.exports = __webpack_public_path__ + \"static/assets/582b9f12ce60392a8ef736c5dfabb4ce.svg\";","module.exports = __webpack_public_path__ + \"static/assets/7bd7487b704797cb5ab3cb441486ea70.svg\";","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./library-item.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./library-item.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./library-item.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import {FormattedMessage} from 'react-intl';\nimport PropTypes from 'prop-types';\nimport React from 'react';\n\nimport Box from '../box/box.jsx';\nimport PlayButton from '../../containers/play-button.jsx';\nimport styles from './library-item.css';\nimport classNames from 'classnames';\n\nimport bluetoothIconURL from './bluetooth.svg';\nimport internetConnectionIconURL from './internet-connection.svg';\n\n/* eslint-disable react/prefer-stateless-function */\nclass LibraryItemComponent extends React.PureComponent {\n render () {\n return this.props.featured ? (\n \n
\n {this.props.disabled ? (\n
\n \n
\n ) : null}\n \n
\n {this.props.insetIconURL ? (\n
\n \n
\n ) : null}\n \n {this.props.name}\n
\n {this.props.description}\n \n {this.props.bluetoothRequired || this.props.internetConnectionRequired || this.props.collaborator ? (\n
\n
\n {this.props.bluetoothRequired || this.props.internetConnectionRequired ? (\n
\n
\n \n
\n \n {this.props.bluetoothRequired ? (\n \n ) : null}\n {this.props.internetConnectionRequired ? (\n \n ) : null}\n
\n
\n ) : null}\n
\n
\n {this.props.collaborator ? (\n
\n
\n \n
\n \n {this.props.collaborator}\n
\n
\n ) : null}\n \n \n ) : null}\n \n ) : (\n \n {/* Layers of wrapping is to prevent layout thrashing on animation */}\n \n \n \n \n \n {this.props.name}\n {this.props.showPlayButton ? (\n \n ) : null}\n \n );\n }\n}\n/* eslint-enable react/prefer-stateless-function */\n\n\nLibraryItemComponent.propTypes = {\n bluetoothRequired: PropTypes.bool,\n collaborator: PropTypes.string,\n description: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.node\n ]),\n disabled: PropTypes.bool,\n extensionId: PropTypes.string,\n featured: PropTypes.bool,\n hidden: PropTypes.bool,\n iconURL: PropTypes.string,\n insetIconURL: PropTypes.string,\n internetConnectionRequired: PropTypes.bool,\n isPlaying: PropTypes.bool,\n name: PropTypes.oneOfType([\n PropTypes.string,\n PropTypes.node\n ]),\n onBlur: PropTypes.func.isRequired,\n onClick: PropTypes.func.isRequired,\n onFocus: PropTypes.func.isRequired,\n onKeyPress: PropTypes.func.isRequired,\n onMouseEnter: PropTypes.func.isRequired,\n onMouseLeave: PropTypes.func.isRequired,\n onPlay: PropTypes.func.isRequired,\n onStop: PropTypes.func.isRequired,\n showPlayButton: PropTypes.bool\n};\n\nLibraryItemComponent.defaultProps = {\n disabled: false,\n showPlayButton: false\n};\n\nexport default LibraryItemComponent;\n","\nvar content = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./library.css\");\n\nif(typeof content === 'string') content = [[module.id, content, '']];\n\nvar transform;\nvar insertInto;\n\n\n\nvar options = {\"hmr\":true}\n\noptions.transform = transform\noptions.insertInto = undefined;\n\nvar update = require(\"!../../../node_modules/style-loader/lib/addStyles.js\")(content, options);\n\nif(content.locals) module.exports = content.locals;\n\nif(module.hot) {\n\tmodule.hot.accept(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./library.css\", function() {\n\t\tvar newContent = require(\"!!../../../node_modules/css-loader/index.js??ref--5-1!../../../node_modules/postcss-loader/src/index.js??postcss!./library.css\");\n\n\t\tif(typeof newContent === 'string') newContent = [[module.id, newContent, '']];\n\n\t\tvar locals = (function(a, b) {\n\t\t\tvar key, idx = 0;\n\n\t\t\tfor(key in a) {\n\t\t\t\tif(!b || a[key] !== b[key]) return false;\n\t\t\t\tidx++;\n\t\t\t}\n\n\t\t\tfor(key in b) idx--;\n\n\t\t\treturn idx === 0;\n\t\t}(content.locals, newContent.locals));\n\n\t\tif(!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.');\n\n\t\tupdate(newContent);\n\t});\n\n\tmodule.hot.dispose(function() { update(); });\n}","import classNames from 'classnames';\nimport bindAll from 'lodash.bindall';\nimport PropTypes from 'prop-types';\nimport React from 'react';\nimport {defineMessages, injectIntl, intlShape} from 'react-intl';\n\nimport LibraryItem from '../../containers/library-item.jsx';\nimport Modal from '../../containers/modal.jsx';\nimport Divider from '../divider/divider.jsx';\nimport Filter from '../filter/filter.jsx';\nimport TagButton from '../../containers/tag-button.jsx';\nimport Spinner from '../spinner/spinner.jsx';\n\nimport styles from './library.css';\n\nconst messages = defineMessages({\n filterPlaceholder: {\n id: 'gui.library.filterPlaceholder',\n defaultMessage: 'Search',\n description: 'Placeholder text for library search field'\n },\n allTag: {\n id: 'gui.library.allTag',\n defaultMessage: 'All',\n description: 'Label for library tag to revert to all items after filtering by tag.'\n }\n});\n\nconst ALL_TAG = {tag: 'all', intlLabel: messages.allTag};\nconst tagListPrefix = [ALL_TAG];\n\nclass LibraryComponent extends React.Component {\n constructor (props) {\n super(props);\n bindAll(this, [\n 'handleClose',\n 'handleFilterChange',\n 'handleFilterClear',\n 'handleMouseEnter',\n 'handleMouseLeave',\n 'handlePlayingEnd',\n 'handleSelect',\n 'handleTagClick',\n 'setFilteredDataRef'\n ]);\n this.state = {\n playingItem: null,\n filterQuery: '',\n selectedTag: ALL_TAG.tag,\n loaded: false\n };\n }\n componentDidMount () {\n // Allow the spinner to display before loading the content\n setTimeout(() => {\n this.setState({loaded: true});\n });\n if (this.props.setStopHandler) this.props.setStopHandler(this.handlePlayingEnd);\n }\n componentDidUpdate (prevProps, prevState) {\n if (prevState.filterQuery !== this.state.filterQuery ||\n prevState.selectedTag !== this.state.selectedTag) {\n this.scrollToTop();\n }\n }\n handleSelect (id) {\n this.handleClose();\n this.props.onItemSelected(this.getFilteredData()[id]);\n }\n handleClose () {\n this.props.onRequestClose();\n }\n handleTagClick (tag) {\n if (this.state.playingItem === null) {\n this.setState({\n filterQuery: '',\n selectedTag: tag.toLowerCase()\n });\n } else {\n this.props.onItemMouseLeave(this.getFilteredData()[[this.state.playingItem]]);\n this.setState({\n filterQuery: '',\n playingItem: null,\n selectedTag: tag.toLowerCase()\n });\n }\n }\n handleMouseEnter (id) {\n // don't restart if mouse over already playing item\n if (this.props.onItemMouseEnter && this.state.playingItem !== id) {\n this.props.onItemMouseEnter(this.getFilteredData()[id]);\n this.setState({\n playingItem: id\n });\n }\n }\n handleMouseLeave (id) {\n if (this.props.onItemMouseLeave) {\n this.props.onItemMouseLeave(this.getFilteredData()[id]);\n this.setState({\n playingItem: null\n });\n }\n }\n handlePlayingEnd () {\n if (this.state.playingItem !== null) {\n this.setState({\n playingItem: null\n });\n }\n }\n handleFilterChange (event) {\n if (this.state.playingItem === null) {\n this.setState({\n filterQuery: event.target.value,\n selectedTag: ALL_TAG.tag\n });\n } else {\n this.props.onItemMouseLeave(this.getFilteredData()[[this.state.playingItem]]);\n this.setState({\n filterQuery: event.target.value,\n playingItem: null,\n selectedTag: ALL_TAG.tag\n });\n }\n }\n handleFilterClear () {\n this.setState({filterQuery: ''});\n }\n getFilteredData () {\n if (this.state.selectedTag === 'all') {\n if (!this.state.filterQuery) return this.props.data;\n return this.props.data.filter(dataItem => (\n (dataItem.tags || [])\n // Second argument to map sets `this`\n .map(String.prototype.toLowerCase.call, String.prototype.toLowerCase)\n .concat(dataItem.name ?\n (typeof dataItem.name === 'string' ?\n // Use the name if it is a string, else use formatMessage to get the translated name\n dataItem.name : this.props.intl.formatMessage(dataItem.name.props)\n ).toLowerCase() :\n null)\n .join('\\n') // unlikely to partially match newlines\n .indexOf(this.state.filterQuery.toLowerCase()) !== -1\n ));\n }\n return this.props.data.filter(dataItem => (\n dataItem.tags &&\n dataItem.tags\n .map(String.prototype.toLowerCase.call, String.prototype.toLowerCase)\n .indexOf(this.state.selectedTag) !== -1\n ));\n }\n scrollToTop () {\n this.filteredDataRef.scrollTop = 0;\n }\n setFilteredDataRef (ref) {\n this.filteredDataRef = ref;\n }\n render () {\n return (\n \n {(this.props.filterable || this.props.tags) && (\n
\n {this.props.filterable && (\n \n )}\n {this.props.filterable && this.props.tags && (\n \n )}\n {this.props.tags &&\n
\n {tagListPrefix.concat(this.props.tags).map((tagProps, id) => (\n \n ))}\n
\n }\n
\n )}\n \n {this.state.loaded ? this.getFilteredData().map((dataItem, index) => (\n