{"version":3,"sources":["jsdelivr-header.js","/npm/ipfs-webrtc-peer@9.7.2/index.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;ACLA,IAAI,MAAQ,QAAQ,QAAR,CAAiB,eACzB,cAAgB,QAAQ,mBACxB,YAAc,QAAQ,eACtB,OAAS,QAAQ,mBACjB,eAAiB,QAAQ,mBACzB,QAAU,QAAQ,YAElB,oBAAsB,MACtB,oBAAsB,IACtB,wBAA0B,IAG9B,SAAS,cAAe,GACtB,OAAO,EAAI,QAAQ,6BAA8B,GACnD,CAEA,SAAS,KAAM,GACb,QAAQ,KAAK,EACf,CAOA,MAAM,aAAa,OAAO,OACxB,WAAA,CAAa,GAwCX,GAnCA,MAJA,EAAO,OAAO,OAAO,CACnB,eAAe,GACd,IAIH,KAAK,IAAM,YAAY,GAAG,SAAS,OAAO,MAAM,EAAG,GACnD,KAAK,OAAO,cAAe,GAE3B,KAAK,YAAc,EAAK,UACpB,EAAK,aAAe,YAAY,IAAI,SAAS,OAC7C,KAEJ,KAAK,UAAY,EAAK,YAAa,EACnC,KAAK,cAAgB,EAAK,eAAiB,KAAK,cAChD,KAAK,WAAa,KAAK,cAAc,WACrC,KAAK,OAAS,OAAO,OAAO,CAAC,EAAG,KAAK,OAAQ,EAAK,QAClD,KAAK,aAAe,EAAK,cAAgB,CAAC,EAC1C,KAAK,cAAgB,EAAK,eAAiB,CAAC,EAC5C,KAAK,aAAe,EAAK,cAAgB,CAAC,GAAO,GACjD,KAAK,QAAU,EAAK,UAAY,EAAK,OAAS,CAAC,EAAK,QAAU,IAC9D,KAAK,aAA2B,IAAjB,EAAK,SAAwB,EAAK,QACjD,KAAK,sBAA6C,IAA1B,EAAK,kBAAiC,EAAK,iBACnE,KAAK,mBAAqB,EAAK,oBAAsB,oBAErD,KAAK,WAAY,EACjB,KAAK,YAAa,EAElB,KAAK,mBAAgB,EACrB,KAAK,kBAAe,EACpB,KAAK,gBAAa,EAClB,KAAK,kBAAe,EACpB,KAAK,iBAAc,EACnB,KAAK,eAAY,EAEjB,KAAK,MAAS,EAAK,MAA6B,iBAAd,EAAK,KACnC,EAAK,KACL,iBAEC,KAAK,MACR,KAAsB,oBAAX,OACH,QAAQ,IAAI,MAAM,qEAAsE,sBAExF,QAAQ,IAAI,MAAM,8CAA+C,sBAI3E,KAAK,UAAW,EAChB,KAAK,eAAgB,EACrB,KAAK,cAAe,EACpB,KAAK,kBAAoB,KACzB,KAAK,SAAW,KAChB,KAAK,mBAAqB,GAE1B,KAAK,gBAAiB,KAAK,aAAsB,KAAK,UACtD,KAAK,qBAAsB,EAC3B,KAAK,oBAAqB,EAC1B,KAAK,uBAAyB,GAC9B,KAAK,WAAa,IAAI,IACtB,KAAK,cAAe,EACpB,KAAK,iBAAmB,KAExB,KAAK,cAAgB,GACrB,KAAK,eAAiB,GAEtB,KAAK,OAAS,KACd,KAAK,IAAM,KACX,KAAK,UAAY,KAEjB,IACE,KAAK,IAAM,IAAK,KAAK,MAAuB,kBAAE,KAAK,OACrD,CAAE,MAAO,GAEP,YADA,gBAAe,IAAM,KAAK,QAAQ,QAAQ,EAAK,wBAEjD,CAIA,KAAK,qBAA6D,iBAA/B,KAAK,IAAI,kBAE5C,KAAK,IAAI,2BAA6B,KACpC,KAAK,mBAAkB,EAEzB,KAAK,IAAI,0BAA4B,KACnC,KAAK,mBAAkB,EAEzB,KAAK,IAAI,wBAA0B,KACjC,KAAK,0BAAyB,EAEhC,KAAK,IAAI,uBAAyB,KAChC,KAAK,yBAAwB,EAE/B,KAAK,IAAI,eAAiB,IACxB,KAAK,gBAAgB,EAAK,EASxB,KAAK,WAAa,KAAK,WACzB,KAAK,WAAW,CACd,QAAS,KAAK,IAAI,kBAAkB,KAAK,YAAa,KAAK,iBAG7D,KAAK,IAAI,cAAgB,IACvB,KAAK,WAAW,EAAK,EAIrB,KAAK,SACP,KAAK,QAAQ,SAAQ,IACnB,KAAK,UAAU,EAAM,IAGzB,KAAK,IAAI,QAAU,IACjB,KAAK,SAAS,EAAK,EAGjB,KAAK,WACP,KAAK,oBAGP,KAAK,eAAiB,KACpB,KAAK,WAAU,EAEjB,KAAK,KAAK,SAAU,KAAK,eAC3B,CAEA,cAAI,GACF,OAAQ,KAAK,UAAY,KAAK,SAAS,gBAAmB,CAC5D,CAIA,aAAI,GACF,OAAQ,KAAK,YAA2C,SAA7B,KAAK,SAAS,UAC3C,CAEA,OAAA,GACE,MAAO,CAAE,KAAM,KAAK,UAAW,OAAQ,KAAK,YAAa,QAAS,KAAK,aACzE,CAEA,MAAA,CAAQ,GACN,GAAI,KAAK,UAAW,MAAM,QAAQ,IAAI,MAAM,yCAA0C,iBACtF,GAAoB,iBAAT,EACT,IACE,EAAO,KAAK,MAAM,EACpB,CAAE,MAAO,GACP,EAAO,CAAC,CACV,CAEF,KAAK,OAAO,YAER,EAAK,aAAe,KAAK,YAC3B,KAAK,OAAO,8BACZ,KAAK,qBAEH,EAAK,oBAAsB,KAAK,YAClC,KAAK,OAAO,+BACZ,KAAK,eAAe,EAAK,mBAAmB,KAAM,EAAK,mBAAmB,OAExE,EAAK,YACH,KAAK,IAAI,mBAAqB,KAAK,IAAI,kBAAkB,KAC3D,KAAK,iBAAiB,EAAK,WAE3B,KAAK,mBAAmB,KAAK,EAAK,YAGlC,EAAK,KACP,KAAK,IAAI,qBAAqB,IAAK,KAAK,MAA2B,sBAAE,IAClE,MAAK,KACA,KAAK,YAET,KAAK,mBAAmB,SAAQ,IAC9B,KAAK,iBAAiB,EAAS,IAEjC,KAAK,mBAAqB,GAEc,UAApC,KAAK,IAAI,kBAAkB,MAAkB,KAAK,gBAAc,IAErE,OAAM,IACL,KAAK,QAAQ,QAAQ,EAAK,8BAA6B,IAGxD,EAAK,KAAQ,EAAK,WAAc,EAAK,aAAgB,EAAK,oBAC7D,KAAK,QAAQ,QAAQ,IAAI,MAAM,4CAA6C,iBAEhF,CAEA,gBAAA,CAAkB,GAChB,IAAI,EAAkB,IAAI,KAAK,MAAM,gBAAgB,GACrD,KAAK,IAAI,gBAAgB,GACtB,OAAM,KACA,EAAgB,SAAW,EAAgB,QAAQ,SAAS,UAC/D,KAAK,uCAEL,KAAK,QAAQ,QAAQ,EAAK,yBAC5B,GAEN,CAMA,IAAA,CAAM,GACJ,KAAK,SAAS,KAAK,EACrB,CAOA,cAAA,CAAgB,EAAM,GAGpB,GAFA,KAAK,OAAO,oBAER,KAAK,UACP,IACE,KAAK,IAAI,eAAe,EAAM,GAC9B,KAAK,mBACP,CAAE,MAAO,GACP,KAAK,QAAQ,QAAQ,EAAK,uBAC5B,MAEA,KAAK,KAAK,SAAU,CAClB,mBAAoB,CAAE,OAAM,SAGlC,CAMA,SAAA,CAAW,GACT,KAAK,OAAO,eAEZ,EAAO,YAAY,SAAQ,IACzB,KAAK,SAAS,EAAO,EAAM,GAE/B,CAOA,QAAA,CAAU,EAAO,GACf,KAAK,OAAO,cAEZ,IAAI,EAAS,KAAK,WAAW,IAAI,IAAU,IAAI,IAC3C,EAAS,EAAO,IAAI,GACxB,GAAK,EAKE,MAAI,EAAO,QACV,QAAQ,IAAI,MAAM,qFAAsF,sBAExG,QAAQ,IAAI,MAAM,gDAAiD,4BAPzE,EAAS,KAAK,IAAI,SAAS,EAAO,GAClC,EAAO,IAAI,EAAQ,GACnB,KAAK,WAAW,IAAI,EAAO,GAC3B,KAAK,mBAMT,CAQA,YAAA,CAAc,EAAU,EAAU,GAChC,KAAK,OAAO,kBAEZ,IAAI,EAAS,KAAK,WAAW,IAAI,GAC7B,EAAS,EAAS,EAAO,IAAI,GAAU,KAC3C,IAAK,EACH,MAAM,QAAQ,IAAI,MAAM,8CAA+C,uBAErE,GAAU,KAAK,WAAW,IAAI,EAAU,GAEjB,MAAvB,EAAO,aACT,EAAO,aAAa,GAEpB,KAAK,QAAQ,QAAQ,IAAI,MAAM,iDAAkD,gCAErF,CAOA,WAAA,CAAa,EAAO,GAClB,KAAK,OAAO,kBAEZ,IAAI,EAAS,KAAK,WAAW,IAAI,GAC7B,EAAS,EAAS,EAAO,IAAI,GAAU,KAC3C,IAAK,EACH,MAAM,QAAQ,IAAI,MAAM,6CAA8C,uBAExE,IACE,EAAO,SAAU,EACjB,KAAK,IAAI,YAAY,EACvB,CAAE,MAAO,GACU,wBAAb,EAAI,KACN,KAAK,uBAAuB,KAAK,GAEjC,KAAK,QAAQ,QAAQ,EAAK,oBAE9B,CACA,KAAK,mBACP,CAMA,YAAA,CAAc,GACZ,KAAK,OAAO,mBAEZ,EAAO,YAAY,SAAQ,IACzB,KAAK,YAAY,EAAO,EAAM,GAElC,CAEA,iBAAA,GACE,KAAK,OAAO,qBACR,KAAK,sBACT,KAAK,qBAAsB,EAC3B,gBAAe,KACb,KAAK,qBAAsB,EAC3B,KAAK,OAAO,gCACZ,KAAK,WAAU,IAEnB,CAEA,SAAA,GACM,KAAK,UACH,KAAK,gBACP,KAAK,oBAAqB,EAC1B,KAAK,OAAO,mCAEZ,KAAK,OAAO,qBACZ,YAAW,KACT,KAAK,cAAa,GACjB,IAGD,KAAK,gBACP,KAAK,oBAAqB,EAC1B,KAAK,OAAO,mCAEZ,KAAK,OAAO,yCACZ,KAAK,KAAK,SAAU,CAClB,aAAa,KAInB,KAAK,gBAAiB,CACxB,CAKA,OAAA,CAAS,GACP,KAAK,SAAS,GAAK,QACrB,CAEA,QAAA,CAAU,EAAK,GACb,IAAI,KAAK,UAAT,CA4BA,GA1BA,KAAK,OAAO,sBAAuB,IAAQ,EAAI,SAAW,IAE1D,KAAK,SAAW,KAAK,UAAW,EAE3B,KAAK,eAAe,OAAO,KAAK,KAAK,MACrC,KAAK,eAAe,UAAU,KAAK,MAExC,KAAK,WAAY,EACjB,KAAK,YAAa,EAClB,KAAK,UAAW,EAChB,KAAK,eAAgB,EACrB,KAAK,cAAgB,KACrB,KAAK,eAAiB,KACtB,KAAK,WAAa,KAElB,cAAc,KAAK,kBACnB,KAAK,iBAAmB,KAExB,cAAc,KAAK,WACnB,KAAK,UAAY,KACjB,KAAK,OAAS,KACd,KAAK,IAAM,KAEP,KAAK,gBAAgB,KAAK,eAAe,SAAU,KAAK,gBAC5D,KAAK,eAAiB,KAElB,KAAK,SAAU,CACjB,IACE,KAAK,SAAS,OAChB,CAAE,MAAO,GAAM,CAEf,KAAK,SAAS,UAAY,KAC1B,KAAK,SAAS,OAAS,KACvB,KAAK,SAAS,QAAU,KACxB,KAAK,SAAS,QAAU,IAC1B,CACA,GAAI,KAAK,IAAK,CACZ,IACE,KAAK,IAAI,OACX,CAAE,MAAO,GAAM,CAEf,KAAK,IAAI,2BAA6B,KACtC,KAAK,IAAI,0BAA4B,KACrC,KAAK,IAAI,uBAAyB,KAClC,KAAK,IAAI,eAAiB,KAC1B,KAAK,IAAI,QAAU,KACnB,KAAK,IAAI,cAAgB,IAC3B,CACA,KAAK,IAAM,KACX,KAAK,SAAW,KAEZ,GAAK,KAAK,KAAK,QAAS,GAC5B,KAAK,KAAK,SACV,GAvDoB,CAwDtB,CAEA,UAAA,CAAY,GACV,IAAK,EAAM,QAIT,OAAO,KAAK,QAAQ,QAAQ,IAAI,MAAM,oDAAqD,qBAG7F,KAAK,SAAW,EAAM,QACtB,KAAK,SAAS,WAAa,cAE6B,iBAA7C,KAAK,SAAS,6BACvB,KAAK,SAAS,2BAA6B,qBAG7C,KAAK,YAAc,KAAK,SAAS,MAEjC,KAAK,SAAS,UAAY,IACxB,KAAK,kBAAkB,EAAK,EAE9B,KAAK,SAAS,oBAAsB,KAClC,KAAK,6BAA4B,EAEnC,KAAK,SAAS,OAAS,KACrB,KAAK,gBAAe,EAEtB,KAAK,SAAS,QAAU,KACtB,KAAK,iBAAgB,EAEvB,KAAK,SAAS,QAAU,IACtB,KAAK,QAAQ,QAAQ,EAAK,oBAAmB,EAK/C,IAAI,GAAY,EAChB,KAAK,iBAAmB,aAAY,KAC9B,KAAK,UAAyC,YAA7B,KAAK,SAAS,YAC7B,GAAW,KAAK,kBACpB,GAAY,GAEZ,GAAY,CACd,GACC,wBACL,CAEA,KAAA,GAAU,CAEV,MAAA,CAAQ,EAAO,EAAU,GACvB,GAAI,KAAK,UAAW,OAAO,EAAG,QAAQ,IAAI,MAAM,wCAAyC,qBAEzF,GAAI,KAAK,WAAY,CACnB,IACE,KAAK,KAAK,EACZ,CAAE,MAAO,GACP,OAAO,KAAK,QAAQ,QAAQ,EAAK,oBACnC,CACI,KAAK,SAAS,eAAiB,qBACjC,KAAK,OAAO,wCAAyC,KAAK,SAAS,gBACnE,KAAK,IAAM,GAEX,EAAG,KAEP,MACE,KAAK,OAAO,wBACZ,KAAK,OAAS,EACd,KAAK,IAAM,CAEf,CAIA,SAAA,GACE,GAAI,KAAK,UAAW,OAIpB,MAAM,EAAc,KAClB,YAAW,IAAM,KAAK,WAAW,IAAI,EAGnC,KAAK,WACP,IAEA,KAAK,KAAK,UAAW,EAEzB,CAEA,wBAAA,GACM,KAAK,WACL,KAAK,oBACT,KAAK,OAAO,+BACZ,KAAK,kBAAoB,YAAW,KAC7B,KAAK,eACR,KAAK,cAAe,EACpB,KAAK,OAAO,iCACZ,KAAK,KAAK,cACV,KAAK,KAAK,gBACZ,GACC,KAAK,oBACV,CAEA,YAAA,GACM,KAAK,WAET,KAAK,IAAI,YAAY,KAAK,cACvB,MAAK,IACJ,GAAI,KAAK,UAAW,OACf,KAAK,SAAY,KAAK,mBAAkB,EAAM,IAAM,cAAc,EAAM,MAC7E,EAAM,IAAM,KAAK,aAAa,EAAM,KAEpC,MAAM,EAAY,KAChB,IAAI,KAAK,UAAT,CACA,IAAI,EAAS,KAAK,IAAI,kBAAoB,EAC1C,KAAK,OAAO,UACZ,KAAK,KAAK,SAAU,CAClB,KAAM,EAAO,KACb,IAAK,EAAO,KALM,CAMnB,EAcH,KAAK,IAAI,oBAAoB,GAC1B,MAZe,KAChB,KAAK,OAAO,uBACR,KAAK,YACL,KAAK,SAAW,KAAK,aAAc,IAClC,KAAK,KAAK,eAAgB,GAAS,IASvC,OANa,IACd,KAAK,QAAQ,QAAQ,EAAK,6BAA4B,GAKxC,IAEjB,OAAM,IACL,KAAK,QAAQ,QAAQ,EAAK,oBAAmB,GAEnD,CAEA,2BAAA,GACM,KAAK,IAAI,iBACX,KAAK,IAAI,kBAAkB,SAAQ,IAC5B,EAAY,MAAO,EAAY,OAAO,OAAU,EAAY,YAC/D,EAAY,WAAY,EACxB,KAAK,eAAe,EAAY,OAAO,MAAM,MAC/C,GAGN,CAEA,aAAA,GACM,KAAK,WAET,KAAK,IAAI,aAAa,KAAK,eACxB,MAAK,IACJ,GAAI,KAAK,UAAW,OACf,KAAK,SAAY,KAAK,mBAAkB,EAAO,IAAM,cAAc,EAAO,MAC/E,EAAO,IAAM,KAAK,aAAa,EAAO,KAEtC,MAAM,EAAa,KACjB,IAAI,KAAK,UAAT,CACA,IAAI,EAAS,KAAK,IAAI,kBAAoB,EAC1C,KAAK,OAAO,UACZ,KAAK,KAAK,SAAU,CAClB,KAAM,EAAO,KACb,IAAK,EAAO,MAET,KAAK,WAAW,KAAK,6BAPN,CAOkC,EAaxD,KAAK,IAAI,oBAAoB,GAC1B,MAXe,KACZ,KAAK,YACL,KAAK,SAAW,KAAK,aAAc,IAClC,KAAK,KAAK,eAAgB,GAAU,IASxC,OANa,IACd,KAAK,QAAQ,QAAQ,EAAK,6BAA4B,GAKxC,IAEjB,OAAM,IACL,KAAK,QAAQ,QAAQ,EAAK,qBAAoB,GAEpD,CAEA,wBAAA,GACM,KAAK,WACwB,WAA7B,KAAK,IAAI,iBACX,KAAK,QAAQ,QAAQ,IAAI,MAAM,sBAAuB,0BAE1D,CAEA,iBAAA,GACE,IAAI,KAAK,UAAT,CACA,IAAI,EAAqB,KAAK,IAAI,mBAC9B,EAAoB,KAAK,IAAI,kBAEjC,KAAK,OACH,kDACA,EACA,GAEF,KAAK,KAAK,iBAAkB,EAAoB,GAErB,cAAvB,GAA6D,cAAvB,IACxC,KAAK,UAAW,EAChB,KAAK,eAEoB,WAAvB,GACF,KAAK,QAAQ,QAAQ,IAAI,MAAM,0BAA2B,+BAEjC,WAAvB,GACF,KAAK,QAAQ,QAAQ,IAAI,MAAM,0BAA2B,6BAnBxC,CAqBtB,CAEA,QAAA,CAAU,GAER,MAAM,EAAgB,IACkC,mBAAlD,OAAO,UAAU,SAAS,KAAK,EAAO,SACxC,EAAO,OAAO,SAAQ,IACpB,OAAO,OAAO,EAAQ,EAAK,IAGxB,GAIwB,IAA7B,KAAK,IAAI,SAAS,QAAgB,KAAK,qBACzC,KAAK,IAAI,WACN,MAAK,IACJ,IAAI,EAAU,GACd,EAAI,SAAQ,IACV,EAAQ,KAAK,EAAc,GAAO,IAEpC,EAAG,KAAM,EAAO,IACf,GAAO,EAAG,KAGN,KAAK,IAAI,SAAS,OAAS,EACpC,KAAK,IAAI,UAAS,IAEhB,IAAI,KAAK,UAAT,CAEA,IAAI,EAAU,GACd,EAAI,SAAS,SAAQ,IACnB,IAAI,EAAS,CAAC,EACd,EAAO,QAAQ,SAAQ,IACrB,EAAO,GAAQ,EAAO,KAAK,EAAI,IAEjC,EAAO,GAAK,EAAO,GACnB,EAAO,KAAO,EAAO,KACrB,EAAO,UAAY,EAAO,UAC1B,EAAQ,KAAK,EAAc,GAAO,IAEpC,EAAG,KAAM,EAbW,CAaJ,IACf,GAAO,EAAG,KAKb,EAAG,KAAM,GAEb,CAEA,WAAA,GAEE,GADA,KAAK,OAAO,8BAA+B,KAAK,SAAU,KAAK,eAC3D,KAAK,YAAc,KAAK,cAAgB,KAAK,WAAa,KAAK,cAAe,OAElF,KAAK,aAAc,EAGnB,MAAM,EAAoB,KACpB,KAAK,WAET,KAAK,UAAS,CAAC,EAAK,KAClB,GAAI,KAAK,UAAW,OAGhB,IAAK,EAAQ,IAEjB,IAAI,EAAmB,CAAC,EACpB,EAAkB,CAAC,EACnB,EAAiB,CAAC,EAClB,GAA6B,EAEjC,EAAM,SAAQ,IAGM,oBAAd,EAAK,MAA4C,qBAAd,EAAK,OAC1C,EAAiB,EAAK,IAAM,GAEZ,mBAAd,EAAK,MAA2C,oBAAd,EAAK,OACzC,EAAgB,EAAK,IAAM,GAEX,kBAAd,EAAK,MAA0C,mBAAd,EAAK,OACxC,EAAe,EAAK,IAAM,EAC5B,IAGF,MAAM,EAA2B,IAC/B,GAA6B,EAE7B,IAAI,EAAQ,EAAgB,EAAsB,kBAE9C,IAAU,EAAM,IAAM,EAAM,UAE9B,KAAK,aAAe,EAAM,IAAM,EAAM,QACtC,KAAK,UAAY,OAAO,EAAM,OACrB,GAAS,EAAM,WAExB,KAAK,aAAe,EAAM,UAC1B,KAAK,UAAY,OAAO,EAAM,aAC6B,iBAA3C,EAAsB,mBAEtC,EAAQ,EAAsB,iBAAiB,MAAM,KACrD,KAAK,aAAe,EAAM,GAC1B,KAAK,UAAY,OAAO,EAAM,KAE5B,KAAK,eACP,KAAK,YAAc,KAAK,aAAa,SAAS,KAAO,OAAS,QAGhE,IAAI,EAAS,EAAiB,EAAsB,mBAEhD,IAAW,EAAO,IAAM,EAAO,UAEjC,KAAK,cAAgB,EAAO,IAAM,EAAO,QACzC,KAAK,WAAa,OAAO,EAAO,OACvB,GAAU,EAAO,WAE1B,KAAK,cAAgB,EAAO,UAC5B,KAAK,WAAa,OAAO,EAAO,aAC4B,iBAA5C,EAAsB,oBAEtC,EAAS,EAAsB,kBAAkB,MAAM,KACvD,KAAK,cAAgB,EAAO,GAC5B,KAAK,WAAa,OAAO,EAAO,KAE9B,KAAK,gBACP,KAAK,aAAe,KAAK,cAAc,SAAS,KAAO,OAAS,QAGlE,KAAK,OACH,qCACA,KAAK,aAAc,KAAK,UAAW,KAAK,cAAe,KAAK,WAC9D,EAoBF,GAjBA,EAAM,SAAQ,IAEM,cAAd,EAAK,MAAwB,EAAK,yBACpC,EAAyB,EAAe,EAAK,2BAK9B,sBAAd,EAAK,MAA8D,SAA9B,EAAK,uBAC3B,kBAAd,EAAK,MAA0C,mBAAd,EAAK,OAA8B,EAAK,WAE3E,EAAyB,EAC3B,IAKG,GAAgC,OAAO,KAAK,GAAgB,SAAU,OAAO,KAAK,GAAiB,OAAxG,CAQA,GAJE,KAAK,aAAc,EACnB,KAAK,YAAa,EAGhB,KAAK,OAAQ,CACf,IACE,KAAK,KAAK,KAAK,OACjB,CAAE,MAAO,GACP,OAAO,KAAK,QAAQ,QAAQ,EAAK,oBACnC,CACA,KAAK,OAAS,KACd,KAAK,OAAO,0CAEZ,IAAI,EAAK,KAAK,IACd,KAAK,IAAM,KACX,EAAG,KACL,CAIwD,iBAA7C,KAAK,SAAS,6BACvB,KAAK,UAAY,aAAY,IAAM,KAAK,eAAe,KACnD,KAAK,UAAU,OAAO,KAAK,UAAU,SAG3C,KAAK,OAAO,WACZ,KAAK,KAAK,UAxBV,MALE,WAAW,EAAmB,IA6Bb,GACpB,EAEH,GACF,CAEA,WAAA,IACO,KAAK,MAAQ,KAAK,UAAY,KAAK,SAAS,eAAiB,qBAGlE,KAAK,6BACP,CAEA,uBAAA,GACM,KAAK,YAEuB,WAA5B,KAAK,IAAI,gBAAgC,KAAK,eAChD,KAAK,gBAAiB,EAGtB,KAAK,OAAO,wBAAyB,KAAK,wBAC1C,KAAK,uBAAuB,SAAQ,IAClC,KAAK,IAAI,YAAY,GACrB,KAAK,oBAAqB,KAE5B,KAAK,uBAAyB,GAE1B,KAAK,qBACP,KAAK,OAAO,8BACZ,KAAK,oBAAqB,EAC1B,KAAK,qBAGP,KAAK,OAAO,aACZ,KAAK,KAAK,cAEZ,KAAK,cAAe,EAEpB,KAAK,OAAO,0BAA2B,KAAK,IAAI,gBAChD,KAAK,KAAK,uBAAwB,KAAK,IAAI,gBAC7C,CAEA,eAAA,CAAiB,GACX,KAAK,YACL,EAAM,WAAa,KAAK,QAC1B,KAAK,KAAK,SAAU,CAClB,UAAW,CACT,UAAW,EAAM,UAAU,UAC3B,cAAe,EAAM,UAAU,cAC/B,OAAQ,EAAM,UAAU,UAGlB,EAAM,WAAc,KAAK,eACnC,KAAK,cAAe,EACpB,KAAK,KAAK,iBAGR,EAAM,WACR,KAAK,2BAET,CAEA,iBAAA,CAAmB,GACjB,IAAI,KAAK,UAAT,CACA,IAAI,EAAO,EAAM,KACb,aAAgB,cAAa,EAAO,OAAO,KAAK,IACpD,KAAK,KAAK,EAHU,CAItB,CAEA,2BAAA,GACE,IAAI,KAAK,WAAc,KAAK,IAA5B,CACA,KAAK,OAAO,yCAA0C,KAAK,SAAS,gBACpE,IAAI,EAAK,KAAK,IACd,KAAK,IAAM,KACX,EAAG,KAJ8B,CAKnC,CAEA,cAAA,GACM,KAAK,YAAc,KAAK,YAC5B,KAAK,OAAO,mBACZ,KAAK,eAAgB,EACrB,KAAK,cACP,CAEA,eAAA,GACM,KAAK,YACT,KAAK,OAAO,oBACZ,KAAK,UACP,CAEA,QAAA,CAAU,GACJ,KAAK,WAET,EAAM,QAAQ,SAAQ,IACpB,KAAK,OAAO,YACZ,KAAK,KAAK,QAAS,EAAM,MAAO,GAEhC,KAAK,cAAc,KAAK,CACtB,MAAO,EAAM,MACb,OAAQ,IAGN,KAAK,eAAe,MAAK,GACpB,EAAa,KAAO,EAAY,OAGzC,KAAK,eAAe,KAAK,GACzB,gBAAe,KACb,KAAK,KAAK,SAAU,EAAW,IAChC,GAEL,CAEA,MAAA,GACE,IAAI,EAAO,GAAG,MAAM,KAAK,WACzB,EAAK,GAAK,IAAM,KAAK,IAAM,KAAO,EAAK,GACvC,MAAM,MAAM,KAAM,EACpB,EAGF,KAAK,iBAAmB,gBAOxB,KAAK,OAAS,CACZ,WAAY,CACV,CACE,KAAM,CACJ,+BACA,sCAIN,aAAc,gBAGhB,KAAK,cAAgB,CAAC,EAEtB,OAAO,QAAU","file":"/npm/ipfs-webrtc-peer@9.7.2/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/ipfs-webrtc-peer@9.7.2/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */\nvar debug = require('debug')('simple-peer')\nvar getBrowserRTC = require('get-browser-rtc')\nvar randombytes = require('randombytes')\nvar stream = require('readable-stream')\nvar queueMicrotask = require('queue-microtask') // TODO: remove when Node 10 is not supported\nvar errCode = require('err-code')\n\nvar MAX_BUFFERED_AMOUNT = 64 * 1024\nvar ICECOMPLETE_TIMEOUT = 5 * 1000\nvar CHANNEL_CLOSING_TIMEOUT = 5 * 1000\n\n// HACK: Filter trickle lines when trickle is disabled #354\nfunction filterTrickle (sdp) {\n  return sdp.replace(/a=ice-options:trickle\\s\\n/g, '')\n}\n\nfunction warn (message) {\n  console.warn(message)\n}\n\n/**\n * WebRTC peer connection. Same API as node core `net.Socket`, plus a few extra methods.\n * Duplex stream.\n * @param {Object} opts\n */\nclass Peer extends stream.Duplex {\n  constructor (opts) {\n    opts = Object.assign({\n      allowHalfOpen: false\n    }, opts)\n\n    super(opts)\n\n    this._id = randombytes(4).toString('hex').slice(0, 7)\n    this._debug('new peer %o', opts)\n\n    this.channelName = opts.initiator\n      ? opts.channelName || randombytes(20).toString('hex')\n      : null\n\n    this.initiator = opts.initiator || false\n    this.channelConfig = opts.channelConfig || Peer.channelConfig\n    this.negotiated = this.channelConfig.negotiated\n    this.config = Object.assign({}, Peer.config, opts.config)\n    this.offerOptions = opts.offerOptions || {}\n    this.answerOptions = opts.answerOptions || {}\n    this.sdpTransform = opts.sdpTransform || (sdp => sdp)\n    this.streams = opts.streams || (opts.stream ? [opts.stream] : []) // support old \"stream\" option\n    this.trickle = opts.trickle !== undefined ? opts.trickle : true\n    this.allowHalfTrickle = opts.allowHalfTrickle !== undefined ? opts.allowHalfTrickle : false\n    this.iceCompleteTimeout = opts.iceCompleteTimeout || ICECOMPLETE_TIMEOUT\n\n    this.destroyed = false\n    this._connected = false\n\n    this.remoteAddress = undefined\n    this.remoteFamily = undefined\n    this.remotePort = undefined\n    this.localAddress = undefined\n    this.localFamily = undefined\n    this.localPort = undefined\n\n    this._wrtc = (opts.wrtc && typeof opts.wrtc === 'object')\n      ? opts.wrtc\n      : getBrowserRTC()\n\n    if (!this._wrtc) {\n      if (typeof window === 'undefined') {\n        throw errCode(new Error('No WebRTC support: Specify `opts.wrtc` option in this environment'), 'ERR_WEBRTC_SUPPORT')\n      } else {\n        throw errCode(new Error('No WebRTC support: Not a supported browser'), 'ERR_WEBRTC_SUPPORT')\n      }\n    }\n\n    this._pcReady = false\n    this._channelReady = false\n    this._iceComplete = false // ice candidate trickle done (got null candidate)\n    this._iceCompleteTimer = null // send an offer/answer anyway after some timeout\n    this._channel = null\n    this._pendingCandidates = []\n\n    this._isNegotiating = this.negotiated ? false : !this.initiator // is this peer waiting for negotiation to complete?\n    this._batchedNegotiation = false // batch synchronous negotiations\n    this._queuedNegotiation = false // is there a queued negotiation request?\n    this._sendersAwaitingStable = []\n    this._senderMap = new Map()\n    this._firstStable = true\n    this._closingInterval = null\n\n    this._remoteTracks = []\n    this._remoteStreams = []\n\n    this._chunk = null\n    this._cb = null\n    this._interval = null\n\n    try {\n      this._pc = new (this._wrtc.RTCPeerConnection)(this.config)\n    } catch (err) {\n      queueMicrotask(() => this.destroy(errCode(err, 'ERR_PC_CONSTRUCTOR')))\n      return\n    }\n\n    // We prefer feature detection whenever possible, but sometimes that's not\n    // possible for certain implementations.\n    this._isReactNativeWebrtc = typeof this._pc._peerConnectionId === 'number'\n\n    this._pc.oniceconnectionstatechange = () => {\n      this._onIceStateChange()\n    }\n    this._pc.onicegatheringstatechange = () => {\n      this._onIceStateChange()\n    }\n    this._pc.onconnectionstatechange = () => {\n      this._onConnectionStateChange()\n    }\n    this._pc.onsignalingstatechange = () => {\n      this._onSignalingStateChange()\n    }\n    this._pc.onicecandidate = event => {\n      this._onIceCandidate(event)\n    }\n\n    // Other spec events, unused by this implementation:\n    // - onconnectionstatechange\n    // - onicecandidateerror\n    // - onfingerprintfailure\n    // - onnegotiationneeded\n\n    if (this.initiator || this.negotiated) {\n      this._setupData({\n        channel: this._pc.createDataChannel(this.channelName, this.channelConfig)\n      })\n    } else {\n      this._pc.ondatachannel = event => {\n        this._setupData(event)\n      }\n    }\n\n    if (this.streams) {\n      this.streams.forEach(stream => {\n        this.addStream(stream)\n      })\n    }\n    this._pc.ontrack = event => {\n      this._onTrack(event)\n    }\n\n    if (this.initiator) {\n      this._needsNegotiation()\n    }\n\n    this._onFinishBound = () => {\n      this._onFinish()\n    }\n    this.once('finish', this._onFinishBound)\n  }\n\n  get bufferSize () {\n    return (this._channel && this._channel.bufferedAmount) || 0\n  }\n\n  // HACK: it's possible channel.readyState is \"closing\" before peer.destroy() fires\n  // https://bugs.chromium.org/p/chromium/issues/detail?id=882743\n  get connected () {\n    return (this._connected && this._channel.readyState === 'open')\n  }\n\n  address () {\n    return { port: this.localPort, family: this.localFamily, address: this.localAddress }\n  }\n\n  signal (data) {\n    if (this.destroyed) throw errCode(new Error('cannot signal after peer is destroyed'), 'ERR_SIGNALING')\n    if (typeof data === 'string') {\n      try {\n        data = JSON.parse(data)\n      } catch (err) {\n        data = {}\n      }\n    }\n    this._debug('signal()')\n\n    if (data.renegotiate && this.initiator) {\n      this._debug('got request to renegotiate')\n      this._needsNegotiation()\n    }\n    if (data.transceiverRequest && this.initiator) {\n      this._debug('got request for transceiver')\n      this.addTransceiver(data.transceiverRequest.kind, data.transceiverRequest.init)\n    }\n    if (data.candidate) {\n      if (this._pc.remoteDescription && this._pc.remoteDescription.type) {\n        this._addIceCandidate(data.candidate)\n      } else {\n        this._pendingCandidates.push(data.candidate)\n      }\n    }\n    if (data.sdp) {\n      this._pc.setRemoteDescription(new (this._wrtc.RTCSessionDescription)(data))\n        .then(() => {\n          if (this.destroyed) return\n\n          this._pendingCandidates.forEach(candidate => {\n            this._addIceCandidate(candidate)\n          })\n          this._pendingCandidates = []\n\n          if (this._pc.remoteDescription.type === 'offer') this._createAnswer()\n        })\n        .catch(err => {\n          this.destroy(errCode(err, 'ERR_SET_REMOTE_DESCRIPTION'))\n        })\n    }\n    if (!data.sdp && !data.candidate && !data.renegotiate && !data.transceiverRequest) {\n      this.destroy(errCode(new Error('signal() called with invalid signal data'), 'ERR_SIGNALING'))\n    }\n  }\n\n  _addIceCandidate (candidate) {\n    var iceCandidateObj = new this._wrtc.RTCIceCandidate(candidate)\n    this._pc.addIceCandidate(iceCandidateObj)\n      .catch(err => {\n        if (!iceCandidateObj.address || iceCandidateObj.address.endsWith('.local')) {\n          warn('Ignoring unsupported ICE candidate.')\n        } else {\n          this.destroy(errCode(err, 'ERR_ADD_ICE_CANDIDATE'))\n        }\n      })\n  }\n\n  /**\n   * Send text/binary data to the remote peer.\n   * @param {ArrayBufferView|ArrayBuffer|Buffer|string|Blob} chunk\n   */\n  send (chunk) {\n    this._channel.send(chunk)\n  }\n\n  /**\n   * Add a Transceiver to the connection.\n   * @param {String} kind\n   * @param {Object} init\n   */\n  addTransceiver (kind, init) {\n    this._debug('addTransceiver()')\n\n    if (this.initiator) {\n      try {\n        this._pc.addTransceiver(kind, init)\n        this._needsNegotiation()\n      } catch (err) {\n        this.destroy(errCode(err, 'ERR_ADD_TRANSCEIVER'))\n      }\n    } else {\n      this.emit('signal', { // request initiator to renegotiate\n        transceiverRequest: { kind, init }\n      })\n    }\n  }\n\n  /**\n   * Add a MediaStream to the connection.\n   * @param {MediaStream} stream\n   */\n  addStream (stream) {\n    this._debug('addStream()')\n\n    stream.getTracks().forEach(track => {\n      this.addTrack(track, stream)\n    })\n  }\n\n  /**\n   * Add a MediaStreamTrack to the connection.\n   * @param {MediaStreamTrack} track\n   * @param {MediaStream} stream\n   */\n  addTrack (track, stream) {\n    this._debug('addTrack()')\n\n    var submap = this._senderMap.get(track) || new Map() // nested Maps map [track, stream] to sender\n    var sender = submap.get(stream)\n    if (!sender) {\n      sender = this._pc.addTrack(track, stream)\n      submap.set(stream, sender)\n      this._senderMap.set(track, submap)\n      this._needsNegotiation()\n    } else if (sender.removed) {\n      throw errCode(new Error('Track has been removed. You should enable/disable tracks that you want to re-add.'), 'ERR_SENDER_REMOVED')\n    } else {\n      throw errCode(new Error('Track has already been added to that stream.'), 'ERR_SENDER_ALREADY_ADDED')\n    }\n  }\n\n  /**\n   * Replace a MediaStreamTrack by another in the connection.\n   * @param {MediaStreamTrack} oldTrack\n   * @param {MediaStreamTrack} newTrack\n   * @param {MediaStream} stream\n   */\n  replaceTrack (oldTrack, newTrack, stream) {\n    this._debug('replaceTrack()')\n\n    var submap = this._senderMap.get(oldTrack)\n    var sender = submap ? submap.get(stream) : null\n    if (!sender) {\n      throw errCode(new Error('Cannot replace track that was never added.'), 'ERR_TRACK_NOT_ADDED')\n    }\n    if (newTrack) this._senderMap.set(newTrack, submap)\n\n    if (sender.replaceTrack != null) {\n      sender.replaceTrack(newTrack)\n    } else {\n      this.destroy(errCode(new Error('replaceTrack is not supported in this browser'), 'ERR_UNSUPPORTED_REPLACETRACK'))\n    }\n  }\n\n  /**\n   * Remove a MediaStreamTrack from the connection.\n   * @param {MediaStreamTrack} track\n   * @param {MediaStream} stream\n   */\n  removeTrack (track, stream) {\n    this._debug('removeSender()')\n\n    var submap = this._senderMap.get(track)\n    var sender = submap ? submap.get(stream) : null\n    if (!sender) {\n      throw errCode(new Error('Cannot remove track that was never added.'), 'ERR_TRACK_NOT_ADDED')\n    }\n    try {\n      sender.removed = true\n      this._pc.removeTrack(sender)\n    } catch (err) {\n      if (err.name === 'NS_ERROR_UNEXPECTED') {\n        this._sendersAwaitingStable.push(sender) // HACK: Firefox must wait until (signalingState === stable) https://bugzilla.mozilla.org/show_bug.cgi?id=1133874\n      } else {\n        this.destroy(errCode(err, 'ERR_REMOVE_TRACK'))\n      }\n    }\n    this._needsNegotiation()\n  }\n\n  /**\n   * Remove a MediaStream from the connection.\n   * @param {MediaStream} stream\n   */\n  removeStream (stream) {\n    this._debug('removeSenders()')\n\n    stream.getTracks().forEach(track => {\n      this.removeTrack(track, stream)\n    })\n  }\n\n  _needsNegotiation () {\n    this._debug('_needsNegotiation')\n    if (this._batchedNegotiation) return // batch synchronous renegotiations\n    this._batchedNegotiation = true\n    queueMicrotask(() => {\n      this._batchedNegotiation = false\n      this._debug('starting batched negotiation')\n      this.negotiate()\n    })\n  }\n\n  negotiate () {\n    if (this.initiator) {\n      if (this._isNegotiating) {\n        this._queuedNegotiation = true\n        this._debug('already negotiating, queueing')\n      } else {\n        this._debug('start negotiation')\n        setTimeout(() => { // HACK: Chrome crashes if we immediately call createOffer\n          this._createOffer()\n        }, 0)\n      }\n    } else {\n      if (this._isNegotiating) {\n        this._queuedNegotiation = true\n        this._debug('already negotiating, queueing')\n      } else {\n        this._debug('requesting negotiation from initiator')\n        this.emit('signal', { // request initiator to renegotiate\n          renegotiate: true\n        })\n      }\n    }\n    this._isNegotiating = true\n  }\n\n  // TODO: Delete this method once readable-stream is updated to contain a default\n  // implementation of destroy() that automatically calls _destroy()\n  // See: https://github.com/nodejs/readable-stream/issues/283\n  destroy (err) {\n    this._destroy(err, () => {})\n  }\n\n  _destroy (err, cb) {\n    if (this.destroyed) return\n\n    this._debug('destroy (error: %s)', err && (err.message || err))\n\n    this.readable = this.writable = false\n\n    if (!this._readableState.ended) this.push(null)\n    if (!this._writableState.finished) this.end()\n\n    this.destroyed = true\n    this._connected = false\n    this._pcReady = false\n    this._channelReady = false\n    this._remoteTracks = null\n    this._remoteStreams = null\n    this._senderMap = null\n\n    clearInterval(this._closingInterval)\n    this._closingInterval = null\n\n    clearInterval(this._interval)\n    this._interval = null\n    this._chunk = null\n    this._cb = null\n\n    if (this._onFinishBound) this.removeListener('finish', this._onFinishBound)\n    this._onFinishBound = null\n\n    if (this._channel) {\n      try {\n        this._channel.close()\n      } catch (err) {}\n\n      this._channel.onmessage = null\n      this._channel.onopen = null\n      this._channel.onclose = null\n      this._channel.onerror = null\n    }\n    if (this._pc) {\n      try {\n        this._pc.close()\n      } catch (err) {}\n\n      this._pc.oniceconnectionstatechange = null\n      this._pc.onicegatheringstatechange = null\n      this._pc.onsignalingstatechange = null\n      this._pc.onicecandidate = null\n      this._pc.ontrack = null\n      this._pc.ondatachannel = null\n    }\n    this._pc = null\n    this._channel = null\n\n    if (err) this.emit('error', err)\n    this.emit('close')\n    cb()\n  }\n\n  _setupData (event) {\n    if (!event.channel) {\n      // In some situations `pc.createDataChannel()` returns `undefined` (in wrtc),\n      // which is invalid behavior. Handle it gracefully.\n      // See: https://github.com/feross/simple-peer/issues/163\n      return this.destroy(errCode(new Error('Data channel event is missing `channel` property'), 'ERR_DATA_CHANNEL'))\n    }\n\n    this._channel = event.channel\n    this._channel.binaryType = 'arraybuffer'\n\n    if (typeof this._channel.bufferedAmountLowThreshold === 'number') {\n      this._channel.bufferedAmountLowThreshold = MAX_BUFFERED_AMOUNT\n    }\n\n    this.channelName = this._channel.label\n\n    this._channel.onmessage = event => {\n      this._onChannelMessage(event)\n    }\n    this._channel.onbufferedamountlow = () => {\n      this._onChannelBufferedAmountLow()\n    }\n    this._channel.onopen = () => {\n      this._onChannelOpen()\n    }\n    this._channel.onclose = () => {\n      this._onChannelClose()\n    }\n    this._channel.onerror = err => {\n      this.destroy(errCode(err, 'ERR_DATA_CHANNEL'))\n    }\n\n    // HACK: Chrome will sometimes get stuck in readyState \"closing\", let's check for this condition\n    // https://bugs.chromium.org/p/chromium/issues/detail?id=882743\n    var isClosing = false\n    this._closingInterval = setInterval(() => { // No \"onclosing\" event\n      if (this._channel && this._channel.readyState === 'closing') {\n        if (isClosing) this._onChannelClose() // closing timed out: equivalent to onclose firing\n        isClosing = true\n      } else {\n        isClosing = false\n      }\n    }, CHANNEL_CLOSING_TIMEOUT)\n  }\n\n  _read () {}\n\n  _write (chunk, encoding, cb) {\n    if (this.destroyed) return cb(errCode(new Error('cannot write after peer is destroyed'), 'ERR_DATA_CHANNEL'))\n\n    if (this._connected) {\n      try {\n        this.send(chunk)\n      } catch (err) {\n        return this.destroy(errCode(err, 'ERR_DATA_CHANNEL'))\n      }\n      if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {\n        this._debug('start backpressure: bufferedAmount %d', this._channel.bufferedAmount)\n        this._cb = cb\n      } else {\n        cb(null)\n      }\n    } else {\n      this._debug('write before connect')\n      this._chunk = chunk\n      this._cb = cb\n    }\n  }\n\n  // When stream finishes writing, close socket. Half open connections are not\n  // supported.\n  _onFinish () {\n    if (this.destroyed) return\n\n    // Wait a bit before destroying so the socket flushes.\n    // TODO: is there a more reliable way to accomplish this?\n    const destroySoon = () => {\n      setTimeout(() => this.destroy(), 1000)\n    }\n\n    if (this._connected) {\n      destroySoon()\n    } else {\n      this.once('connect', destroySoon)\n    }\n  }\n\n  _startIceCompleteTimeout () {\n    if (this.destroyed) return\n    if (this._iceCompleteTimer) return\n    this._debug('started iceComplete timeout')\n    this._iceCompleteTimer = setTimeout(() => {\n      if (!this._iceComplete) {\n        this._iceComplete = true\n        this._debug('iceComplete timeout completed')\n        this.emit('iceTimeout')\n        this.emit('_iceComplete')\n      }\n    }, this.iceCompleteTimeout)\n  }\n\n  _createOffer () {\n    if (this.destroyed) return\n\n    this._pc.createOffer(this.offerOptions)\n      .then(offer => {\n        if (this.destroyed) return\n        if (!this.trickle && !this.allowHalfTrickle) offer.sdp = filterTrickle(offer.sdp)\n        offer.sdp = this.sdpTransform(offer.sdp)\n\n        const sendOffer = () => {\n          if (this.destroyed) return\n          var signal = this._pc.localDescription || offer\n          this._debug('signal')\n          this.emit('signal', {\n            type: signal.type,\n            sdp: signal.sdp\n          })\n        }\n\n        const onSuccess = () => {\n          this._debug('createOffer success')\n          if (this.destroyed) return\n          if (this.trickle || this._iceComplete) sendOffer()\n          else this.once('_iceComplete', sendOffer) // wait for candidates\n        }\n\n        const onError = err => {\n          this.destroy(errCode(err, 'ERR_SET_LOCAL_DESCRIPTION'))\n        }\n\n        this._pc.setLocalDescription(offer)\n          .then(onSuccess)\n          .catch(onError)\n      })\n      .catch(err => {\n        this.destroy(errCode(err, 'ERR_CREATE_OFFER'))\n      })\n  }\n\n  _requestMissingTransceivers () {\n    if (this._pc.getTransceivers) {\n      this._pc.getTransceivers().forEach(transceiver => {\n        if (!transceiver.mid && transceiver.sender.track && !transceiver.requested) {\n          transceiver.requested = true // HACK: Safari returns negotiated transceivers with a null mid\n          this.addTransceiver(transceiver.sender.track.kind)\n        }\n      })\n    }\n  }\n\n  _createAnswer () {\n    if (this.destroyed) return\n\n    this._pc.createAnswer(this.answerOptions)\n      .then(answer => {\n        if (this.destroyed) return\n        if (!this.trickle && !this.allowHalfTrickle) answer.sdp = filterTrickle(answer.sdp)\n        answer.sdp = this.sdpTransform(answer.sdp)\n\n        const sendAnswer = () => {\n          if (this.destroyed) return\n          var signal = this._pc.localDescription || answer\n          this._debug('signal')\n          this.emit('signal', {\n            type: signal.type,\n            sdp: signal.sdp\n          })\n          if (!this.initiator) this._requestMissingTransceivers()\n        }\n\n        const onSuccess = () => {\n          if (this.destroyed) return\n          if (this.trickle || this._iceComplete) sendAnswer()\n          else this.once('_iceComplete', sendAnswer)\n        }\n\n        const onError = err => {\n          this.destroy(errCode(err, 'ERR_SET_LOCAL_DESCRIPTION'))\n        }\n\n        this._pc.setLocalDescription(answer)\n          .then(onSuccess)\n          .catch(onError)\n      })\n      .catch(err => {\n        this.destroy(errCode(err, 'ERR_CREATE_ANSWER'))\n      })\n  }\n\n  _onConnectionStateChange () {\n    if (this.destroyed) return\n    if (this._pc.connectionState === 'failed') {\n      this.destroy(errCode(new Error('Connection failed.'), 'ERR_CONNECTION_FAILURE'))\n    }\n  }\n\n  _onIceStateChange () {\n    if (this.destroyed) return\n    var iceConnectionState = this._pc.iceConnectionState\n    var iceGatheringState = this._pc.iceGatheringState\n\n    this._debug(\n      'iceStateChange (connection: %s) (gathering: %s)',\n      iceConnectionState,\n      iceGatheringState\n    )\n    this.emit('iceStateChange', iceConnectionState, iceGatheringState)\n\n    if (iceConnectionState === 'connected' || iceConnectionState === 'completed') {\n      this._pcReady = true\n      this._maybeReady()\n    }\n    if (iceConnectionState === 'failed') {\n      this.destroy(errCode(new Error('Ice connection failed.'), 'ERR_ICE_CONNECTION_FAILURE'))\n    }\n    if (iceConnectionState === 'closed') {\n      this.destroy(errCode(new Error('Ice connection closed.'), 'ERR_ICE_CONNECTION_CLOSED'))\n    }\n  }\n\n  getStats (cb) {\n    // statreports can come with a value array instead of properties\n    const flattenValues = report => {\n      if (Object.prototype.toString.call(report.values) === '[object Array]') {\n        report.values.forEach(value => {\n          Object.assign(report, value)\n        })\n      }\n      return report\n    }\n\n    // Promise-based getStats() (standard)\n    if (this._pc.getStats.length === 0 || this._isReactNativeWebrtc) {\n      this._pc.getStats()\n        .then(res => {\n          var reports = []\n          res.forEach(report => {\n            reports.push(flattenValues(report))\n          })\n          cb(null, reports)\n        }, err => cb(err))\n\n    // Single-parameter callback-based getStats() (non-standard)\n    } else if (this._pc.getStats.length > 0) {\n      this._pc.getStats(res => {\n        // If we destroy connection in `connect` callback this code might happen to run when actual connection is already closed\n        if (this.destroyed) return\n\n        var reports = []\n        res.result().forEach(result => {\n          var report = {}\n          result.names().forEach(name => {\n            report[name] = result.stat(name)\n          })\n          report.id = result.id\n          report.type = result.type\n          report.timestamp = result.timestamp\n          reports.push(flattenValues(report))\n        })\n        cb(null, reports)\n      }, err => cb(err))\n\n    // Unknown browser, skip getStats() since it's anyone's guess which style of\n    // getStats() they implement.\n    } else {\n      cb(null, [])\n    }\n  }\n\n  _maybeReady () {\n    this._debug('maybeReady pc %s channel %s', this._pcReady, this._channelReady)\n    if (this._connected || this._connecting || !this._pcReady || !this._channelReady) return\n\n    this._connecting = true\n\n    // HACK: We can't rely on order here, for details see https://github.com/js-platform/node-webrtc/issues/339\n    const findCandidatePair = () => {\n      if (this.destroyed) return\n\n      this.getStats((err, items) => {\n        if (this.destroyed) return\n\n        // Treat getStats error as non-fatal. It's not essential.\n        if (err) items = []\n\n        var remoteCandidates = {}\n        var localCandidates = {}\n        var candidatePairs = {}\n        var foundSelectedCandidatePair = false\n\n        items.forEach(item => {\n          // TODO: Once all browsers support the hyphenated stats report types, remove\n          // the non-hypenated ones\n          if (item.type === 'remotecandidate' || item.type === 'remote-candidate') {\n            remoteCandidates[item.id] = item\n          }\n          if (item.type === 'localcandidate' || item.type === 'local-candidate') {\n            localCandidates[item.id] = item\n          }\n          if (item.type === 'candidatepair' || item.type === 'candidate-pair') {\n            candidatePairs[item.id] = item\n          }\n        })\n\n        const setSelectedCandidatePair = selectedCandidatePair => {\n          foundSelectedCandidatePair = true\n\n          var local = localCandidates[selectedCandidatePair.localCandidateId]\n\n          if (local && (local.ip || local.address)) {\n            // Spec\n            this.localAddress = local.ip || local.address\n            this.localPort = Number(local.port)\n          } else if (local && local.ipAddress) {\n            // Firefox\n            this.localAddress = local.ipAddress\n            this.localPort = Number(local.portNumber)\n          } else if (typeof selectedCandidatePair.googLocalAddress === 'string') {\n            // TODO: remove this once Chrome 58 is released\n            local = selectedCandidatePair.googLocalAddress.split(':')\n            this.localAddress = local[0]\n            this.localPort = Number(local[1])\n          }\n          if (this.localAddress) {\n            this.localFamily = this.localAddress.includes(':') ? 'IPv6' : 'IPv4'\n          }\n\n          var remote = remoteCandidates[selectedCandidatePair.remoteCandidateId]\n\n          if (remote && (remote.ip || remote.address)) {\n            // Spec\n            this.remoteAddress = remote.ip || remote.address\n            this.remotePort = Number(remote.port)\n          } else if (remote && remote.ipAddress) {\n            // Firefox\n            this.remoteAddress = remote.ipAddress\n            this.remotePort = Number(remote.portNumber)\n          } else if (typeof selectedCandidatePair.googRemoteAddress === 'string') {\n            // TODO: remove this once Chrome 58 is released\n            remote = selectedCandidatePair.googRemoteAddress.split(':')\n            this.remoteAddress = remote[0]\n            this.remotePort = Number(remote[1])\n          }\n          if (this.remoteAddress) {\n            this.remoteFamily = this.remoteAddress.includes(':') ? 'IPv6' : 'IPv4'\n          }\n\n          this._debug(\n            'connect local: %s:%s remote: %s:%s',\n            this.localAddress, this.localPort, this.remoteAddress, this.remotePort\n          )\n        }\n\n        items.forEach(item => {\n          // Spec-compliant\n          if (item.type === 'transport' && item.selectedCandidatePairId) {\n            setSelectedCandidatePair(candidatePairs[item.selectedCandidatePairId])\n          }\n\n          // Old implementations\n          if (\n            (item.type === 'googCandidatePair' && item.googActiveConnection === 'true') ||\n            ((item.type === 'candidatepair' || item.type === 'candidate-pair') && item.selected)\n          ) {\n            setSelectedCandidatePair(item)\n          }\n        })\n\n        // Ignore candidate pair selection in browsers like Safari 11 that do not have any local or remote candidates\n        // But wait until at least 1 candidate pair is available\n        if (!foundSelectedCandidatePair && (!Object.keys(candidatePairs).length || Object.keys(localCandidates).length)) {\n          setTimeout(findCandidatePair, 100)\n          return\n        } else {\n          this._connecting = false\n          this._connected = true\n        }\n\n        if (this._chunk) {\n          try {\n            this.send(this._chunk)\n          } catch (err) {\n            return this.destroy(errCode(err, 'ERR_DATA_CHANNEL'))\n          }\n          this._chunk = null\n          this._debug('sent chunk from \"write before connect\"')\n\n          var cb = this._cb\n          this._cb = null\n          cb(null)\n        }\n\n        // If `bufferedAmountLowThreshold` and 'onbufferedamountlow' are unsupported,\n        // fallback to using setInterval to implement backpressure.\n        if (typeof this._channel.bufferedAmountLowThreshold !== 'number') {\n          this._interval = setInterval(() => this._onInterval(), 150)\n          if (this._interval.unref) this._interval.unref()\n        }\n\n        this._debug('connect')\n        this.emit('connect')\n      })\n    }\n    findCandidatePair()\n  }\n\n  _onInterval () {\n    if (!this._cb || !this._channel || this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {\n      return\n    }\n    this._onChannelBufferedAmountLow()\n  }\n\n  _onSignalingStateChange () {\n    if (this.destroyed) return\n\n    if (this._pc.signalingState === 'stable' && !this._firstStable) {\n      this._isNegotiating = false\n\n      // HACK: Firefox doesn't yet support removing tracks when signalingState !== 'stable'\n      this._debug('flushing sender queue', this._sendersAwaitingStable)\n      this._sendersAwaitingStable.forEach(sender => {\n        this._pc.removeTrack(sender)\n        this._queuedNegotiation = true\n      })\n      this._sendersAwaitingStable = []\n\n      if (this._queuedNegotiation) {\n        this._debug('flushing negotiation queue')\n        this._queuedNegotiation = false\n        this._needsNegotiation() // negotiate again\n      }\n\n      this._debug('negotiate')\n      this.emit('negotiate')\n    }\n    this._firstStable = false\n\n    this._debug('signalingStateChange %s', this._pc.signalingState)\n    this.emit('signalingStateChange', this._pc.signalingState)\n  }\n\n  _onIceCandidate (event) {\n    if (this.destroyed) return\n    if (event.candidate && this.trickle) {\n      this.emit('signal', {\n        candidate: {\n          candidate: event.candidate.candidate,\n          sdpMLineIndex: event.candidate.sdpMLineIndex,\n          sdpMid: event.candidate.sdpMid\n        }\n      })\n    } else if (!event.candidate && !this._iceComplete) {\n      this._iceComplete = true\n      this.emit('_iceComplete')\n    }\n    // as soon as we've received one valid candidate start timeout\n    if (event.candidate) {\n      this._startIceCompleteTimeout()\n    }\n  }\n\n  _onChannelMessage (event) {\n    if (this.destroyed) return\n    var data = event.data\n    if (data instanceof ArrayBuffer) data = Buffer.from(data)\n    this.push(data)\n  }\n\n  _onChannelBufferedAmountLow () {\n    if (this.destroyed || !this._cb) return\n    this._debug('ending backpressure: bufferedAmount %d', this._channel.bufferedAmount)\n    var cb = this._cb\n    this._cb = null\n    cb(null)\n  }\n\n  _onChannelOpen () {\n    if (this._connected || this.destroyed) return\n    this._debug('on channel open')\n    this._channelReady = true\n    this._maybeReady()\n  }\n\n  _onChannelClose () {\n    if (this.destroyed) return\n    this._debug('on channel close')\n    this.destroy()\n  }\n\n  _onTrack (event) {\n    if (this.destroyed) return\n\n    event.streams.forEach(eventStream => {\n      this._debug('on track')\n      this.emit('track', event.track, eventStream)\n\n      this._remoteTracks.push({\n        track: event.track,\n        stream: eventStream\n      })\n\n      if (this._remoteStreams.some(remoteStream => {\n        return remoteStream.id === eventStream.id\n      })) return // Only fire one 'stream' event, even though there may be multiple tracks per stream\n\n      this._remoteStreams.push(eventStream)\n      queueMicrotask(() => {\n        this.emit('stream', eventStream) // ensure all tracks have been added\n      })\n    })\n  }\n\n  _debug () {\n    var args = [].slice.call(arguments)\n    args[0] = '[' + this._id + '] ' + args[0]\n    debug.apply(null, args)\n  }\n}\n\nPeer.WEBRTC_SUPPORT = !!getBrowserRTC()\n\n/**\n * Expose peer and data channel config for overriding all Peer\n * instances. Otherwise, just set opts.config or opts.channelConfig\n * when constructing a Peer.\n */\nPeer.config = {\n  iceServers: [\n    {\n      urls: [\n        'stun:stun.l.google.com:19302',\n        'stun:global.stun.twilio.com:3478'\n      ]\n    }\n  ],\n  sdpSemantics: 'unified-plan'\n}\n\nPeer.channelConfig = {}\n\nmodule.exports = Peer\n"]}