lakutata 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/codeStyles/Project.xml +18 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/lakutata.iml +13 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/build/Application-78a416de.d.ts +387 -0
- package/build/Application-b5e19e08.d.ts +387 -0
- package/build/Components.cjs +55 -0
- package/build/Components.d.cts +9 -0
- package/build/Components.d.ts +9 -0
- package/build/Components.js +44 -0
- package/build/Core.cjs +148 -0
- package/build/Core.d.cts +33 -0
- package/build/Core.d.ts +33 -0
- package/build/Core.js +71 -0
- package/build/Crypto.cjs +96 -0
- package/build/Crypto.d.cts +19 -0
- package/build/Crypto.d.ts +19 -0
- package/build/Crypto.js +41 -0
- package/build/Decorators.cjs +100 -0
- package/build/Decorators.d.cts +23 -0
- package/build/Decorators.d.ts +23 -0
- package/build/Decorators.js +45 -0
- package/build/DependencyInjectionContainer-871a6c03.d.ts +340 -0
- package/build/DependencyInjectionContainer-f037ac36.d.ts +340 -0
- package/build/Exceptions.cjs +144 -0
- package/build/Exceptions.d.cts +28 -0
- package/build/Exceptions.d.ts +28 -0
- package/build/Exceptions.js +37 -0
- package/build/Hash.cjs +223 -0
- package/build/Hash.d.cts +535 -0
- package/build/Hash.d.ts +535 -0
- package/build/Hash.js +10 -0
- package/build/Time.cjs +14 -0
- package/build/Time.d.cts +5 -0
- package/build/Time.d.ts +5 -0
- package/build/Time.js +5 -0
- package/build/TimeInput-24fced42.d.ts +243 -0
- package/build/TimeInput-4401fc58.d.ts +243 -0
- package/build/Utilities.cjs +100 -0
- package/build/Utilities.d.cts +212 -0
- package/build/Utilities.d.ts +212 -0
- package/build/Utilities.js +7 -0
- package/build/Validator.cjs +24 -0
- package/build/Validator.d.cts +1851 -0
- package/build/Validator.d.ts +1851 -0
- package/build/Validator.js +11 -0
- package/build/chunk-26TQI22I.js +196 -0
- package/build/chunk-27OFA7C3.js +16 -0
- package/build/chunk-2C2UILFN.js +23 -0
- package/build/chunk-2CHYQHWR.cjs +16 -0
- package/build/chunk-2DN35UQB.cjs +10947 -0
- package/build/chunk-2E4TF6LU.cjs +16 -0
- package/build/chunk-2PLJEW2R.js +14 -0
- package/build/chunk-2RW3VMNS.js +45 -0
- package/build/chunk-2T6JU2UH.js +14 -0
- package/build/chunk-3CX3GCQF.js +32 -0
- package/build/chunk-3JIQCDQG.cjs +25 -0
- package/build/chunk-3KLEN3PR.js +14 -0
- package/build/chunk-3LZRQPJ5.js +14 -0
- package/build/chunk-3NHHHZFR.cjs +870 -0
- package/build/chunk-4332C5BW.js +30 -0
- package/build/chunk-46V7GHKE.cjs +25 -0
- package/build/chunk-4EPPSZ7L.js +14 -0
- package/build/chunk-4FEEQIQ4.js +23 -0
- package/build/chunk-4G2ZCUBN.js +5570 -0
- package/build/chunk-4KTVY73U.js +15 -0
- package/build/chunk-4MQXSUTL.cjs +14 -0
- package/build/chunk-4OHSPWRQ.js +34 -0
- package/build/chunk-4PK4TGU4.cjs +16 -0
- package/build/chunk-4YXUEJSO.js +23 -0
- package/build/chunk-5475IFR4.cjs +16 -0
- package/build/chunk-5B5Z4GCR.cjs +17 -0
- package/build/chunk-5FPTDIKI.cjs +16 -0
- package/build/chunk-5NK7E2HA.js +69 -0
- package/build/chunk-67F5WP5Z.cjs +8 -0
- package/build/chunk-6BJTKEXZ.cjs +25 -0
- package/build/chunk-6WNLPTDY.cjs +8 -0
- package/build/chunk-7G7FCNEG.cjs +8 -0
- package/build/chunk-7IVNTVYK.cjs +16 -0
- package/build/chunk-7MJAWOWL.js +22896 -0
- package/build/chunk-7MTOK62N.js +767 -0
- package/build/chunk-7PADGZPI.cjs +129 -0
- package/build/chunk-7ZUM53G6.js +14 -0
- package/build/chunk-A4BYNKYF.js +42 -0
- package/build/chunk-A7F6LCRA.cjs +16 -0
- package/build/chunk-AFV3VN3X.cjs +8 -0
- package/build/chunk-AGHMOCC3.cjs +16 -0
- package/build/chunk-AHUH4FWQ.cjs +29 -0
- package/build/chunk-AM4YMG2S.js +6 -0
- package/build/chunk-ANDEVIKJ.cjs +16 -0
- package/build/chunk-APETX7ZT.cjs +16 -0
- package/build/chunk-ASMC7EUP.js +6 -0
- package/build/chunk-BDCRHGKN.js +6 -0
- package/build/chunk-BDJXMO44.js +2920 -0
- package/build/chunk-BE7ICF5R.js +32 -0
- package/build/chunk-BEDKPRVX.cjs +17 -0
- package/build/chunk-BFE66ADZ.cjs +34 -0
- package/build/chunk-BKCT2HSQ.js +178 -0
- package/build/chunk-BMNC4W46.js +20 -0
- package/build/chunk-BO7Y6HNS.cjs +176 -0
- package/build/chunk-D4H35ART.cjs +53 -0
- package/build/chunk-D5DE7Z4J.js +29 -0
- package/build/chunk-DHSSJJMD.cjs +25 -0
- package/build/chunk-DIMOR6NE.cjs +8 -0
- package/build/chunk-DN5TSX6S.cjs +244 -0
- package/build/chunk-EEH5LCBP.cjs +16 -0
- package/build/chunk-EFYDUUXT.cjs +92 -0
- package/build/chunk-ENJSEFE4.js +14 -0
- package/build/chunk-EPYJVQHQ.js +6 -0
- package/build/chunk-EUVLTNDV.js +32 -0
- package/build/chunk-EXQVCESB.cjs +20 -0
- package/build/chunk-EYPPC6HP.js +18 -0
- package/build/chunk-F5NKGQDL.cjs +16 -0
- package/build/chunk-F7RNH2H2.js +266 -0
- package/build/chunk-FCTV4OB7.cjs +50 -0
- package/build/chunk-FHEXUE67.js +29 -0
- package/build/chunk-FJP3KNXK.js +23 -0
- package/build/chunk-FJQSLRIP.js +14 -0
- package/build/chunk-FSFWPTIC.js +6 -0
- package/build/chunk-FTKFMQHJ.cjs +16 -0
- package/build/chunk-FW26MPE4.js +69 -0
- package/build/chunk-FZNRGZGE.js +6372 -0
- package/build/chunk-G7EDOLQ7.cjs +100 -0
- package/build/chunk-GGY7LCMQ.cjs +73 -0
- package/build/chunk-GLWUJIMW.cjs +8 -0
- package/build/chunk-GZ5KN2PE.js +6 -0
- package/build/chunk-HBPRX3WA.cjs +202 -0
- package/build/chunk-HJAQ6WJM.cjs +288 -0
- package/build/chunk-HJSJA5CF.js +14 -0
- package/build/chunk-HKAY7FWM.js +28 -0
- package/build/chunk-HMKTNRQF.js +14 -0
- package/build/chunk-HODDA5D5.js +199 -0
- package/build/chunk-HPKJUFTM.js +14 -0
- package/build/chunk-HWCTWIVZ.cjs +30 -0
- package/build/chunk-HXWC4YN6.cjs +22908 -0
- package/build/chunk-HZJ7XFHQ.cjs +8 -0
- package/build/chunk-I5TGKTX6.js +18 -0
- package/build/chunk-I7J6V3EU.cjs +34 -0
- package/build/chunk-IKWXYUGY.js +14 -0
- package/build/chunk-IYGGR65W.cjs +16 -0
- package/build/chunk-J6RXNX2K.js +174 -0
- package/build/chunk-JAEEMFEZ.cjs +24 -0
- package/build/chunk-JFOMNL5I.cjs +22 -0
- package/build/chunk-JPV2PUHF.cjs +8 -0
- package/build/chunk-JR726PDZ.cjs +70 -0
- package/build/chunk-JTKOYDJB.js +5914 -0
- package/build/chunk-JU53NOVA.cjs +31 -0
- package/build/chunk-JVSBYHUY.js +10944 -0
- package/build/chunk-JYBISTRN.cjs +25 -0
- package/build/chunk-K2ALA7QI.js +12 -0
- package/build/chunk-KG6DPM4B.js +14 -0
- package/build/chunk-KNSBLLL2.cjs +32 -0
- package/build/chunk-KNTGBUSY.js +6 -0
- package/build/chunk-KWOHVRRL.js +6 -0
- package/build/chunk-L3IVYIVA.js +23 -0
- package/build/chunk-LBL5XNWX.js +221 -0
- package/build/chunk-LBOBUFWZ.js +6 -0
- package/build/chunk-LEJXJUBE.js +6 -0
- package/build/chunk-LJTCXKC4.js +242 -0
- package/build/chunk-MBKTJ3KM.cjs +118 -0
- package/build/chunk-MDE5SRLT.cjs +16 -0
- package/build/chunk-MEKICSEL.js +22 -0
- package/build/chunk-MNDBRDT2.cjs +608 -0
- package/build/chunk-MSWZLYS7.cjs +5916 -0
- package/build/chunk-MT2OB376.js +14 -0
- package/build/chunk-MVWB4XDJ.js +14 -0
- package/build/chunk-MXAAAL2S.js +53 -0
- package/build/chunk-N37KV2VV.cjs +199 -0
- package/build/chunk-NZ5IZMM5.cjs +2922 -0
- package/build/chunk-O2NOYN65.js +54 -0
- package/build/chunk-OAD22QZQ.js +6 -0
- package/build/chunk-OIFILR4I.js +125 -0
- package/build/chunk-OJGBPS2B.cjs +16 -0
- package/build/chunk-OMPATIMZ.cjs +71 -0
- package/build/chunk-P3Z7ZEGJ.cjs +18 -0
- package/build/chunk-P6BBXCBD.cjs +6425 -0
- package/build/chunk-PE4C2TIO.cjs +16 -0
- package/build/chunk-PF2WAZLH.cjs +52 -0
- package/build/chunk-PFFTGOAR.cjs +25 -0
- package/build/chunk-PFUZLHWJ.cjs +25 -0
- package/build/chunk-POE7A7NF.cjs +180 -0
- package/build/chunk-PQSDA5BN.js +50 -0
- package/build/chunk-PR5TPAGH.js +14 -0
- package/build/chunk-PXMWVOKK.cjs +16 -0
- package/build/chunk-PZ5OJC4I.cjs +16 -0
- package/build/chunk-Q4LNTPEI.cjs +34 -0
- package/build/chunk-QCA5YGYV.js +14 -0
- package/build/chunk-QGGML4PP.js +17 -0
- package/build/chunk-QHW273SN.js +32 -0
- package/build/chunk-QJJRQMA6.cjs +8 -0
- package/build/chunk-QKB76MIV.cjs +769 -0
- package/build/chunk-QKVPGRI5.cjs +8 -0
- package/build/chunk-QME47CJL.cjs +8 -0
- package/build/chunk-QNJ6XBYQ.js +14 -0
- package/build/chunk-QWYKUNU5.js +14 -0
- package/build/chunk-QXTBP6TW.js +116 -0
- package/build/chunk-RH3LAIQS.js +32 -0
- package/build/chunk-RMAXG5F7.js +118 -0
- package/build/chunk-RUHAPGDE.js +14 -0
- package/build/chunk-S4KA3ZGO.js +6 -0
- package/build/chunk-SAGMV3YX.cjs +16 -0
- package/build/chunk-SCWEQ5JA.cjs +34 -0
- package/build/chunk-SEKBDIJH.cjs +16 -0
- package/build/chunk-SGWWTKLW.cjs +16 -0
- package/build/chunk-SWCU6OID.cjs +61 -0
- package/build/chunk-T4C7UJEZ.js +29 -0
- package/build/chunk-TBWIKIS3.cjs +8 -0
- package/build/chunk-TS74DN3N.cjs +229 -0
- package/build/chunk-TXTNUC7S.cjs +16 -0
- package/build/chunk-UEGDBJEG.cjs +127 -0
- package/build/chunk-UR2ZK7MI.cjs +16 -0
- package/build/chunk-VAOR6JOP.js +14 -0
- package/build/chunk-VELZ3KJY.cjs +45 -0
- package/build/chunk-VHTAHAD6.cjs +34 -0
- package/build/chunk-VISA22LF.js +14 -0
- package/build/chunk-VOFRWVGM.js +23 -0
- package/build/chunk-VPRNM6FU.cjs +118 -0
- package/build/chunk-VTFNEUOF.js +14 -0
- package/build/chunk-VVNU27G2.js +868 -0
- package/build/chunk-W3TQER3B.cjs +31 -0
- package/build/chunk-WINISBV4.js +70 -0
- package/build/chunk-WSEZ7DZV.js +14 -0
- package/build/chunk-WW57G6RG.js +124 -0
- package/build/chunk-WYJCE3KY.cjs +5593 -0
- package/build/chunk-WZI5UPER.cjs +61 -0
- package/build/chunk-WZZF2IEV.js +14 -0
- package/build/chunk-X4AIZSIY.cjs +47 -0
- package/build/chunk-XO6M5AYN.js +585 -0
- package/build/chunk-XWP76C6E.js +25 -0
- package/build/chunk-Y7O5SCF6.cjs +16 -0
- package/build/chunk-YEBPQG7X.js +96 -0
- package/build/chunk-YT4CYDJ3.js +14 -0
- package/build/chunk-ZG3PHRVQ.cjs +20 -0
- package/build/chunk-ZG7QF5S2.cjs +16 -0
- package/build/chunk-ZJYLWSBE.js +90 -0
- package/build/chunk-ZYBMNLGI.js +48 -0
- package/build/constants/DefaultValue.cjs +14 -0
- package/build/constants/DefaultValue.d.cts +9 -0
- package/build/constants/DefaultValue.d.ts +9 -0
- package/build/constants/DefaultValue.js +5 -0
- package/build/constants/MetadataKey.cjs +114 -0
- package/build/constants/MetadataKey.d.cts +30 -0
- package/build/constants/MetadataKey.d.ts +30 -0
- package/build/constants/MetadataKey.js +5 -0
- package/build/decorators/ControllerDecorators.cjs +21 -0
- package/build/decorators/ControllerDecorators.d.cts +32 -0
- package/build/decorators/ControllerDecorators.d.ts +32 -0
- package/build/decorators/ControllerDecorators.js +12 -0
- package/build/decorators/DependencyInjectionDecorators.cjs +78 -0
- package/build/decorators/DependencyInjectionDecorators.d.cts +75 -0
- package/build/decorators/DependencyInjectionDecorators.d.ts +75 -0
- package/build/decorators/DependencyInjectionDecorators.js +41 -0
- package/build/decorators/ValidationDecorators.cjs +35 -0
- package/build/decorators/ValidationDecorators.d.cts +36 -0
- package/build/decorators/ValidationDecorators.d.ts +36 -0
- package/build/decorators/ValidationDecorators.js +14 -0
- package/build/exceptions/DependencyInjectionException.cjs +18 -0
- package/build/exceptions/DependencyInjectionException.d.cts +8 -0
- package/build/exceptions/DependencyInjectionException.d.ts +8 -0
- package/build/exceptions/DependencyInjectionException.js +9 -0
- package/build/exceptions/InvalidConfigurableValueException.cjs +18 -0
- package/build/exceptions/InvalidConfigurableValueException.d.cts +8 -0
- package/build/exceptions/InvalidConfigurableValueException.d.ts +8 -0
- package/build/exceptions/InvalidConfigurableValueException.js +9 -0
- package/build/exceptions/InvalidDTOValueException.cjs +18 -0
- package/build/exceptions/InvalidDTOValueException.d.cts +8 -0
- package/build/exceptions/InvalidDTOValueException.d.ts +8 -0
- package/build/exceptions/InvalidDTOValueException.js +9 -0
- package/build/exceptions/InvalidGlobStringException.cjs +18 -0
- package/build/exceptions/InvalidGlobStringException.d.cts +8 -0
- package/build/exceptions/InvalidGlobStringException.d.ts +8 -0
- package/build/exceptions/InvalidGlobStringException.js +9 -0
- package/build/exceptions/MethodNotFoundException.cjs +18 -0
- package/build/exceptions/MethodNotFoundException.d.cts +8 -0
- package/build/exceptions/MethodNotFoundException.d.ts +8 -0
- package/build/exceptions/MethodNotFoundException.js +9 -0
- package/build/exceptions/NotSupportHashException.cjs +18 -0
- package/build/exceptions/NotSupportHashException.d.cts +8 -0
- package/build/exceptions/NotSupportHashException.d.ts +8 -0
- package/build/exceptions/NotSupportHashException.js +9 -0
- package/build/exceptions/controller/DuplicateControllerActionPatternException.cjs +18 -0
- package/build/exceptions/controller/DuplicateControllerActionPatternException.d.cts +8 -0
- package/build/exceptions/controller/DuplicateControllerActionPatternException.d.ts +8 -0
- package/build/exceptions/controller/DuplicateControllerActionPatternException.js +9 -0
- package/build/exceptions/controller/DynamicRegisterControllerNotAllowException.cjs +18 -0
- package/build/exceptions/controller/DynamicRegisterControllerNotAllowException.d.cts +8 -0
- package/build/exceptions/controller/DynamicRegisterControllerNotAllowException.d.ts +8 -0
- package/build/exceptions/controller/DynamicRegisterControllerNotAllowException.js +9 -0
- package/build/exceptions/controller/NoMatchedControllerActionPatternException.cjs +18 -0
- package/build/exceptions/controller/NoMatchedControllerActionPatternException.d.cts +8 -0
- package/build/exceptions/controller/NoMatchedControllerActionPatternException.d.ts +8 -0
- package/build/exceptions/controller/NoMatchedControllerActionPatternException.js +9 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricDecryptException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricDecryptException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricDecryptException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricDecryptException.js +9 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricEncryptException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricEncryptException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricEncryptException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricEncryptException.js +9 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricSignException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricSignException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricSignException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricSignException.js +9 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricVerifyException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricVerifyException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricVerifyException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/AsymmetricVerifyException.js +9 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptKeyPairException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptKeyPairException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptKeyPairException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptKeyPairException.js +9 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPrivateKeyException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPrivateKeyException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPrivateKeyException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPrivateKeyException.js +9 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPublicKeyException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPublicKeyException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPublicKeyException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/InvalidAsymmetricEncryptPublicKeyException.js +9 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPrivateKeyException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPrivateKeyException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPrivateKeyException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPrivateKeyException.js +9 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPublicKeyException.cjs +18 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPublicKeyException.d.cts +8 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPublicKeyException.d.ts +8 -0
- package/build/exceptions/crypto/asymmetric/NoAsymmetricEncryptPublicKeyException.js +9 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherIVLengthException.cjs +18 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherIVLengthException.d.cts +8 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherIVLengthException.d.ts +8 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherIVLengthException.js +9 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherKeyLengthException.cjs +18 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherKeyLengthException.d.cts +8 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherKeyLengthException.d.ts +8 -0
- package/build/exceptions/crypto/symmetric/InvalidSymmetricCipherKeyLengthException.js +9 -0
- package/build/exceptions/crypto/symmetric/NotSupportCipherException.cjs +18 -0
- package/build/exceptions/crypto/symmetric/NotSupportCipherException.d.cts +8 -0
- package/build/exceptions/crypto/symmetric/NotSupportCipherException.d.ts +8 -0
- package/build/exceptions/crypto/symmetric/NotSupportCipherException.js +9 -0
- package/build/exceptions/crypto/symmetric/SymmetricDecryptException.cjs +18 -0
- package/build/exceptions/crypto/symmetric/SymmetricDecryptException.d.cts +8 -0
- package/build/exceptions/crypto/symmetric/SymmetricDecryptException.d.ts +8 -0
- package/build/exceptions/crypto/symmetric/SymmetricDecryptException.js +9 -0
- package/build/exceptions/crypto/symmetric/SymmetricEncryptException.cjs +18 -0
- package/build/exceptions/crypto/symmetric/SymmetricEncryptException.d.cts +8 -0
- package/build/exceptions/crypto/symmetric/SymmetricEncryptException.d.ts +8 -0
- package/build/exceptions/crypto/symmetric/SymmetricEncryptException.js +9 -0
- package/build/exceptions/validation/InvalidMethodAcceptException.cjs +18 -0
- package/build/exceptions/validation/InvalidMethodAcceptException.d.cts +8 -0
- package/build/exceptions/validation/InvalidMethodAcceptException.d.ts +8 -0
- package/build/exceptions/validation/InvalidMethodAcceptException.js +9 -0
- package/build/exceptions/validation/InvalidMethodReturnException.cjs +18 -0
- package/build/exceptions/validation/InvalidMethodReturnException.d.cts +8 -0
- package/build/exceptions/validation/InvalidMethodReturnException.d.ts +8 -0
- package/build/exceptions/validation/InvalidMethodReturnException.js +9 -0
- package/build/exceptions/validation/InvalidValueException.cjs +18 -0
- package/build/exceptions/validation/InvalidValueException.d.cts +8 -0
- package/build/exceptions/validation/InvalidValueException.d.ts +8 -0
- package/build/exceptions/validation/InvalidValueException.js +9 -0
- package/build/index.d-e5279fea.d.ts +872 -0
- package/build/interfaces/IConstructor.cjs +7 -0
- package/build/interfaces/IConstructor.d.cts +6 -0
- package/build/interfaces/IConstructor.d.ts +6 -0
- package/build/interfaces/IConstructor.js +4 -0
- package/build/interfaces/ILogger.cjs +7 -0
- package/build/interfaces/ILogger.d.cts +22 -0
- package/build/interfaces/ILogger.d.ts +22 -0
- package/build/interfaces/ILogger.js +4 -0
- package/build/interfaces/IPatRun.cjs +7 -0
- package/build/interfaces/IPatRun.d.cts +12 -0
- package/build/interfaces/IPatRun.d.ts +12 -0
- package/build/interfaces/IPatRun.js +4 -0
- package/build/interfaces/ISortArrayOptions.cjs +7 -0
- package/build/interfaces/ISortArrayOptions.d.cts +12 -0
- package/build/interfaces/ISortArrayOptions.d.ts +12 -0
- package/build/interfaces/ISortArrayOptions.js +4 -0
- package/build/interfaces/ISortObjectOptions.cjs +7 -0
- package/build/interfaces/ISortObjectOptions.d.cts +6 -0
- package/build/interfaces/ISortObjectOptions.d.ts +6 -0
- package/build/interfaces/ISortObjectOptions.js +4 -0
- package/build/lib/Application.cjs +50 -0
- package/build/lib/Application.d.cts +20 -0
- package/build/lib/Application.d.ts +20 -0
- package/build/lib/Application.js +41 -0
- package/build/lib/base/BaseObject.cjs +50 -0
- package/build/lib/base/BaseObject.d.cts +112 -0
- package/build/lib/base/BaseObject.d.ts +112 -0
- package/build/lib/base/BaseObject.js +41 -0
- package/build/lib/base/Component.cjs +50 -0
- package/build/lib/base/Component.d.cts +116 -0
- package/build/lib/base/Component.d.ts +116 -0
- package/build/lib/base/Component.js +41 -0
- package/build/lib/base/Container.cjs +50 -0
- package/build/lib/base/Container.d.cts +20 -0
- package/build/lib/base/Container.d.ts +20 -0
- package/build/lib/base/Container.js +41 -0
- package/build/lib/base/Controller.cjs +50 -0
- package/build/lib/base/Controller.d.cts +20 -0
- package/build/lib/base/Controller.d.ts +20 -0
- package/build/lib/base/Controller.js +41 -0
- package/build/lib/base/DTO.cjs +23 -0
- package/build/lib/base/DTO.d.cts +59 -0
- package/build/lib/base/DTO.d.ts +59 -0
- package/build/lib/base/DTO.js +14 -0
- package/build/lib/base/Model.cjs +51 -0
- package/build/lib/base/Model.d.cts +30 -0
- package/build/lib/base/Model.d.ts +30 -0
- package/build/lib/base/Model.js +42 -0
- package/build/lib/base/Module.cjs +50 -0
- package/build/lib/base/Module.d.cts +20 -0
- package/build/lib/base/Module.d.ts +20 -0
- package/build/lib/base/Module.js +41 -0
- package/build/lib/base/abstracts/AsymmetricEncryption.cjs +27 -0
- package/build/lib/base/abstracts/AsymmetricEncryption.d.cts +172 -0
- package/build/lib/base/abstracts/AsymmetricEncryption.d.ts +172 -0
- package/build/lib/base/abstracts/AsymmetricEncryption.js +18 -0
- package/build/lib/base/abstracts/Exception.cjs +17 -0
- package/build/lib/base/abstracts/Exception.d.cts +23 -0
- package/build/lib/base/abstracts/Exception.d.ts +23 -0
- package/build/lib/base/abstracts/Exception.js +8 -0
- package/build/lib/base/abstracts/Interval.cjs +51 -0
- package/build/lib/base/abstracts/Interval.d.cts +76 -0
- package/build/lib/base/abstracts/Interval.d.ts +76 -0
- package/build/lib/base/abstracts/Interval.js +42 -0
- package/build/lib/base/abstracts/SymmetricEncryption.cjs +23 -0
- package/build/lib/base/abstracts/SymmetricEncryption.d.cts +149 -0
- package/build/lib/base/abstracts/SymmetricEncryption.d.ts +149 -0
- package/build/lib/base/abstracts/SymmetricEncryption.js +14 -0
- package/build/lib/base/async-constructor/Append.cjs +14 -0
- package/build/lib/base/async-constructor/Append.d.cts +5 -0
- package/build/lib/base/async-constructor/Append.d.ts +5 -0
- package/build/lib/base/async-constructor/Append.js +5 -0
- package/build/lib/base/async-constructor/AsyncConstructor.cjs +15 -0
- package/build/lib/base/async-constructor/AsyncConstructor.d.cts +7 -0
- package/build/lib/base/async-constructor/AsyncConstructor.d.ts +7 -0
- package/build/lib/base/async-constructor/AsyncConstructor.js +6 -0
- package/build/lib/components/Formatter.cjs +50 -0
- package/build/lib/components/Formatter.d.cts +203 -0
- package/build/lib/components/Formatter.d.ts +203 -0
- package/build/lib/components/Formatter.js +41 -0
- package/build/lib/components/Logger.cjs +50 -0
- package/build/lib/components/Logger.d.cts +61 -0
- package/build/lib/components/Logger.d.ts +61 -0
- package/build/lib/components/Logger.js +41 -0
- package/build/lib/crypto/RSA.cjs +28 -0
- package/build/lib/crypto/RSA.d.cts +61 -0
- package/build/lib/crypto/RSA.d.ts +61 -0
- package/build/lib/crypto/RSA.js +19 -0
- package/build/lib/crypto/SM2.cjs +28 -0
- package/build/lib/crypto/SM2.d.cts +47 -0
- package/build/lib/crypto/SM2.d.ts +47 -0
- package/build/lib/crypto/SM2.js +19 -0
- package/build/lib/crypto/aes/AES128.cjs +25 -0
- package/build/lib/crypto/aes/AES128.d.cts +14 -0
- package/build/lib/crypto/aes/AES128.d.ts +14 -0
- package/build/lib/crypto/aes/AES128.js +16 -0
- package/build/lib/crypto/aes/AES192.cjs +25 -0
- package/build/lib/crypto/aes/AES192.d.cts +14 -0
- package/build/lib/crypto/aes/AES192.d.ts +14 -0
- package/build/lib/crypto/aes/AES192.js +16 -0
- package/build/lib/crypto/aes/AES256.cjs +25 -0
- package/build/lib/crypto/aes/AES256.d.cts +14 -0
- package/build/lib/crypto/aes/AES256.d.ts +14 -0
- package/build/lib/crypto/aes/AES256.js +16 -0
- package/build/lib/crypto/aria/ARIA128.cjs +24 -0
- package/build/lib/crypto/aria/ARIA128.d.cts +13 -0
- package/build/lib/crypto/aria/ARIA128.d.ts +13 -0
- package/build/lib/crypto/aria/ARIA128.js +15 -0
- package/build/lib/crypto/aria/ARIA192.cjs +24 -0
- package/build/lib/crypto/aria/ARIA192.d.cts +13 -0
- package/build/lib/crypto/aria/ARIA192.d.ts +13 -0
- package/build/lib/crypto/aria/ARIA192.js +15 -0
- package/build/lib/crypto/aria/ARIA256.cjs +24 -0
- package/build/lib/crypto/aria/ARIA256.d.cts +13 -0
- package/build/lib/crypto/aria/ARIA256.d.ts +13 -0
- package/build/lib/crypto/aria/ARIA256.js +15 -0
- package/build/lib/crypto/camellia/CAMELLIA128.cjs +24 -0
- package/build/lib/crypto/camellia/CAMELLIA128.d.cts +13 -0
- package/build/lib/crypto/camellia/CAMELLIA128.d.ts +13 -0
- package/build/lib/crypto/camellia/CAMELLIA128.js +15 -0
- package/build/lib/crypto/camellia/CAMELLIA192.cjs +24 -0
- package/build/lib/crypto/camellia/CAMELLIA192.d.cts +13 -0
- package/build/lib/crypto/camellia/CAMELLIA192.d.ts +13 -0
- package/build/lib/crypto/camellia/CAMELLIA192.js +15 -0
- package/build/lib/crypto/camellia/CAMELLIA256.cjs +24 -0
- package/build/lib/crypto/camellia/CAMELLIA256.d.cts +13 -0
- package/build/lib/crypto/camellia/CAMELLIA256.d.ts +13 -0
- package/build/lib/crypto/camellia/CAMELLIA256.js +15 -0
- package/build/lib/crypto/des/DES.cjs +25 -0
- package/build/lib/crypto/des/DES.d.cts +14 -0
- package/build/lib/crypto/des/DES.d.ts +14 -0
- package/build/lib/crypto/des/DES.js +16 -0
- package/build/lib/crypto/des/TripleDES.cjs +25 -0
- package/build/lib/crypto/des/TripleDES.d.cts +14 -0
- package/build/lib/crypto/des/TripleDES.d.ts +14 -0
- package/build/lib/crypto/des/TripleDES.js +16 -0
- package/build/lib/ioc/DependencyInjectionContainer.cjs +29 -0
- package/build/lib/ioc/DependencyInjectionContainer.d.cts +4 -0
- package/build/lib/ioc/DependencyInjectionContainer.d.ts +4 -0
- package/build/lib/ioc/DependencyInjectionContainer.js +20 -0
- package/build/lib/ioc/Errors.cjs +27 -0
- package/build/lib/ioc/Errors.d.cts +53 -0
- package/build/lib/ioc/Errors.d.ts +53 -0
- package/build/lib/ioc/Errors.js +10 -0
- package/build/lib/ioc/FunctionTokenizer.cjs +18 -0
- package/build/lib/ioc/FunctionTokenizer.d.cts +33 -0
- package/build/lib/ioc/FunctionTokenizer.d.ts +33 -0
- package/build/lib/ioc/FunctionTokenizer.js +5 -0
- package/build/lib/ioc/InjectionMode.cjs +14 -0
- package/build/lib/ioc/InjectionMode.d.cts +12 -0
- package/build/lib/ioc/InjectionMode.d.ts +12 -0
- package/build/lib/ioc/InjectionMode.js +5 -0
- package/build/lib/ioc/Lifetime.cjs +14 -0
- package/build/lib/ioc/Lifetime.d.cts +12 -0
- package/build/lib/ioc/Lifetime.d.ts +12 -0
- package/build/lib/ioc/Lifetime.js +5 -0
- package/build/lib/ioc/ListModules.cjs +17 -0
- package/build/lib/ioc/ListModules.d.cts +4 -0
- package/build/lib/ioc/ListModules.d.ts +4 -0
- package/build/lib/ioc/ListModules.js +8 -0
- package/build/lib/ioc/LoadModuleNative.cjs +14 -0
- package/build/lib/ioc/LoadModuleNative.d.cts +9 -0
- package/build/lib/ioc/LoadModuleNative.d.ts +9 -0
- package/build/lib/ioc/LoadModuleNative.js +5 -0
- package/build/lib/ioc/LoadModules.cjs +26 -0
- package/build/lib/ioc/LoadModules.d.cts +4 -0
- package/build/lib/ioc/LoadModules.d.ts +4 -0
- package/build/lib/ioc/LoadModules.js +17 -0
- package/build/lib/ioc/ParamParser.cjs +15 -0
- package/build/lib/ioc/ParamParser.d.cts +25 -0
- package/build/lib/ioc/ParamParser.d.ts +25 -0
- package/build/lib/ioc/ParamParser.js +6 -0
- package/build/lib/ioc/Resolvers.cjs +49 -0
- package/build/lib/ioc/Resolvers.d.cts +4 -0
- package/build/lib/ioc/Resolvers.d.ts +4 -0
- package/build/lib/ioc/Resolvers.js +16 -0
- package/build/lib/ioc/Utils.cjs +35 -0
- package/build/lib/ioc/Utils.d.cts +38 -0
- package/build/lib/ioc/Utils.d.ts +38 -0
- package/build/lib/ioc/Utils.js +6 -0
- package/build/options/ApplicationOptions.cjs +50 -0
- package/build/options/ApplicationOptions.d.cts +20 -0
- package/build/options/ApplicationOptions.d.ts +20 -0
- package/build/options/ApplicationOptions.js +41 -0
- package/build/options/LoadComponentOptions.cjs +50 -0
- package/build/options/LoadComponentOptions.d.cts +22 -0
- package/build/options/LoadComponentOptions.d.ts +22 -0
- package/build/options/LoadComponentOptions.js +41 -0
- package/build/options/LoadEntryClassOptions.cjs +50 -0
- package/build/options/LoadEntryClassOptions.d.cts +16 -0
- package/build/options/LoadEntryClassOptions.d.ts +16 -0
- package/build/options/LoadEntryClassOptions.js +41 -0
- package/build/options/LoadEntryCommonOptions.cjs +27 -0
- package/build/options/LoadEntryCommonOptions.d.cts +13 -0
- package/build/options/LoadEntryCommonOptions.d.ts +13 -0
- package/build/options/LoadEntryCommonOptions.js +18 -0
- package/build/options/LoadModuleOptions.cjs +50 -0
- package/build/options/LoadModuleOptions.d.cts +20 -0
- package/build/options/LoadModuleOptions.d.ts +20 -0
- package/build/options/LoadModuleOptions.js +41 -0
- package/build/options/ModuleOptions.cjs +50 -0
- package/build/options/ModuleOptions.d.cts +20 -0
- package/build/options/ModuleOptions.d.ts +20 -0
- package/build/options/ModuleOptions.js +41 -0
- package/build/types/AsyncFunction.cjs +7 -0
- package/build/types/AsyncFunction.d.cts +3 -0
- package/build/types/AsyncFunction.d.ts +3 -0
- package/build/types/AsyncFunction.js +4 -0
- package/build/types/ControllerActionMapItem.cjs +7 -0
- package/build/types/ControllerActionMapItem.d.cts +20 -0
- package/build/types/ControllerActionMapItem.d.ts +20 -0
- package/build/types/ControllerActionMapItem.js +4 -0
- package/build/types/InjectionProperties.cjs +7 -0
- package/build/types/InjectionProperties.d.cts +3 -0
- package/build/types/InjectionProperties.d.ts +3 -0
- package/build/types/InjectionProperties.js +4 -0
- package/build/types/TimeInput.cjs +7 -0
- package/build/types/TimeInput.d.cts +5 -0
- package/build/types/TimeInput.d.ts +5 -0
- package/build/types/TimeInput.js +4 -0
- package/build/types/TimeObject.cjs +7 -0
- package/build/types/TimeObject.d.cts +11 -0
- package/build/types/TimeObject.d.ts +11 -0
- package/build/types/TimeObject.js +4 -0
- package/build/types/UnitOfTime.cjs +7 -0
- package/build/types/UnitOfTime.d.cts +14 -0
- package/build/types/UnitOfTime.d.ts +14 -0
- package/build/types/UnitOfTime.js +4 -0
- package/package.json +145 -0
|
@@ -0,0 +1,2920 @@
|
|
|
1
|
+
import { AsymmetricEncryption } from './chunk-BKCT2HSQ.js';
|
|
2
|
+
import { As } from './chunk-XO6M5AYN.js';
|
|
3
|
+
import { init_esm_shims, __export, __name } from './chunk-5NK7E2HA.js';
|
|
4
|
+
|
|
5
|
+
// src/lib/crypto/SM2.ts
|
|
6
|
+
init_esm_shims();
|
|
7
|
+
|
|
8
|
+
// node_modules/sm-crypto-v2/dist/index.mjs
|
|
9
|
+
init_esm_shims();
|
|
10
|
+
|
|
11
|
+
// node_modules/@noble/curves/esm/abstract/utils.js
|
|
12
|
+
var utils_exports = {};
|
|
13
|
+
__export(utils_exports, {
|
|
14
|
+
bitGet: () => bitGet,
|
|
15
|
+
bitLen: () => bitLen,
|
|
16
|
+
bitMask: () => bitMask,
|
|
17
|
+
bitSet: () => bitSet,
|
|
18
|
+
bytesToHex: () => bytesToHex,
|
|
19
|
+
bytesToNumberBE: () => bytesToNumberBE,
|
|
20
|
+
bytesToNumberLE: () => bytesToNumberLE,
|
|
21
|
+
concatBytes: () => concatBytes,
|
|
22
|
+
createHmacDrbg: () => createHmacDrbg,
|
|
23
|
+
ensureBytes: () => ensureBytes,
|
|
24
|
+
equalBytes: () => equalBytes,
|
|
25
|
+
hexToBytes: () => hexToBytes,
|
|
26
|
+
hexToNumber: () => hexToNumber,
|
|
27
|
+
numberToBytesBE: () => numberToBytesBE,
|
|
28
|
+
numberToBytesLE: () => numberToBytesLE,
|
|
29
|
+
numberToHexUnpadded: () => numberToHexUnpadded,
|
|
30
|
+
numberToVarBytesBE: () => numberToVarBytesBE,
|
|
31
|
+
utf8ToBytes: () => utf8ToBytes,
|
|
32
|
+
validateObject: () => validateObject
|
|
33
|
+
});
|
|
34
|
+
init_esm_shims();
|
|
35
|
+
var _0n = BigInt(0);
|
|
36
|
+
var _1n = BigInt(1);
|
|
37
|
+
var _2n = BigInt(2);
|
|
38
|
+
var u8a = /* @__PURE__ */ __name((a) => a instanceof Uint8Array, "u8a");
|
|
39
|
+
var hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, "0"));
|
|
40
|
+
function bytesToHex(bytes) {
|
|
41
|
+
if (!u8a(bytes))
|
|
42
|
+
throw new Error("Uint8Array expected");
|
|
43
|
+
let hex = "";
|
|
44
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
45
|
+
hex += hexes[bytes[i]];
|
|
46
|
+
}
|
|
47
|
+
return hex;
|
|
48
|
+
}
|
|
49
|
+
__name(bytesToHex, "bytesToHex");
|
|
50
|
+
function numberToHexUnpadded(num) {
|
|
51
|
+
const hex = num.toString(16);
|
|
52
|
+
return hex.length & 1 ? `0${hex}` : hex;
|
|
53
|
+
}
|
|
54
|
+
__name(numberToHexUnpadded, "numberToHexUnpadded");
|
|
55
|
+
function hexToNumber(hex) {
|
|
56
|
+
if (typeof hex !== "string")
|
|
57
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
58
|
+
return BigInt(hex === "" ? "0" : `0x${hex}`);
|
|
59
|
+
}
|
|
60
|
+
__name(hexToNumber, "hexToNumber");
|
|
61
|
+
function hexToBytes(hex) {
|
|
62
|
+
if (typeof hex !== "string")
|
|
63
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
64
|
+
const len = hex.length;
|
|
65
|
+
if (len % 2)
|
|
66
|
+
throw new Error("padded hex string expected, got unpadded hex of length " + len);
|
|
67
|
+
const array = new Uint8Array(len / 2);
|
|
68
|
+
for (let i = 0; i < array.length; i++) {
|
|
69
|
+
const j = i * 2;
|
|
70
|
+
const hexByte = hex.slice(j, j + 2);
|
|
71
|
+
const byte = Number.parseInt(hexByte, 16);
|
|
72
|
+
if (Number.isNaN(byte) || byte < 0)
|
|
73
|
+
throw new Error("Invalid byte sequence");
|
|
74
|
+
array[i] = byte;
|
|
75
|
+
}
|
|
76
|
+
return array;
|
|
77
|
+
}
|
|
78
|
+
__name(hexToBytes, "hexToBytes");
|
|
79
|
+
function bytesToNumberBE(bytes) {
|
|
80
|
+
return hexToNumber(bytesToHex(bytes));
|
|
81
|
+
}
|
|
82
|
+
__name(bytesToNumberBE, "bytesToNumberBE");
|
|
83
|
+
function bytesToNumberLE(bytes) {
|
|
84
|
+
if (!u8a(bytes))
|
|
85
|
+
throw new Error("Uint8Array expected");
|
|
86
|
+
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
|
87
|
+
}
|
|
88
|
+
__name(bytesToNumberLE, "bytesToNumberLE");
|
|
89
|
+
function numberToBytesBE(n, len) {
|
|
90
|
+
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
|
|
91
|
+
}
|
|
92
|
+
__name(numberToBytesBE, "numberToBytesBE");
|
|
93
|
+
function numberToBytesLE(n, len) {
|
|
94
|
+
return numberToBytesBE(n, len).reverse();
|
|
95
|
+
}
|
|
96
|
+
__name(numberToBytesLE, "numberToBytesLE");
|
|
97
|
+
function numberToVarBytesBE(n) {
|
|
98
|
+
return hexToBytes(numberToHexUnpadded(n));
|
|
99
|
+
}
|
|
100
|
+
__name(numberToVarBytesBE, "numberToVarBytesBE");
|
|
101
|
+
function ensureBytes(title, hex, expectedLength) {
|
|
102
|
+
let res;
|
|
103
|
+
if (typeof hex === "string") {
|
|
104
|
+
try {
|
|
105
|
+
res = hexToBytes(hex);
|
|
106
|
+
} catch (e) {
|
|
107
|
+
throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`);
|
|
108
|
+
}
|
|
109
|
+
} else if (u8a(hex)) {
|
|
110
|
+
res = Uint8Array.from(hex);
|
|
111
|
+
} else {
|
|
112
|
+
throw new Error(`${title} must be hex string or Uint8Array`);
|
|
113
|
+
}
|
|
114
|
+
const len = res.length;
|
|
115
|
+
if (typeof expectedLength === "number" && len !== expectedLength)
|
|
116
|
+
throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
|
|
117
|
+
return res;
|
|
118
|
+
}
|
|
119
|
+
__name(ensureBytes, "ensureBytes");
|
|
120
|
+
function concatBytes(...arrays) {
|
|
121
|
+
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
|
|
122
|
+
let pad = 0;
|
|
123
|
+
arrays.forEach((a) => {
|
|
124
|
+
if (!u8a(a))
|
|
125
|
+
throw new Error("Uint8Array expected");
|
|
126
|
+
r.set(a, pad);
|
|
127
|
+
pad += a.length;
|
|
128
|
+
});
|
|
129
|
+
return r;
|
|
130
|
+
}
|
|
131
|
+
__name(concatBytes, "concatBytes");
|
|
132
|
+
function equalBytes(b1, b2) {
|
|
133
|
+
if (b1.length !== b2.length)
|
|
134
|
+
return false;
|
|
135
|
+
for (let i = 0; i < b1.length; i++)
|
|
136
|
+
if (b1[i] !== b2[i])
|
|
137
|
+
return false;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
__name(equalBytes, "equalBytes");
|
|
141
|
+
function utf8ToBytes(str) {
|
|
142
|
+
if (typeof str !== "string")
|
|
143
|
+
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
|
144
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
145
|
+
}
|
|
146
|
+
__name(utf8ToBytes, "utf8ToBytes");
|
|
147
|
+
function bitLen(n) {
|
|
148
|
+
let len;
|
|
149
|
+
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
150
|
+
;
|
|
151
|
+
return len;
|
|
152
|
+
}
|
|
153
|
+
__name(bitLen, "bitLen");
|
|
154
|
+
function bitGet(n, pos) {
|
|
155
|
+
return n >> BigInt(pos) & _1n;
|
|
156
|
+
}
|
|
157
|
+
__name(bitGet, "bitGet");
|
|
158
|
+
var bitSet = /* @__PURE__ */ __name((n, pos, value) => {
|
|
159
|
+
return n | (value ? _1n : _0n) << BigInt(pos);
|
|
160
|
+
}, "bitSet");
|
|
161
|
+
var bitMask = /* @__PURE__ */ __name((n) => (_2n << BigInt(n - 1)) - _1n, "bitMask");
|
|
162
|
+
var u8n = /* @__PURE__ */ __name((data) => new Uint8Array(data), "u8n");
|
|
163
|
+
var u8fr = /* @__PURE__ */ __name((arr) => Uint8Array.from(arr), "u8fr");
|
|
164
|
+
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
165
|
+
if (typeof hashLen !== "number" || hashLen < 2)
|
|
166
|
+
throw new Error("hashLen must be a number");
|
|
167
|
+
if (typeof qByteLen !== "number" || qByteLen < 2)
|
|
168
|
+
throw new Error("qByteLen must be a number");
|
|
169
|
+
if (typeof hmacFn !== "function")
|
|
170
|
+
throw new Error("hmacFn must be a function");
|
|
171
|
+
let v = u8n(hashLen);
|
|
172
|
+
let k = u8n(hashLen);
|
|
173
|
+
let i = 0;
|
|
174
|
+
const reset = /* @__PURE__ */ __name(() => {
|
|
175
|
+
v.fill(1);
|
|
176
|
+
k.fill(0);
|
|
177
|
+
i = 0;
|
|
178
|
+
}, "reset");
|
|
179
|
+
const h = /* @__PURE__ */ __name((...b) => hmacFn(k, v, ...b), "h");
|
|
180
|
+
const reseed = /* @__PURE__ */ __name((seed = u8n()) => {
|
|
181
|
+
k = h(u8fr([0]), seed);
|
|
182
|
+
v = h();
|
|
183
|
+
if (seed.length === 0)
|
|
184
|
+
return;
|
|
185
|
+
k = h(u8fr([1]), seed);
|
|
186
|
+
v = h();
|
|
187
|
+
}, "reseed");
|
|
188
|
+
const gen = /* @__PURE__ */ __name(() => {
|
|
189
|
+
if (i++ >= 1e3)
|
|
190
|
+
throw new Error("drbg: tried 1000 values");
|
|
191
|
+
let len = 0;
|
|
192
|
+
const out = [];
|
|
193
|
+
while (len < qByteLen) {
|
|
194
|
+
v = h();
|
|
195
|
+
const sl = v.slice();
|
|
196
|
+
out.push(sl);
|
|
197
|
+
len += v.length;
|
|
198
|
+
}
|
|
199
|
+
return concatBytes(...out);
|
|
200
|
+
}, "gen");
|
|
201
|
+
const genUntil = /* @__PURE__ */ __name((seed, pred) => {
|
|
202
|
+
reset();
|
|
203
|
+
reseed(seed);
|
|
204
|
+
let res = void 0;
|
|
205
|
+
while (!(res = pred(gen())))
|
|
206
|
+
reseed();
|
|
207
|
+
reset();
|
|
208
|
+
return res;
|
|
209
|
+
}, "genUntil");
|
|
210
|
+
return genUntil;
|
|
211
|
+
}
|
|
212
|
+
__name(createHmacDrbg, "createHmacDrbg");
|
|
213
|
+
var validatorFns = {
|
|
214
|
+
bigint: (val) => typeof val === "bigint",
|
|
215
|
+
function: (val) => typeof val === "function",
|
|
216
|
+
boolean: (val) => typeof val === "boolean",
|
|
217
|
+
string: (val) => typeof val === "string",
|
|
218
|
+
isSafeInteger: (val) => Number.isSafeInteger(val),
|
|
219
|
+
array: (val) => Array.isArray(val),
|
|
220
|
+
field: (val, object) => object.Fp.isValid(val),
|
|
221
|
+
hash: (val) => typeof val === "function" && Number.isSafeInteger(val.outputLen)
|
|
222
|
+
};
|
|
223
|
+
function validateObject(object, validators, optValidators = {}) {
|
|
224
|
+
const checkField = /* @__PURE__ */ __name((fieldName, type, isOptional) => {
|
|
225
|
+
const checkVal = validatorFns[type];
|
|
226
|
+
if (typeof checkVal !== "function")
|
|
227
|
+
throw new Error(`Invalid validator "${type}", expected function`);
|
|
228
|
+
const val = object[fieldName];
|
|
229
|
+
if (isOptional && val === void 0)
|
|
230
|
+
return;
|
|
231
|
+
if (!checkVal(val, object)) {
|
|
232
|
+
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
|
|
233
|
+
}
|
|
234
|
+
}, "checkField");
|
|
235
|
+
for (const [fieldName, type] of Object.entries(validators))
|
|
236
|
+
checkField(fieldName, type, false);
|
|
237
|
+
for (const [fieldName, type] of Object.entries(optValidators))
|
|
238
|
+
checkField(fieldName, type, true);
|
|
239
|
+
return object;
|
|
240
|
+
}
|
|
241
|
+
__name(validateObject, "validateObject");
|
|
242
|
+
|
|
243
|
+
// node_modules/@noble/curves/esm/abstract/weierstrass.js
|
|
244
|
+
init_esm_shims();
|
|
245
|
+
|
|
246
|
+
// node_modules/@noble/curves/esm/abstract/modular.js
|
|
247
|
+
init_esm_shims();
|
|
248
|
+
var _0n2 = BigInt(0);
|
|
249
|
+
var _1n2 = BigInt(1);
|
|
250
|
+
var _2n2 = BigInt(2);
|
|
251
|
+
var _3n = BigInt(3);
|
|
252
|
+
var _4n = BigInt(4);
|
|
253
|
+
var _5n = BigInt(5);
|
|
254
|
+
var _8n = BigInt(8);
|
|
255
|
+
BigInt(9);
|
|
256
|
+
BigInt(16);
|
|
257
|
+
function mod(a, b) {
|
|
258
|
+
const result = a % b;
|
|
259
|
+
return result >= _0n2 ? result : b + result;
|
|
260
|
+
}
|
|
261
|
+
__name(mod, "mod");
|
|
262
|
+
function pow(num, power, modulo) {
|
|
263
|
+
if (modulo <= _0n2 || power < _0n2)
|
|
264
|
+
throw new Error("Expected power/modulo > 0");
|
|
265
|
+
if (modulo === _1n2)
|
|
266
|
+
return _0n2;
|
|
267
|
+
let res = _1n2;
|
|
268
|
+
while (power > _0n2) {
|
|
269
|
+
if (power & _1n2)
|
|
270
|
+
res = res * num % modulo;
|
|
271
|
+
num = num * num % modulo;
|
|
272
|
+
power >>= _1n2;
|
|
273
|
+
}
|
|
274
|
+
return res;
|
|
275
|
+
}
|
|
276
|
+
__name(pow, "pow");
|
|
277
|
+
function invert(number, modulo) {
|
|
278
|
+
if (number === _0n2 || modulo <= _0n2) {
|
|
279
|
+
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
280
|
+
}
|
|
281
|
+
let a = mod(number, modulo);
|
|
282
|
+
let b = modulo;
|
|
283
|
+
let x2 = _0n2, u = _1n2;
|
|
284
|
+
while (a !== _0n2) {
|
|
285
|
+
const q = b / a;
|
|
286
|
+
const r = b % a;
|
|
287
|
+
const m = x2 - u * q;
|
|
288
|
+
b = a, a = r, x2 = u, u = m;
|
|
289
|
+
}
|
|
290
|
+
const gcd = b;
|
|
291
|
+
if (gcd !== _1n2)
|
|
292
|
+
throw new Error("invert: does not exist");
|
|
293
|
+
return mod(x2, modulo);
|
|
294
|
+
}
|
|
295
|
+
__name(invert, "invert");
|
|
296
|
+
function tonelliShanks(P) {
|
|
297
|
+
const legendreC = (P - _1n2) / _2n2;
|
|
298
|
+
let Q, S, Z;
|
|
299
|
+
for (Q = P - _1n2, S = 0; Q % _2n2 === _0n2; Q /= _2n2, S++)
|
|
300
|
+
;
|
|
301
|
+
for (Z = _2n2; Z < P && pow(Z, legendreC, P) !== P - _1n2; Z++)
|
|
302
|
+
;
|
|
303
|
+
if (S === 1) {
|
|
304
|
+
const p1div4 = (P + _1n2) / _4n;
|
|
305
|
+
return /* @__PURE__ */ __name(function tonelliFast(Fp, n) {
|
|
306
|
+
const root = Fp.pow(n, p1div4);
|
|
307
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
308
|
+
throw new Error("Cannot find square root");
|
|
309
|
+
return root;
|
|
310
|
+
}, "tonelliFast");
|
|
311
|
+
}
|
|
312
|
+
const Q1div2 = (Q + _1n2) / _2n2;
|
|
313
|
+
return /* @__PURE__ */ __name(function tonelliSlow(Fp, n) {
|
|
314
|
+
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))
|
|
315
|
+
throw new Error("Cannot find square root");
|
|
316
|
+
let r = S;
|
|
317
|
+
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q);
|
|
318
|
+
let x2 = Fp.pow(n, Q1div2);
|
|
319
|
+
let b = Fp.pow(n, Q);
|
|
320
|
+
while (!Fp.eql(b, Fp.ONE)) {
|
|
321
|
+
if (Fp.eql(b, Fp.ZERO))
|
|
322
|
+
return Fp.ZERO;
|
|
323
|
+
let m = 1;
|
|
324
|
+
for (let t2 = Fp.sqr(b); m < r; m++) {
|
|
325
|
+
if (Fp.eql(t2, Fp.ONE))
|
|
326
|
+
break;
|
|
327
|
+
t2 = Fp.sqr(t2);
|
|
328
|
+
}
|
|
329
|
+
const ge = Fp.pow(g, _1n2 << BigInt(r - m - 1));
|
|
330
|
+
g = Fp.sqr(ge);
|
|
331
|
+
x2 = Fp.mul(x2, ge);
|
|
332
|
+
b = Fp.mul(b, g);
|
|
333
|
+
r = m;
|
|
334
|
+
}
|
|
335
|
+
return x2;
|
|
336
|
+
}, "tonelliSlow");
|
|
337
|
+
}
|
|
338
|
+
__name(tonelliShanks, "tonelliShanks");
|
|
339
|
+
function FpSqrt(P) {
|
|
340
|
+
if (P % _4n === _3n) {
|
|
341
|
+
const p1div4 = (P + _1n2) / _4n;
|
|
342
|
+
return /* @__PURE__ */ __name(function sqrt3mod4(Fp, n) {
|
|
343
|
+
const root = Fp.pow(n, p1div4);
|
|
344
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
345
|
+
throw new Error("Cannot find square root");
|
|
346
|
+
return root;
|
|
347
|
+
}, "sqrt3mod4");
|
|
348
|
+
}
|
|
349
|
+
if (P % _8n === _5n) {
|
|
350
|
+
const c1 = (P - _5n) / _8n;
|
|
351
|
+
return /* @__PURE__ */ __name(function sqrt5mod8(Fp, n) {
|
|
352
|
+
const n2 = Fp.mul(n, _2n2);
|
|
353
|
+
const v = Fp.pow(n2, c1);
|
|
354
|
+
const nv = Fp.mul(n, v);
|
|
355
|
+
const i = Fp.mul(Fp.mul(nv, _2n2), v);
|
|
356
|
+
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
357
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
358
|
+
throw new Error("Cannot find square root");
|
|
359
|
+
return root;
|
|
360
|
+
}, "sqrt5mod8");
|
|
361
|
+
}
|
|
362
|
+
return tonelliShanks(P);
|
|
363
|
+
}
|
|
364
|
+
__name(FpSqrt, "FpSqrt");
|
|
365
|
+
var FIELD_FIELDS = [
|
|
366
|
+
"create",
|
|
367
|
+
"isValid",
|
|
368
|
+
"is0",
|
|
369
|
+
"neg",
|
|
370
|
+
"inv",
|
|
371
|
+
"sqrt",
|
|
372
|
+
"sqr",
|
|
373
|
+
"eql",
|
|
374
|
+
"add",
|
|
375
|
+
"sub",
|
|
376
|
+
"mul",
|
|
377
|
+
"pow",
|
|
378
|
+
"div",
|
|
379
|
+
"addN",
|
|
380
|
+
"subN",
|
|
381
|
+
"mulN",
|
|
382
|
+
"sqrN"
|
|
383
|
+
];
|
|
384
|
+
function validateField(field2) {
|
|
385
|
+
const initial = {
|
|
386
|
+
ORDER: "bigint",
|
|
387
|
+
MASK: "bigint",
|
|
388
|
+
BYTES: "isSafeInteger",
|
|
389
|
+
BITS: "isSafeInteger"
|
|
390
|
+
};
|
|
391
|
+
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
392
|
+
map[val] = "function";
|
|
393
|
+
return map;
|
|
394
|
+
}, initial);
|
|
395
|
+
return validateObject(field2, opts);
|
|
396
|
+
}
|
|
397
|
+
__name(validateField, "validateField");
|
|
398
|
+
function FpPow(f, num, power) {
|
|
399
|
+
if (power < _0n2)
|
|
400
|
+
throw new Error("Expected power > 0");
|
|
401
|
+
if (power === _0n2)
|
|
402
|
+
return f.ONE;
|
|
403
|
+
if (power === _1n2)
|
|
404
|
+
return num;
|
|
405
|
+
let p = f.ONE;
|
|
406
|
+
let d = num;
|
|
407
|
+
while (power > _0n2) {
|
|
408
|
+
if (power & _1n2)
|
|
409
|
+
p = f.mul(p, d);
|
|
410
|
+
d = f.sqr(d);
|
|
411
|
+
power >>= _1n2;
|
|
412
|
+
}
|
|
413
|
+
return p;
|
|
414
|
+
}
|
|
415
|
+
__name(FpPow, "FpPow");
|
|
416
|
+
function FpInvertBatch(f, nums) {
|
|
417
|
+
const tmp2 = new Array(nums.length);
|
|
418
|
+
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
419
|
+
if (f.is0(num))
|
|
420
|
+
return acc;
|
|
421
|
+
tmp2[i] = acc;
|
|
422
|
+
return f.mul(acc, num);
|
|
423
|
+
}, f.ONE);
|
|
424
|
+
const inverted = f.inv(lastMultiplied);
|
|
425
|
+
nums.reduceRight((acc, num, i) => {
|
|
426
|
+
if (f.is0(num))
|
|
427
|
+
return acc;
|
|
428
|
+
tmp2[i] = f.mul(acc, tmp2[i]);
|
|
429
|
+
return f.mul(acc, num);
|
|
430
|
+
}, inverted);
|
|
431
|
+
return tmp2;
|
|
432
|
+
}
|
|
433
|
+
__name(FpInvertBatch, "FpInvertBatch");
|
|
434
|
+
function nLength(n, nBitLength) {
|
|
435
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length;
|
|
436
|
+
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
437
|
+
return { nBitLength: _nBitLength, nByteLength };
|
|
438
|
+
}
|
|
439
|
+
__name(nLength, "nLength");
|
|
440
|
+
function Field(ORDER, bitLen2, isLE2 = false, redef = {}) {
|
|
441
|
+
if (ORDER <= _0n2)
|
|
442
|
+
throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
|
443
|
+
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen2);
|
|
444
|
+
if (BYTES > 2048)
|
|
445
|
+
throw new Error("Field lengths over 2048 bytes are not supported");
|
|
446
|
+
const sqrtP = FpSqrt(ORDER);
|
|
447
|
+
const f = Object.freeze({
|
|
448
|
+
ORDER,
|
|
449
|
+
BITS,
|
|
450
|
+
BYTES,
|
|
451
|
+
MASK: bitMask(BITS),
|
|
452
|
+
ZERO: _0n2,
|
|
453
|
+
ONE: _1n2,
|
|
454
|
+
create: (num) => mod(num, ORDER),
|
|
455
|
+
isValid: (num) => {
|
|
456
|
+
if (typeof num !== "bigint")
|
|
457
|
+
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
|
458
|
+
return _0n2 <= num && num < ORDER;
|
|
459
|
+
},
|
|
460
|
+
is0: (num) => num === _0n2,
|
|
461
|
+
isOdd: (num) => (num & _1n2) === _1n2,
|
|
462
|
+
neg: (num) => mod(-num, ORDER),
|
|
463
|
+
eql: (lhs, rhs) => lhs === rhs,
|
|
464
|
+
sqr: (num) => mod(num * num, ORDER),
|
|
465
|
+
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
|
466
|
+
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
|
467
|
+
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
|
468
|
+
pow: (num, power) => FpPow(f, num, power),
|
|
469
|
+
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
|
470
|
+
// Same as above, but doesn't normalize
|
|
471
|
+
sqrN: (num) => num * num,
|
|
472
|
+
addN: (lhs, rhs) => lhs + rhs,
|
|
473
|
+
subN: (lhs, rhs) => lhs - rhs,
|
|
474
|
+
mulN: (lhs, rhs) => lhs * rhs,
|
|
475
|
+
inv: (num) => invert(num, ORDER),
|
|
476
|
+
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
|
|
477
|
+
invertBatch: (lst) => FpInvertBatch(f, lst),
|
|
478
|
+
// TODO: do we really need constant cmov?
|
|
479
|
+
// We don't have const-time bigints anyway, so probably will be not very useful
|
|
480
|
+
cmov: (a, b, c) => c ? b : a,
|
|
481
|
+
toBytes: (num) => isLE2 ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES),
|
|
482
|
+
fromBytes: (bytes) => {
|
|
483
|
+
if (bytes.length !== BYTES)
|
|
484
|
+
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
|
485
|
+
return isLE2 ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
return Object.freeze(f);
|
|
489
|
+
}
|
|
490
|
+
__name(Field, "Field");
|
|
491
|
+
function hashToPrivateScalar(hash, groupOrder, isLE2 = false) {
|
|
492
|
+
hash = ensureBytes("privateHash", hash);
|
|
493
|
+
const hashLen = hash.length;
|
|
494
|
+
const minLen = nLength(groupOrder).nByteLength + 8;
|
|
495
|
+
if (minLen < 24 || hashLen < minLen || hashLen > 1024)
|
|
496
|
+
throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);
|
|
497
|
+
const num = isLE2 ? bytesToNumberLE(hash) : bytesToNumberBE(hash);
|
|
498
|
+
return mod(num, groupOrder - _1n2) + _1n2;
|
|
499
|
+
}
|
|
500
|
+
__name(hashToPrivateScalar, "hashToPrivateScalar");
|
|
501
|
+
|
|
502
|
+
// node_modules/@noble/curves/esm/abstract/curve.js
|
|
503
|
+
init_esm_shims();
|
|
504
|
+
var _0n3 = BigInt(0);
|
|
505
|
+
var _1n3 = BigInt(1);
|
|
506
|
+
function wNAF(c, bits) {
|
|
507
|
+
const constTimeNegate = /* @__PURE__ */ __name((condition, item) => {
|
|
508
|
+
const neg = item.negate();
|
|
509
|
+
return condition ? neg : item;
|
|
510
|
+
}, "constTimeNegate");
|
|
511
|
+
const opts = /* @__PURE__ */ __name((W) => {
|
|
512
|
+
const windows = Math.ceil(bits / W) + 1;
|
|
513
|
+
const windowSize = 2 ** (W - 1);
|
|
514
|
+
return { windows, windowSize };
|
|
515
|
+
}, "opts");
|
|
516
|
+
return {
|
|
517
|
+
constTimeNegate,
|
|
518
|
+
// non-const time multiplication ladder
|
|
519
|
+
unsafeLadder(elm, n) {
|
|
520
|
+
let p = c.ZERO;
|
|
521
|
+
let d = elm;
|
|
522
|
+
while (n > _0n3) {
|
|
523
|
+
if (n & _1n3)
|
|
524
|
+
p = p.add(d);
|
|
525
|
+
d = d.double();
|
|
526
|
+
n >>= _1n3;
|
|
527
|
+
}
|
|
528
|
+
return p;
|
|
529
|
+
},
|
|
530
|
+
/**
|
|
531
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
532
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
533
|
+
* Number of precomputed points depends on the curve size:
|
|
534
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
535
|
+
* - 𝑊 is the window size
|
|
536
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
537
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
538
|
+
* @returns precomputed point tables flattened to a single array
|
|
539
|
+
*/
|
|
540
|
+
precomputeWindow(elm, W) {
|
|
541
|
+
const { windows, windowSize } = opts(W);
|
|
542
|
+
const points = [];
|
|
543
|
+
let p = elm;
|
|
544
|
+
let base = p;
|
|
545
|
+
for (let window = 0; window < windows; window++) {
|
|
546
|
+
base = p;
|
|
547
|
+
points.push(base);
|
|
548
|
+
for (let i = 1; i < windowSize; i++) {
|
|
549
|
+
base = base.add(p);
|
|
550
|
+
points.push(base);
|
|
551
|
+
}
|
|
552
|
+
p = base.double();
|
|
553
|
+
}
|
|
554
|
+
return points;
|
|
555
|
+
},
|
|
556
|
+
/**
|
|
557
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
558
|
+
* @param W window size
|
|
559
|
+
* @param precomputes precomputed tables
|
|
560
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
|
561
|
+
* @returns real and fake (for const-time) points
|
|
562
|
+
*/
|
|
563
|
+
wNAF(W, precomputes, n) {
|
|
564
|
+
const { windows, windowSize } = opts(W);
|
|
565
|
+
let p = c.ZERO;
|
|
566
|
+
let f = c.BASE;
|
|
567
|
+
const mask = BigInt(2 ** W - 1);
|
|
568
|
+
const maxNumber = 2 ** W;
|
|
569
|
+
const shiftBy = BigInt(W);
|
|
570
|
+
for (let window = 0; window < windows; window++) {
|
|
571
|
+
const offset = window * windowSize;
|
|
572
|
+
let wbits = Number(n & mask);
|
|
573
|
+
n >>= shiftBy;
|
|
574
|
+
if (wbits > windowSize) {
|
|
575
|
+
wbits -= maxNumber;
|
|
576
|
+
n += _1n3;
|
|
577
|
+
}
|
|
578
|
+
const offset1 = offset;
|
|
579
|
+
const offset2 = offset + Math.abs(wbits) - 1;
|
|
580
|
+
const cond1 = window % 2 !== 0;
|
|
581
|
+
const cond2 = wbits < 0;
|
|
582
|
+
if (wbits === 0) {
|
|
583
|
+
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
|
584
|
+
} else {
|
|
585
|
+
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return { p, f };
|
|
589
|
+
},
|
|
590
|
+
wNAFCached(P, precomputesMap, n, transform) {
|
|
591
|
+
const W = P._WINDOW_SIZE || 1;
|
|
592
|
+
let comp = precomputesMap.get(P);
|
|
593
|
+
if (!comp) {
|
|
594
|
+
comp = this.precomputeWindow(P, W);
|
|
595
|
+
if (W !== 1) {
|
|
596
|
+
precomputesMap.set(P, transform(comp));
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return this.wNAF(W, comp, n);
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
__name(wNAF, "wNAF");
|
|
604
|
+
function validateBasic(curve) {
|
|
605
|
+
validateField(curve.Fp);
|
|
606
|
+
validateObject(curve, {
|
|
607
|
+
n: "bigint",
|
|
608
|
+
h: "bigint",
|
|
609
|
+
Gx: "field",
|
|
610
|
+
Gy: "field"
|
|
611
|
+
}, {
|
|
612
|
+
nBitLength: "isSafeInteger",
|
|
613
|
+
nByteLength: "isSafeInteger"
|
|
614
|
+
});
|
|
615
|
+
return Object.freeze({
|
|
616
|
+
...nLength(curve.n, curve.nBitLength),
|
|
617
|
+
...curve,
|
|
618
|
+
...{ p: curve.Fp.ORDER }
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
__name(validateBasic, "validateBasic");
|
|
622
|
+
|
|
623
|
+
// node_modules/@noble/curves/esm/abstract/weierstrass.js
|
|
624
|
+
function validatePointOpts(curve) {
|
|
625
|
+
const opts = validateBasic(curve);
|
|
626
|
+
validateObject(opts, {
|
|
627
|
+
a: "field",
|
|
628
|
+
b: "field"
|
|
629
|
+
}, {
|
|
630
|
+
allowedPrivateKeyLengths: "array",
|
|
631
|
+
wrapPrivateKey: "boolean",
|
|
632
|
+
isTorsionFree: "function",
|
|
633
|
+
clearCofactor: "function",
|
|
634
|
+
allowInfinityPoint: "boolean",
|
|
635
|
+
fromBytes: "function",
|
|
636
|
+
toBytes: "function"
|
|
637
|
+
});
|
|
638
|
+
const { endo, Fp, a } = opts;
|
|
639
|
+
if (endo) {
|
|
640
|
+
if (!Fp.eql(a, Fp.ZERO)) {
|
|
641
|
+
throw new Error("Endomorphism can only be defined for Koblitz curves that have a=0");
|
|
642
|
+
}
|
|
643
|
+
if (typeof endo !== "object" || typeof endo.beta !== "bigint" || typeof endo.splitScalar !== "function") {
|
|
644
|
+
throw new Error("Expected endomorphism with beta: bigint and splitScalar: function");
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return Object.freeze({ ...opts });
|
|
648
|
+
}
|
|
649
|
+
__name(validatePointOpts, "validatePointOpts");
|
|
650
|
+
var { bytesToNumberBE: b2n, hexToBytes: h2b } = utils_exports;
|
|
651
|
+
var _a;
|
|
652
|
+
var DER = {
|
|
653
|
+
// asn.1 DER encoding utils
|
|
654
|
+
Err: (_a = class extends Error {
|
|
655
|
+
constructor(m = "") {
|
|
656
|
+
super(m);
|
|
657
|
+
}
|
|
658
|
+
}, __name(_a, "DERErr"), _a),
|
|
659
|
+
_parseInt(data) {
|
|
660
|
+
const { Err: E } = DER;
|
|
661
|
+
if (data.length < 2 || data[0] !== 2)
|
|
662
|
+
throw new E("Invalid signature integer tag");
|
|
663
|
+
const len = data[1];
|
|
664
|
+
const res = data.subarray(2, len + 2);
|
|
665
|
+
if (!len || res.length !== len)
|
|
666
|
+
throw new E("Invalid signature integer: wrong length");
|
|
667
|
+
if (res[0] & 128)
|
|
668
|
+
throw new E("Invalid signature integer: negative");
|
|
669
|
+
if (res[0] === 0 && !(res[1] & 128))
|
|
670
|
+
throw new E("Invalid signature integer: unnecessary leading zero");
|
|
671
|
+
return { d: b2n(res), l: data.subarray(len + 2) };
|
|
672
|
+
},
|
|
673
|
+
toSig(hex) {
|
|
674
|
+
const { Err: E } = DER;
|
|
675
|
+
const data = typeof hex === "string" ? h2b(hex) : hex;
|
|
676
|
+
if (!(data instanceof Uint8Array))
|
|
677
|
+
throw new Error("ui8a expected");
|
|
678
|
+
let l = data.length;
|
|
679
|
+
if (l < 2 || data[0] != 48)
|
|
680
|
+
throw new E("Invalid signature tag");
|
|
681
|
+
if (data[1] !== l - 2)
|
|
682
|
+
throw new E("Invalid signature: incorrect length");
|
|
683
|
+
const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));
|
|
684
|
+
const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
|
|
685
|
+
if (rBytesLeft.length)
|
|
686
|
+
throw new E("Invalid signature: left bytes after parsing");
|
|
687
|
+
return { r, s };
|
|
688
|
+
},
|
|
689
|
+
hexFromSig(sig) {
|
|
690
|
+
const slice = /* @__PURE__ */ __name((s2) => Number.parseInt(s2[0], 16) & 8 ? "00" + s2 : s2, "slice");
|
|
691
|
+
const h = /* @__PURE__ */ __name((num) => {
|
|
692
|
+
const hex = num.toString(16);
|
|
693
|
+
return hex.length & 1 ? `0${hex}` : hex;
|
|
694
|
+
}, "h");
|
|
695
|
+
const s = slice(h(sig.s));
|
|
696
|
+
const r = slice(h(sig.r));
|
|
697
|
+
const shl = s.length / 2;
|
|
698
|
+
const rhl = r.length / 2;
|
|
699
|
+
const sl = h(shl);
|
|
700
|
+
const rl = h(rhl);
|
|
701
|
+
return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
var _0n4 = BigInt(0);
|
|
705
|
+
var _1n4 = BigInt(1);
|
|
706
|
+
BigInt(2);
|
|
707
|
+
var _3n2 = BigInt(3);
|
|
708
|
+
BigInt(4);
|
|
709
|
+
function weierstrassPoints(opts) {
|
|
710
|
+
const CURVE = validatePointOpts(opts);
|
|
711
|
+
const { Fp } = CURVE;
|
|
712
|
+
const toBytes2 = CURVE.toBytes || ((c, point, isCompressed) => {
|
|
713
|
+
const a = point.toAffine();
|
|
714
|
+
return concatBytes(Uint8Array.from([4]), Fp.toBytes(a.x), Fp.toBytes(a.y));
|
|
715
|
+
});
|
|
716
|
+
const fromBytes = CURVE.fromBytes || ((bytes) => {
|
|
717
|
+
const tail = bytes.subarray(1);
|
|
718
|
+
const x2 = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
|
719
|
+
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
|
720
|
+
return { x: x2, y };
|
|
721
|
+
});
|
|
722
|
+
function weierstrassEquation(x2) {
|
|
723
|
+
const { a, b } = CURVE;
|
|
724
|
+
const x22 = Fp.sqr(x2);
|
|
725
|
+
const x3 = Fp.mul(x22, x2);
|
|
726
|
+
return Fp.add(Fp.add(x3, Fp.mul(x2, a)), b);
|
|
727
|
+
}
|
|
728
|
+
__name(weierstrassEquation, "weierstrassEquation");
|
|
729
|
+
if (!Fp.eql(Fp.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx)))
|
|
730
|
+
throw new Error("bad generator point: equation left != right");
|
|
731
|
+
function isWithinCurveOrder(num) {
|
|
732
|
+
return typeof num === "bigint" && _0n4 < num && num < CURVE.n;
|
|
733
|
+
}
|
|
734
|
+
__name(isWithinCurveOrder, "isWithinCurveOrder");
|
|
735
|
+
function assertGE(num) {
|
|
736
|
+
if (!isWithinCurveOrder(num))
|
|
737
|
+
throw new Error("Expected valid bigint: 0 < bigint < curve.n");
|
|
738
|
+
}
|
|
739
|
+
__name(assertGE, "assertGE");
|
|
740
|
+
function normPrivateKeyToScalar(key) {
|
|
741
|
+
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
|
742
|
+
if (lengths && typeof key !== "bigint") {
|
|
743
|
+
if (key instanceof Uint8Array)
|
|
744
|
+
key = bytesToHex(key);
|
|
745
|
+
if (typeof key !== "string" || !lengths.includes(key.length))
|
|
746
|
+
throw new Error("Invalid key");
|
|
747
|
+
key = key.padStart(nByteLength * 2, "0");
|
|
748
|
+
}
|
|
749
|
+
let num;
|
|
750
|
+
try {
|
|
751
|
+
num = typeof key === "bigint" ? key : bytesToNumberBE(ensureBytes("private key", key, nByteLength));
|
|
752
|
+
} catch (error) {
|
|
753
|
+
throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
|
|
754
|
+
}
|
|
755
|
+
if (wrapPrivateKey)
|
|
756
|
+
num = mod(num, n);
|
|
757
|
+
assertGE(num);
|
|
758
|
+
return num;
|
|
759
|
+
}
|
|
760
|
+
__name(normPrivateKeyToScalar, "normPrivateKeyToScalar");
|
|
761
|
+
const pointPrecomputes = /* @__PURE__ */ new Map();
|
|
762
|
+
function assertPrjPoint(other) {
|
|
763
|
+
if (!(other instanceof Point))
|
|
764
|
+
throw new Error("ProjectivePoint expected");
|
|
765
|
+
}
|
|
766
|
+
__name(assertPrjPoint, "assertPrjPoint");
|
|
767
|
+
const _Point = class _Point {
|
|
768
|
+
constructor(px, py, pz) {
|
|
769
|
+
this.px = px;
|
|
770
|
+
this.py = py;
|
|
771
|
+
this.pz = pz;
|
|
772
|
+
if (px == null || !Fp.isValid(px))
|
|
773
|
+
throw new Error("x required");
|
|
774
|
+
if (py == null || !Fp.isValid(py))
|
|
775
|
+
throw new Error("y required");
|
|
776
|
+
if (pz == null || !Fp.isValid(pz))
|
|
777
|
+
throw new Error("z required");
|
|
778
|
+
}
|
|
779
|
+
// Does not validate if the point is on-curve.
|
|
780
|
+
// Use fromHex instead, or call assertValidity() later.
|
|
781
|
+
static fromAffine(p) {
|
|
782
|
+
const { x: x2, y } = p || {};
|
|
783
|
+
if (!p || !Fp.isValid(x2) || !Fp.isValid(y))
|
|
784
|
+
throw new Error("invalid affine point");
|
|
785
|
+
if (p instanceof _Point)
|
|
786
|
+
throw new Error("projective point not allowed");
|
|
787
|
+
const is0 = /* @__PURE__ */ __name((i) => Fp.eql(i, Fp.ZERO), "is0");
|
|
788
|
+
if (is0(x2) && is0(y))
|
|
789
|
+
return _Point.ZERO;
|
|
790
|
+
return new _Point(x2, y, Fp.ONE);
|
|
791
|
+
}
|
|
792
|
+
get x() {
|
|
793
|
+
return this.toAffine().x;
|
|
794
|
+
}
|
|
795
|
+
get y() {
|
|
796
|
+
return this.toAffine().y;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Takes a bunch of Projective Points but executes only one
|
|
800
|
+
* inversion on all of them. Inversion is very slow operation,
|
|
801
|
+
* so this improves performance massively.
|
|
802
|
+
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
|
803
|
+
*/
|
|
804
|
+
static normalizeZ(points) {
|
|
805
|
+
const toInv = Fp.invertBatch(points.map((p) => p.pz));
|
|
806
|
+
return points.map((p, i) => p.toAffine(toInv[i])).map(_Point.fromAffine);
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Converts hash string or Uint8Array to Point.
|
|
810
|
+
* @param hex short/long ECDSA hex
|
|
811
|
+
*/
|
|
812
|
+
static fromHex(hex) {
|
|
813
|
+
const P = _Point.fromAffine(fromBytes(ensureBytes("pointHex", hex)));
|
|
814
|
+
P.assertValidity();
|
|
815
|
+
return P;
|
|
816
|
+
}
|
|
817
|
+
// Multiplies generator point by privateKey.
|
|
818
|
+
static fromPrivateKey(privateKey) {
|
|
819
|
+
return _Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
|
820
|
+
}
|
|
821
|
+
// "Private method", don't use it directly
|
|
822
|
+
_setWindowSize(windowSize) {
|
|
823
|
+
this._WINDOW_SIZE = windowSize;
|
|
824
|
+
pointPrecomputes.delete(this);
|
|
825
|
+
}
|
|
826
|
+
// A point on curve is valid if it conforms to equation.
|
|
827
|
+
assertValidity() {
|
|
828
|
+
if (this.is0()) {
|
|
829
|
+
if (CURVE.allowInfinityPoint)
|
|
830
|
+
return;
|
|
831
|
+
throw new Error("bad point: ZERO");
|
|
832
|
+
}
|
|
833
|
+
const { x: x2, y } = this.toAffine();
|
|
834
|
+
if (!Fp.isValid(x2) || !Fp.isValid(y))
|
|
835
|
+
throw new Error("bad point: x or y not FE");
|
|
836
|
+
const left = Fp.sqr(y);
|
|
837
|
+
const right = weierstrassEquation(x2);
|
|
838
|
+
if (!Fp.eql(left, right))
|
|
839
|
+
throw new Error("bad point: equation left != right");
|
|
840
|
+
if (!this.isTorsionFree())
|
|
841
|
+
throw new Error("bad point: not in prime-order subgroup");
|
|
842
|
+
}
|
|
843
|
+
hasEvenY() {
|
|
844
|
+
const { y } = this.toAffine();
|
|
845
|
+
if (Fp.isOdd)
|
|
846
|
+
return !Fp.isOdd(y);
|
|
847
|
+
throw new Error("Field doesn't support isOdd");
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Compare one point to another.
|
|
851
|
+
*/
|
|
852
|
+
equals(other) {
|
|
853
|
+
assertPrjPoint(other);
|
|
854
|
+
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
855
|
+
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
856
|
+
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
|
857
|
+
const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
|
|
858
|
+
return U1 && U2;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Flips point to one corresponding to (x, -y) in Affine coordinates.
|
|
862
|
+
*/
|
|
863
|
+
negate() {
|
|
864
|
+
return new _Point(this.px, Fp.neg(this.py), this.pz);
|
|
865
|
+
}
|
|
866
|
+
// Renes-Costello-Batina exception-free doubling formula.
|
|
867
|
+
// There is 30% faster Jacobian formula, but it is not complete.
|
|
868
|
+
// https://eprint.iacr.org/2015/1060, algorithm 3
|
|
869
|
+
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
|
870
|
+
double() {
|
|
871
|
+
const { a, b } = CURVE;
|
|
872
|
+
const b3 = Fp.mul(b, _3n2);
|
|
873
|
+
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
874
|
+
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO;
|
|
875
|
+
let t0 = Fp.mul(X1, X1);
|
|
876
|
+
let t1 = Fp.mul(Y1, Y1);
|
|
877
|
+
let t2 = Fp.mul(Z1, Z1);
|
|
878
|
+
let t3 = Fp.mul(X1, Y1);
|
|
879
|
+
t3 = Fp.add(t3, t3);
|
|
880
|
+
Z3 = Fp.mul(X1, Z1);
|
|
881
|
+
Z3 = Fp.add(Z3, Z3);
|
|
882
|
+
X3 = Fp.mul(a, Z3);
|
|
883
|
+
Y3 = Fp.mul(b3, t2);
|
|
884
|
+
Y3 = Fp.add(X3, Y3);
|
|
885
|
+
X3 = Fp.sub(t1, Y3);
|
|
886
|
+
Y3 = Fp.add(t1, Y3);
|
|
887
|
+
Y3 = Fp.mul(X3, Y3);
|
|
888
|
+
X3 = Fp.mul(t3, X3);
|
|
889
|
+
Z3 = Fp.mul(b3, Z3);
|
|
890
|
+
t2 = Fp.mul(a, t2);
|
|
891
|
+
t3 = Fp.sub(t0, t2);
|
|
892
|
+
t3 = Fp.mul(a, t3);
|
|
893
|
+
t3 = Fp.add(t3, Z3);
|
|
894
|
+
Z3 = Fp.add(t0, t0);
|
|
895
|
+
t0 = Fp.add(Z3, t0);
|
|
896
|
+
t0 = Fp.add(t0, t2);
|
|
897
|
+
t0 = Fp.mul(t0, t3);
|
|
898
|
+
Y3 = Fp.add(Y3, t0);
|
|
899
|
+
t2 = Fp.mul(Y1, Z1);
|
|
900
|
+
t2 = Fp.add(t2, t2);
|
|
901
|
+
t0 = Fp.mul(t2, t3);
|
|
902
|
+
X3 = Fp.sub(X3, t0);
|
|
903
|
+
Z3 = Fp.mul(t2, t1);
|
|
904
|
+
Z3 = Fp.add(Z3, Z3);
|
|
905
|
+
Z3 = Fp.add(Z3, Z3);
|
|
906
|
+
return new _Point(X3, Y3, Z3);
|
|
907
|
+
}
|
|
908
|
+
// Renes-Costello-Batina exception-free addition formula.
|
|
909
|
+
// There is 30% faster Jacobian formula, but it is not complete.
|
|
910
|
+
// https://eprint.iacr.org/2015/1060, algorithm 1
|
|
911
|
+
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
|
912
|
+
add(other) {
|
|
913
|
+
assertPrjPoint(other);
|
|
914
|
+
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
915
|
+
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
916
|
+
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO;
|
|
917
|
+
const a = CURVE.a;
|
|
918
|
+
const b3 = Fp.mul(CURVE.b, _3n2);
|
|
919
|
+
let t0 = Fp.mul(X1, X2);
|
|
920
|
+
let t1 = Fp.mul(Y1, Y2);
|
|
921
|
+
let t2 = Fp.mul(Z1, Z2);
|
|
922
|
+
let t3 = Fp.add(X1, Y1);
|
|
923
|
+
let t4 = Fp.add(X2, Y2);
|
|
924
|
+
t3 = Fp.mul(t3, t4);
|
|
925
|
+
t4 = Fp.add(t0, t1);
|
|
926
|
+
t3 = Fp.sub(t3, t4);
|
|
927
|
+
t4 = Fp.add(X1, Z1);
|
|
928
|
+
let t5 = Fp.add(X2, Z2);
|
|
929
|
+
t4 = Fp.mul(t4, t5);
|
|
930
|
+
t5 = Fp.add(t0, t2);
|
|
931
|
+
t4 = Fp.sub(t4, t5);
|
|
932
|
+
t5 = Fp.add(Y1, Z1);
|
|
933
|
+
X3 = Fp.add(Y2, Z2);
|
|
934
|
+
t5 = Fp.mul(t5, X3);
|
|
935
|
+
X3 = Fp.add(t1, t2);
|
|
936
|
+
t5 = Fp.sub(t5, X3);
|
|
937
|
+
Z3 = Fp.mul(a, t4);
|
|
938
|
+
X3 = Fp.mul(b3, t2);
|
|
939
|
+
Z3 = Fp.add(X3, Z3);
|
|
940
|
+
X3 = Fp.sub(t1, Z3);
|
|
941
|
+
Z3 = Fp.add(t1, Z3);
|
|
942
|
+
Y3 = Fp.mul(X3, Z3);
|
|
943
|
+
t1 = Fp.add(t0, t0);
|
|
944
|
+
t1 = Fp.add(t1, t0);
|
|
945
|
+
t2 = Fp.mul(a, t2);
|
|
946
|
+
t4 = Fp.mul(b3, t4);
|
|
947
|
+
t1 = Fp.add(t1, t2);
|
|
948
|
+
t2 = Fp.sub(t0, t2);
|
|
949
|
+
t2 = Fp.mul(a, t2);
|
|
950
|
+
t4 = Fp.add(t4, t2);
|
|
951
|
+
t0 = Fp.mul(t1, t4);
|
|
952
|
+
Y3 = Fp.add(Y3, t0);
|
|
953
|
+
t0 = Fp.mul(t5, t4);
|
|
954
|
+
X3 = Fp.mul(t3, X3);
|
|
955
|
+
X3 = Fp.sub(X3, t0);
|
|
956
|
+
t0 = Fp.mul(t3, t1);
|
|
957
|
+
Z3 = Fp.mul(t5, Z3);
|
|
958
|
+
Z3 = Fp.add(Z3, t0);
|
|
959
|
+
return new _Point(X3, Y3, Z3);
|
|
960
|
+
}
|
|
961
|
+
subtract(other) {
|
|
962
|
+
return this.add(other.negate());
|
|
963
|
+
}
|
|
964
|
+
is0() {
|
|
965
|
+
return this.equals(_Point.ZERO);
|
|
966
|
+
}
|
|
967
|
+
wNAF(n) {
|
|
968
|
+
return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
|
|
969
|
+
const toInv = Fp.invertBatch(comp.map((p) => p.pz));
|
|
970
|
+
return comp.map((p, i) => p.toAffine(toInv[i])).map(_Point.fromAffine);
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
975
|
+
* It's faster, but should only be used when you don't care about
|
|
976
|
+
* an exposed private key e.g. sig verification, which works over *public* keys.
|
|
977
|
+
*/
|
|
978
|
+
multiplyUnsafe(n) {
|
|
979
|
+
const I = _Point.ZERO;
|
|
980
|
+
if (n === _0n4)
|
|
981
|
+
return I;
|
|
982
|
+
assertGE(n);
|
|
983
|
+
if (n === _1n4)
|
|
984
|
+
return this;
|
|
985
|
+
const { endo } = CURVE;
|
|
986
|
+
if (!endo)
|
|
987
|
+
return wnaf.unsafeLadder(this, n);
|
|
988
|
+
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
|
989
|
+
let k1p = I;
|
|
990
|
+
let k2p = I;
|
|
991
|
+
let d = this;
|
|
992
|
+
while (k1 > _0n4 || k2 > _0n4) {
|
|
993
|
+
if (k1 & _1n4)
|
|
994
|
+
k1p = k1p.add(d);
|
|
995
|
+
if (k2 & _1n4)
|
|
996
|
+
k2p = k2p.add(d);
|
|
997
|
+
d = d.double();
|
|
998
|
+
k1 >>= _1n4;
|
|
999
|
+
k2 >>= _1n4;
|
|
1000
|
+
}
|
|
1001
|
+
if (k1neg)
|
|
1002
|
+
k1p = k1p.negate();
|
|
1003
|
+
if (k2neg)
|
|
1004
|
+
k2p = k2p.negate();
|
|
1005
|
+
k2p = new _Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
|
|
1006
|
+
return k1p.add(k2p);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Constant time multiplication.
|
|
1010
|
+
* Uses wNAF method. Windowed method may be 10% faster,
|
|
1011
|
+
* but takes 2x longer to generate and consumes 2x memory.
|
|
1012
|
+
* Uses precomputes when available.
|
|
1013
|
+
* Uses endomorphism for Koblitz curves.
|
|
1014
|
+
* @param scalar by which the point would be multiplied
|
|
1015
|
+
* @returns New point
|
|
1016
|
+
*/
|
|
1017
|
+
multiply(scalar) {
|
|
1018
|
+
assertGE(scalar);
|
|
1019
|
+
let n = scalar;
|
|
1020
|
+
let point, fake;
|
|
1021
|
+
const { endo } = CURVE;
|
|
1022
|
+
if (endo) {
|
|
1023
|
+
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
|
1024
|
+
let { p: k1p, f: f1p } = this.wNAF(k1);
|
|
1025
|
+
let { p: k2p, f: f2p } = this.wNAF(k2);
|
|
1026
|
+
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
|
1027
|
+
k2p = wnaf.constTimeNegate(k2neg, k2p);
|
|
1028
|
+
k2p = new _Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
|
|
1029
|
+
point = k1p.add(k2p);
|
|
1030
|
+
fake = f1p.add(f2p);
|
|
1031
|
+
} else {
|
|
1032
|
+
const { p, f } = this.wNAF(n);
|
|
1033
|
+
point = p;
|
|
1034
|
+
fake = f;
|
|
1035
|
+
}
|
|
1036
|
+
return _Point.normalizeZ([point, fake])[0];
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Efficiently calculate `aP + bQ`. Unsafe, can expose private key, if used incorrectly.
|
|
1040
|
+
* Not using Strauss-Shamir trick: precomputation tables are faster.
|
|
1041
|
+
* The trick could be useful if both P and Q are not G (not in our case).
|
|
1042
|
+
* @returns non-zero affine point
|
|
1043
|
+
*/
|
|
1044
|
+
multiplyAndAddUnsafe(Q, a, b) {
|
|
1045
|
+
const G = _Point.BASE;
|
|
1046
|
+
const mul = /* @__PURE__ */ __name((P, a2) => a2 === _0n4 || a2 === _1n4 || !P.equals(G) ? P.multiplyUnsafe(a2) : P.multiply(a2), "mul");
|
|
1047
|
+
const sum = mul(this, a).add(mul(Q, b));
|
|
1048
|
+
return sum.is0() ? void 0 : sum;
|
|
1049
|
+
}
|
|
1050
|
+
// Converts Projective point to affine (x, y) coordinates.
|
|
1051
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
1052
|
+
// (x, y, z) ∋ (x=x/z, y=y/z)
|
|
1053
|
+
toAffine(iz) {
|
|
1054
|
+
const { px: x2, py: y, pz: z } = this;
|
|
1055
|
+
const is0 = this.is0();
|
|
1056
|
+
if (iz == null)
|
|
1057
|
+
iz = is0 ? Fp.ONE : Fp.inv(z);
|
|
1058
|
+
const ax = Fp.mul(x2, iz);
|
|
1059
|
+
const ay = Fp.mul(y, iz);
|
|
1060
|
+
const zz = Fp.mul(z, iz);
|
|
1061
|
+
if (is0)
|
|
1062
|
+
return { x: Fp.ZERO, y: Fp.ZERO };
|
|
1063
|
+
if (!Fp.eql(zz, Fp.ONE))
|
|
1064
|
+
throw new Error("invZ was invalid");
|
|
1065
|
+
return { x: ax, y: ay };
|
|
1066
|
+
}
|
|
1067
|
+
isTorsionFree() {
|
|
1068
|
+
const { h: cofactor, isTorsionFree } = CURVE;
|
|
1069
|
+
if (cofactor === _1n4)
|
|
1070
|
+
return true;
|
|
1071
|
+
if (isTorsionFree)
|
|
1072
|
+
return isTorsionFree(_Point, this);
|
|
1073
|
+
throw new Error("isTorsionFree() has not been declared for the elliptic curve");
|
|
1074
|
+
}
|
|
1075
|
+
clearCofactor() {
|
|
1076
|
+
const { h: cofactor, clearCofactor } = CURVE;
|
|
1077
|
+
if (cofactor === _1n4)
|
|
1078
|
+
return this;
|
|
1079
|
+
if (clearCofactor)
|
|
1080
|
+
return clearCofactor(_Point, this);
|
|
1081
|
+
return this.multiplyUnsafe(CURVE.h);
|
|
1082
|
+
}
|
|
1083
|
+
toRawBytes(isCompressed = true) {
|
|
1084
|
+
this.assertValidity();
|
|
1085
|
+
return toBytes2(_Point, this, isCompressed);
|
|
1086
|
+
}
|
|
1087
|
+
toHex(isCompressed = true) {
|
|
1088
|
+
return bytesToHex(this.toRawBytes(isCompressed));
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
__name(_Point, "Point");
|
|
1092
|
+
let Point = _Point;
|
|
1093
|
+
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
|
1094
|
+
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
|
1095
|
+
const _bits = CURVE.nBitLength;
|
|
1096
|
+
const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
|
1097
|
+
return {
|
|
1098
|
+
CURVE,
|
|
1099
|
+
ProjectivePoint: Point,
|
|
1100
|
+
normPrivateKeyToScalar,
|
|
1101
|
+
weierstrassEquation,
|
|
1102
|
+
isWithinCurveOrder
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
__name(weierstrassPoints, "weierstrassPoints");
|
|
1106
|
+
function validateOpts(curve) {
|
|
1107
|
+
const opts = validateBasic(curve);
|
|
1108
|
+
validateObject(opts, {
|
|
1109
|
+
hash: "hash",
|
|
1110
|
+
hmac: "function",
|
|
1111
|
+
randomBytes: "function"
|
|
1112
|
+
}, {
|
|
1113
|
+
bits2int: "function",
|
|
1114
|
+
bits2int_modN: "function",
|
|
1115
|
+
lowS: "boolean"
|
|
1116
|
+
});
|
|
1117
|
+
return Object.freeze({ lowS: true, ...opts });
|
|
1118
|
+
}
|
|
1119
|
+
__name(validateOpts, "validateOpts");
|
|
1120
|
+
function weierstrass(curveDef) {
|
|
1121
|
+
const CURVE = validateOpts(curveDef);
|
|
1122
|
+
const { Fp, n: CURVE_ORDER } = CURVE;
|
|
1123
|
+
const compressedLen = Fp.BYTES + 1;
|
|
1124
|
+
const uncompressedLen = 2 * Fp.BYTES + 1;
|
|
1125
|
+
function isValidFieldElement(num) {
|
|
1126
|
+
return _0n4 < num && num < Fp.ORDER;
|
|
1127
|
+
}
|
|
1128
|
+
__name(isValidFieldElement, "isValidFieldElement");
|
|
1129
|
+
function modN(a) {
|
|
1130
|
+
return mod(a, CURVE_ORDER);
|
|
1131
|
+
}
|
|
1132
|
+
__name(modN, "modN");
|
|
1133
|
+
function invN(a) {
|
|
1134
|
+
return invert(a, CURVE_ORDER);
|
|
1135
|
+
}
|
|
1136
|
+
__name(invN, "invN");
|
|
1137
|
+
const { ProjectivePoint: Point, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder } = weierstrassPoints({
|
|
1138
|
+
...CURVE,
|
|
1139
|
+
toBytes(c, point, isCompressed) {
|
|
1140
|
+
const a = point.toAffine();
|
|
1141
|
+
const x2 = Fp.toBytes(a.x);
|
|
1142
|
+
const cat = concatBytes;
|
|
1143
|
+
if (isCompressed) {
|
|
1144
|
+
return cat(Uint8Array.from([point.hasEvenY() ? 2 : 3]), x2);
|
|
1145
|
+
} else {
|
|
1146
|
+
return cat(Uint8Array.from([4]), x2, Fp.toBytes(a.y));
|
|
1147
|
+
}
|
|
1148
|
+
},
|
|
1149
|
+
fromBytes(bytes) {
|
|
1150
|
+
const len = bytes.length;
|
|
1151
|
+
const head = bytes[0];
|
|
1152
|
+
const tail = bytes.subarray(1);
|
|
1153
|
+
if (len === compressedLen && (head === 2 || head === 3)) {
|
|
1154
|
+
const x2 = bytesToNumberBE(tail);
|
|
1155
|
+
if (!isValidFieldElement(x2))
|
|
1156
|
+
throw new Error("Point is not on curve");
|
|
1157
|
+
const y2 = weierstrassEquation(x2);
|
|
1158
|
+
let y = Fp.sqrt(y2);
|
|
1159
|
+
const isYOdd = (y & _1n4) === _1n4;
|
|
1160
|
+
const isHeadOdd = (head & 1) === 1;
|
|
1161
|
+
if (isHeadOdd !== isYOdd)
|
|
1162
|
+
y = Fp.neg(y);
|
|
1163
|
+
return { x: x2, y };
|
|
1164
|
+
} else if (len === uncompressedLen && head === 4) {
|
|
1165
|
+
const x2 = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
|
1166
|
+
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
|
1167
|
+
return { x: x2, y };
|
|
1168
|
+
} else {
|
|
1169
|
+
throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
const numToNByteStr = /* @__PURE__ */ __name((num) => bytesToHex(numberToBytesBE(num, CURVE.nByteLength)), "numToNByteStr");
|
|
1174
|
+
function isBiggerThanHalfOrder(number) {
|
|
1175
|
+
const HALF = CURVE_ORDER >> _1n4;
|
|
1176
|
+
return number > HALF;
|
|
1177
|
+
}
|
|
1178
|
+
__name(isBiggerThanHalfOrder, "isBiggerThanHalfOrder");
|
|
1179
|
+
function normalizeS(s) {
|
|
1180
|
+
return isBiggerThanHalfOrder(s) ? modN(-s) : s;
|
|
1181
|
+
}
|
|
1182
|
+
__name(normalizeS, "normalizeS");
|
|
1183
|
+
const slcNum = /* @__PURE__ */ __name((b, from, to) => bytesToNumberBE(b.slice(from, to)), "slcNum");
|
|
1184
|
+
const _Signature = class _Signature {
|
|
1185
|
+
constructor(r, s, recovery) {
|
|
1186
|
+
this.r = r;
|
|
1187
|
+
this.s = s;
|
|
1188
|
+
this.recovery = recovery;
|
|
1189
|
+
this.assertValidity();
|
|
1190
|
+
}
|
|
1191
|
+
// pair (bytes of r, bytes of s)
|
|
1192
|
+
static fromCompact(hex) {
|
|
1193
|
+
const l = CURVE.nByteLength;
|
|
1194
|
+
hex = ensureBytes("compactSignature", hex, l * 2);
|
|
1195
|
+
return new _Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
|
|
1196
|
+
}
|
|
1197
|
+
// DER encoded ECDSA signature
|
|
1198
|
+
// https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
|
|
1199
|
+
static fromDER(hex) {
|
|
1200
|
+
const { r, s } = DER.toSig(ensureBytes("DER", hex));
|
|
1201
|
+
return new _Signature(r, s);
|
|
1202
|
+
}
|
|
1203
|
+
assertValidity() {
|
|
1204
|
+
if (!isWithinCurveOrder(this.r))
|
|
1205
|
+
throw new Error("r must be 0 < r < CURVE.n");
|
|
1206
|
+
if (!isWithinCurveOrder(this.s))
|
|
1207
|
+
throw new Error("s must be 0 < s < CURVE.n");
|
|
1208
|
+
}
|
|
1209
|
+
addRecoveryBit(recovery) {
|
|
1210
|
+
return new _Signature(this.r, this.s, recovery);
|
|
1211
|
+
}
|
|
1212
|
+
recoverPublicKey(msgHash) {
|
|
1213
|
+
const { r, s, recovery: rec } = this;
|
|
1214
|
+
const h = bits2int_modN(ensureBytes("msgHash", msgHash));
|
|
1215
|
+
if (rec == null || ![0, 1, 2, 3].includes(rec))
|
|
1216
|
+
throw new Error("recovery id invalid");
|
|
1217
|
+
const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
|
|
1218
|
+
if (radj >= Fp.ORDER)
|
|
1219
|
+
throw new Error("recovery id 2 or 3 invalid");
|
|
1220
|
+
const prefix = (rec & 1) === 0 ? "02" : "03";
|
|
1221
|
+
const R = Point.fromHex(prefix + numToNByteStr(radj));
|
|
1222
|
+
const ir = invN(radj);
|
|
1223
|
+
const u1 = modN(-h * ir);
|
|
1224
|
+
const u2 = modN(s * ir);
|
|
1225
|
+
const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2);
|
|
1226
|
+
if (!Q)
|
|
1227
|
+
throw new Error("point at infinify");
|
|
1228
|
+
Q.assertValidity();
|
|
1229
|
+
return Q;
|
|
1230
|
+
}
|
|
1231
|
+
// Signatures should be low-s, to prevent malleability.
|
|
1232
|
+
hasHighS() {
|
|
1233
|
+
return isBiggerThanHalfOrder(this.s);
|
|
1234
|
+
}
|
|
1235
|
+
normalizeS() {
|
|
1236
|
+
return this.hasHighS() ? new _Signature(this.r, modN(-this.s), this.recovery) : this;
|
|
1237
|
+
}
|
|
1238
|
+
// DER-encoded
|
|
1239
|
+
toDERRawBytes() {
|
|
1240
|
+
return hexToBytes(this.toDERHex());
|
|
1241
|
+
}
|
|
1242
|
+
toDERHex() {
|
|
1243
|
+
return DER.hexFromSig({ r: this.r, s: this.s });
|
|
1244
|
+
}
|
|
1245
|
+
// padded bytes of r, then padded bytes of s
|
|
1246
|
+
toCompactRawBytes() {
|
|
1247
|
+
return hexToBytes(this.toCompactHex());
|
|
1248
|
+
}
|
|
1249
|
+
toCompactHex() {
|
|
1250
|
+
return numToNByteStr(this.r) + numToNByteStr(this.s);
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
__name(_Signature, "Signature");
|
|
1254
|
+
let Signature = _Signature;
|
|
1255
|
+
const utils = {
|
|
1256
|
+
isValidPrivateKey(privateKey) {
|
|
1257
|
+
try {
|
|
1258
|
+
normPrivateKeyToScalar(privateKey);
|
|
1259
|
+
return true;
|
|
1260
|
+
} catch (error) {
|
|
1261
|
+
return false;
|
|
1262
|
+
}
|
|
1263
|
+
},
|
|
1264
|
+
normPrivateKeyToScalar,
|
|
1265
|
+
/**
|
|
1266
|
+
* Produces cryptographically secure private key from random of size (nBitLength+64)
|
|
1267
|
+
* as per FIPS 186 B.4.1 with modulo bias being neglible.
|
|
1268
|
+
*/
|
|
1269
|
+
randomPrivateKey: () => {
|
|
1270
|
+
const rand = CURVE.randomBytes(Fp.BYTES + 8);
|
|
1271
|
+
const num = hashToPrivateScalar(rand, CURVE_ORDER);
|
|
1272
|
+
return numberToBytesBE(num, CURVE.nByteLength);
|
|
1273
|
+
},
|
|
1274
|
+
/**
|
|
1275
|
+
* Creates precompute table for an arbitrary EC point. Makes point "cached".
|
|
1276
|
+
* Allows to massively speed-up `point.multiply(scalar)`.
|
|
1277
|
+
* @returns cached point
|
|
1278
|
+
* @example
|
|
1279
|
+
* const fast = utils.precompute(8, ProjectivePoint.fromHex(someonesPubKey));
|
|
1280
|
+
* fast.multiply(privKey); // much faster ECDH now
|
|
1281
|
+
*/
|
|
1282
|
+
precompute(windowSize = 8, point = Point.BASE) {
|
|
1283
|
+
point._setWindowSize(windowSize);
|
|
1284
|
+
point.multiply(BigInt(3));
|
|
1285
|
+
return point;
|
|
1286
|
+
}
|
|
1287
|
+
};
|
|
1288
|
+
function getPublicKey(privateKey, isCompressed = true) {
|
|
1289
|
+
return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);
|
|
1290
|
+
}
|
|
1291
|
+
__name(getPublicKey, "getPublicKey");
|
|
1292
|
+
function isProbPub(item) {
|
|
1293
|
+
const arr = item instanceof Uint8Array;
|
|
1294
|
+
const str = typeof item === "string";
|
|
1295
|
+
const len = (arr || str) && item.length;
|
|
1296
|
+
if (arr)
|
|
1297
|
+
return len === compressedLen || len === uncompressedLen;
|
|
1298
|
+
if (str)
|
|
1299
|
+
return len === 2 * compressedLen || len === 2 * uncompressedLen;
|
|
1300
|
+
if (item instanceof Point)
|
|
1301
|
+
return true;
|
|
1302
|
+
return false;
|
|
1303
|
+
}
|
|
1304
|
+
__name(isProbPub, "isProbPub");
|
|
1305
|
+
function getSharedSecret(privateA, publicB, isCompressed = true) {
|
|
1306
|
+
if (isProbPub(privateA))
|
|
1307
|
+
throw new Error("first arg must be private key");
|
|
1308
|
+
if (!isProbPub(publicB))
|
|
1309
|
+
throw new Error("second arg must be public key");
|
|
1310
|
+
const b = Point.fromHex(publicB);
|
|
1311
|
+
return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed);
|
|
1312
|
+
}
|
|
1313
|
+
__name(getSharedSecret, "getSharedSecret");
|
|
1314
|
+
const bits2int = CURVE.bits2int || function(bytes) {
|
|
1315
|
+
const num = bytesToNumberBE(bytes);
|
|
1316
|
+
const delta = bytes.length * 8 - CURVE.nBitLength;
|
|
1317
|
+
return delta > 0 ? num >> BigInt(delta) : num;
|
|
1318
|
+
};
|
|
1319
|
+
const bits2int_modN = CURVE.bits2int_modN || function(bytes) {
|
|
1320
|
+
return modN(bits2int(bytes));
|
|
1321
|
+
};
|
|
1322
|
+
const ORDER_MASK = bitMask(CURVE.nBitLength);
|
|
1323
|
+
function int2octets(num) {
|
|
1324
|
+
if (typeof num !== "bigint")
|
|
1325
|
+
throw new Error("bigint expected");
|
|
1326
|
+
if (!(_0n4 <= num && num < ORDER_MASK))
|
|
1327
|
+
throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
|
|
1328
|
+
return numberToBytesBE(num, CURVE.nByteLength);
|
|
1329
|
+
}
|
|
1330
|
+
__name(int2octets, "int2octets");
|
|
1331
|
+
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
|
1332
|
+
if (["recovered", "canonical"].some((k) => k in opts))
|
|
1333
|
+
throw new Error("sign() legacy options not supported");
|
|
1334
|
+
const { hash, randomBytes: randomBytes2 } = CURVE;
|
|
1335
|
+
let { lowS, prehash, extraEntropy: ent } = opts;
|
|
1336
|
+
if (lowS == null)
|
|
1337
|
+
lowS = true;
|
|
1338
|
+
msgHash = ensureBytes("msgHash", msgHash);
|
|
1339
|
+
if (prehash)
|
|
1340
|
+
msgHash = ensureBytes("prehashed msgHash", hash(msgHash));
|
|
1341
|
+
const h1int = bits2int_modN(msgHash);
|
|
1342
|
+
const d = normPrivateKeyToScalar(privateKey);
|
|
1343
|
+
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
1344
|
+
if (ent != null) {
|
|
1345
|
+
const e = ent === true ? randomBytes2(Fp.BYTES) : ent;
|
|
1346
|
+
seedArgs.push(ensureBytes("extraEntropy", e, Fp.BYTES));
|
|
1347
|
+
}
|
|
1348
|
+
const seed = concatBytes(...seedArgs);
|
|
1349
|
+
const m = h1int;
|
|
1350
|
+
function k2sig(kBytes) {
|
|
1351
|
+
const k = bits2int(kBytes);
|
|
1352
|
+
if (!isWithinCurveOrder(k))
|
|
1353
|
+
return;
|
|
1354
|
+
const ik = invN(k);
|
|
1355
|
+
const q = Point.BASE.multiply(k).toAffine();
|
|
1356
|
+
const r = modN(q.x);
|
|
1357
|
+
if (r === _0n4)
|
|
1358
|
+
return;
|
|
1359
|
+
const s = modN(ik * modN(m + r * d));
|
|
1360
|
+
if (s === _0n4)
|
|
1361
|
+
return;
|
|
1362
|
+
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n4);
|
|
1363
|
+
let normS = s;
|
|
1364
|
+
if (lowS && isBiggerThanHalfOrder(s)) {
|
|
1365
|
+
normS = normalizeS(s);
|
|
1366
|
+
recovery ^= 1;
|
|
1367
|
+
}
|
|
1368
|
+
return new Signature(r, normS, recovery);
|
|
1369
|
+
}
|
|
1370
|
+
__name(k2sig, "k2sig");
|
|
1371
|
+
return { seed, k2sig };
|
|
1372
|
+
}
|
|
1373
|
+
__name(prepSig, "prepSig");
|
|
1374
|
+
const defaultSigOpts = { lowS: CURVE.lowS, prehash: false };
|
|
1375
|
+
const defaultVerOpts = { lowS: CURVE.lowS, prehash: false };
|
|
1376
|
+
function sign(msgHash, privKey, opts = defaultSigOpts) {
|
|
1377
|
+
const { seed, k2sig } = prepSig(msgHash, privKey, opts);
|
|
1378
|
+
const C = CURVE;
|
|
1379
|
+
const drbg = createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac);
|
|
1380
|
+
return drbg(seed, k2sig);
|
|
1381
|
+
}
|
|
1382
|
+
__name(sign, "sign");
|
|
1383
|
+
Point.BASE._setWindowSize(8);
|
|
1384
|
+
function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
|
|
1385
|
+
var _a9;
|
|
1386
|
+
const sg = signature;
|
|
1387
|
+
msgHash = ensureBytes("msgHash", msgHash);
|
|
1388
|
+
publicKey = ensureBytes("publicKey", publicKey);
|
|
1389
|
+
if ("strict" in opts)
|
|
1390
|
+
throw new Error("options.strict was renamed to lowS");
|
|
1391
|
+
const { lowS, prehash } = opts;
|
|
1392
|
+
let _sig = void 0;
|
|
1393
|
+
let P;
|
|
1394
|
+
try {
|
|
1395
|
+
if (typeof sg === "string" || sg instanceof Uint8Array) {
|
|
1396
|
+
try {
|
|
1397
|
+
_sig = Signature.fromDER(sg);
|
|
1398
|
+
} catch (derError) {
|
|
1399
|
+
if (!(derError instanceof DER.Err))
|
|
1400
|
+
throw derError;
|
|
1401
|
+
_sig = Signature.fromCompact(sg);
|
|
1402
|
+
}
|
|
1403
|
+
} else if (typeof sg === "object" && typeof sg.r === "bigint" && typeof sg.s === "bigint") {
|
|
1404
|
+
const { r: r2, s: s2 } = sg;
|
|
1405
|
+
_sig = new Signature(r2, s2);
|
|
1406
|
+
} else {
|
|
1407
|
+
throw new Error("PARSE");
|
|
1408
|
+
}
|
|
1409
|
+
P = Point.fromHex(publicKey);
|
|
1410
|
+
} catch (error) {
|
|
1411
|
+
if (error.message === "PARSE")
|
|
1412
|
+
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
|
1413
|
+
return false;
|
|
1414
|
+
}
|
|
1415
|
+
if (lowS && _sig.hasHighS())
|
|
1416
|
+
return false;
|
|
1417
|
+
if (prehash)
|
|
1418
|
+
msgHash = CURVE.hash(msgHash);
|
|
1419
|
+
const { r, s } = _sig;
|
|
1420
|
+
const h = bits2int_modN(msgHash);
|
|
1421
|
+
const is = invN(s);
|
|
1422
|
+
const u1 = modN(h * is);
|
|
1423
|
+
const u2 = modN(r * is);
|
|
1424
|
+
const R = (_a9 = Point.BASE.multiplyAndAddUnsafe(P, u1, u2)) == null ? void 0 : _a9.toAffine();
|
|
1425
|
+
if (!R)
|
|
1426
|
+
return false;
|
|
1427
|
+
const v = modN(R.x);
|
|
1428
|
+
return v === r;
|
|
1429
|
+
}
|
|
1430
|
+
__name(verify, "verify");
|
|
1431
|
+
return {
|
|
1432
|
+
CURVE,
|
|
1433
|
+
getPublicKey,
|
|
1434
|
+
getSharedSecret,
|
|
1435
|
+
sign,
|
|
1436
|
+
verify,
|
|
1437
|
+
ProjectivePoint: Point,
|
|
1438
|
+
Signature,
|
|
1439
|
+
utils
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
__name(weierstrass, "weierstrass");
|
|
1443
|
+
|
|
1444
|
+
// node_modules/sm-crypto-v2/dist/index.mjs
|
|
1445
|
+
var __defProp = Object.defineProperty;
|
|
1446
|
+
var __export2 = /* @__PURE__ */ __name((target, all) => {
|
|
1447
|
+
for (var name in all)
|
|
1448
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
1449
|
+
}, "__export");
|
|
1450
|
+
var sm2_exports = {};
|
|
1451
|
+
__export2(sm2_exports, {
|
|
1452
|
+
EmptyArray: () => EmptyArray,
|
|
1453
|
+
arrayToHex: () => arrayToHex,
|
|
1454
|
+
arrayToUtf8: () => arrayToUtf8,
|
|
1455
|
+
calculateSharedKey: () => calculateSharedKey,
|
|
1456
|
+
comparePublicKeyHex: () => comparePublicKeyHex,
|
|
1457
|
+
compressPublicKeyHex: () => compressPublicKeyHex,
|
|
1458
|
+
doDecrypt: () => doDecrypt,
|
|
1459
|
+
doEncrypt: () => doEncrypt,
|
|
1460
|
+
doSignature: () => doSignature,
|
|
1461
|
+
doVerifySignature: () => doVerifySignature,
|
|
1462
|
+
generateKeyPairHex: () => generateKeyPairHex,
|
|
1463
|
+
getHash: () => getHash,
|
|
1464
|
+
getPoint: () => getPoint,
|
|
1465
|
+
getPublicKeyFromPrivateKey: () => getPublicKeyFromPrivateKey,
|
|
1466
|
+
getZ: () => getZ,
|
|
1467
|
+
hexToArray: () => hexToArray,
|
|
1468
|
+
initRNGPool: () => initRNGPool,
|
|
1469
|
+
leftPad: () => leftPad,
|
|
1470
|
+
precomputePublicKey: () => precomputePublicKey,
|
|
1471
|
+
utf8ToHex: () => utf8ToHex,
|
|
1472
|
+
verifyPublicKey: () => verifyPublicKey
|
|
1473
|
+
});
|
|
1474
|
+
var ZERO = BigInt(0);
|
|
1475
|
+
var ONE = BigInt(1);
|
|
1476
|
+
var TWO = BigInt(2);
|
|
1477
|
+
BigInt(3);
|
|
1478
|
+
function bigintToValue(bigint) {
|
|
1479
|
+
let h = bigint.toString(16);
|
|
1480
|
+
if (h[0] !== "-") {
|
|
1481
|
+
if (h.length % 2 === 1)
|
|
1482
|
+
h = "0" + h;
|
|
1483
|
+
else if (!h.match(/^[0-7]/))
|
|
1484
|
+
h = "00" + h;
|
|
1485
|
+
} else {
|
|
1486
|
+
h = h.substring(1);
|
|
1487
|
+
let len = h.length;
|
|
1488
|
+
if (len % 2 === 1)
|
|
1489
|
+
len += 1;
|
|
1490
|
+
else if (!h.match(/^[0-7]/))
|
|
1491
|
+
len += 2;
|
|
1492
|
+
let maskString = "";
|
|
1493
|
+
for (let i = 0; i < len; i++)
|
|
1494
|
+
maskString += "f";
|
|
1495
|
+
let mask = hexToNumber(maskString);
|
|
1496
|
+
let output = (mask ^ bigint) + ONE;
|
|
1497
|
+
h = output.toString(16).replace(/^-/, "");
|
|
1498
|
+
}
|
|
1499
|
+
return h;
|
|
1500
|
+
}
|
|
1501
|
+
__name(bigintToValue, "bigintToValue");
|
|
1502
|
+
var _a2;
|
|
1503
|
+
var ASN1Object = (_a2 = class {
|
|
1504
|
+
constructor(tlv = null, t = "00", l = "00", v = "") {
|
|
1505
|
+
this.tlv = tlv;
|
|
1506
|
+
this.t = t;
|
|
1507
|
+
this.l = l;
|
|
1508
|
+
this.v = v;
|
|
1509
|
+
}
|
|
1510
|
+
getEncodedHex() {
|
|
1511
|
+
if (!this.tlv) {
|
|
1512
|
+
this.v = this.getValue();
|
|
1513
|
+
this.l = this.getLength();
|
|
1514
|
+
this.tlv = this.t + this.l + this.v;
|
|
1515
|
+
}
|
|
1516
|
+
return this.tlv;
|
|
1517
|
+
}
|
|
1518
|
+
getLength() {
|
|
1519
|
+
const n = this.v.length / 2;
|
|
1520
|
+
let nHex = n.toString(16);
|
|
1521
|
+
if (nHex.length % 2 === 1)
|
|
1522
|
+
nHex = "0" + nHex;
|
|
1523
|
+
if (n < 128) {
|
|
1524
|
+
return nHex;
|
|
1525
|
+
} else {
|
|
1526
|
+
const head = 128 + nHex.length / 2;
|
|
1527
|
+
return head.toString(16) + nHex;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
getValue() {
|
|
1531
|
+
return "";
|
|
1532
|
+
}
|
|
1533
|
+
}, __name(_a2, "ASN1Object"), _a2);
|
|
1534
|
+
var _a3;
|
|
1535
|
+
var DERInteger = (_a3 = class extends ASN1Object {
|
|
1536
|
+
constructor(bigint) {
|
|
1537
|
+
super();
|
|
1538
|
+
this.t = "02";
|
|
1539
|
+
if (bigint)
|
|
1540
|
+
this.v = bigintToValue(bigint);
|
|
1541
|
+
}
|
|
1542
|
+
getValue() {
|
|
1543
|
+
return this.v;
|
|
1544
|
+
}
|
|
1545
|
+
}, __name(_a3, "DERInteger"), _a3);
|
|
1546
|
+
var _a4;
|
|
1547
|
+
var DERSequence = (_a4 = class extends ASN1Object {
|
|
1548
|
+
constructor(asn1Array) {
|
|
1549
|
+
super();
|
|
1550
|
+
this.asn1Array = asn1Array;
|
|
1551
|
+
}
|
|
1552
|
+
t = "30";
|
|
1553
|
+
getValue() {
|
|
1554
|
+
this.v = this.asn1Array.map((asn1Object) => asn1Object.getEncodedHex()).join("");
|
|
1555
|
+
return this.v;
|
|
1556
|
+
}
|
|
1557
|
+
}, __name(_a4, "DERSequence"), _a4);
|
|
1558
|
+
function getLenOfL(str, start) {
|
|
1559
|
+
if (+str[start + 2] < 8)
|
|
1560
|
+
return 1;
|
|
1561
|
+
return +str.substring(start + 2, start + 4) & 127 + 1;
|
|
1562
|
+
}
|
|
1563
|
+
__name(getLenOfL, "getLenOfL");
|
|
1564
|
+
function getL(str, start) {
|
|
1565
|
+
const len = getLenOfL(str, start);
|
|
1566
|
+
const l = str.substring(start + 2, start + 2 + len * 2);
|
|
1567
|
+
if (!l)
|
|
1568
|
+
return -1;
|
|
1569
|
+
const bigint = +l[0] < 8 ? hexToNumber(l) : hexToNumber(l.substring(2));
|
|
1570
|
+
return +bigint.toString();
|
|
1571
|
+
}
|
|
1572
|
+
__name(getL, "getL");
|
|
1573
|
+
function getStartOfV(str, start) {
|
|
1574
|
+
const len = getLenOfL(str, start);
|
|
1575
|
+
return start + (len + 1) * 2;
|
|
1576
|
+
}
|
|
1577
|
+
__name(getStartOfV, "getStartOfV");
|
|
1578
|
+
function encodeDer(r, s) {
|
|
1579
|
+
const derR = new DERInteger(r);
|
|
1580
|
+
const derS = new DERInteger(s);
|
|
1581
|
+
const derSeq = new DERSequence([derR, derS]);
|
|
1582
|
+
return derSeq.getEncodedHex();
|
|
1583
|
+
}
|
|
1584
|
+
__name(encodeDer, "encodeDer");
|
|
1585
|
+
function decodeDer(input) {
|
|
1586
|
+
const start = getStartOfV(input, 0);
|
|
1587
|
+
const vIndexR = getStartOfV(input, start);
|
|
1588
|
+
const lR = getL(input, start);
|
|
1589
|
+
const vR = input.substr(vIndexR, lR * 2);
|
|
1590
|
+
const nextStart = vIndexR + vR.length;
|
|
1591
|
+
const vIndexS = getStartOfV(input, nextStart);
|
|
1592
|
+
const lS = getL(input, nextStart);
|
|
1593
|
+
const vS = input.substring(vIndexS, vIndexS + lS * 2);
|
|
1594
|
+
const r = hexToNumber(vR);
|
|
1595
|
+
const s = hexToNumber(vS);
|
|
1596
|
+
return { r, s };
|
|
1597
|
+
}
|
|
1598
|
+
__name(decodeDer, "decodeDer");
|
|
1599
|
+
var DEFAULT_PRNG_POOL_SIZE = 16384;
|
|
1600
|
+
var prngPool = new Uint8Array(0);
|
|
1601
|
+
var _syncCrypto;
|
|
1602
|
+
async function initRNGPool() {
|
|
1603
|
+
if ("crypto" in globalThis) {
|
|
1604
|
+
_syncCrypto = globalThis.crypto;
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
if (prngPool.length > DEFAULT_PRNG_POOL_SIZE / 2)
|
|
1608
|
+
return;
|
|
1609
|
+
if ("wx" in globalThis && "getRandomValues" in globalThis.wx) {
|
|
1610
|
+
prngPool = await new Promise((r) => {
|
|
1611
|
+
wx.getRandomValues({
|
|
1612
|
+
length: DEFAULT_PRNG_POOL_SIZE,
|
|
1613
|
+
success(res) {
|
|
1614
|
+
r(new Uint8Array(res.randomValues));
|
|
1615
|
+
}
|
|
1616
|
+
});
|
|
1617
|
+
});
|
|
1618
|
+
} else {
|
|
1619
|
+
try {
|
|
1620
|
+
if (globalThis.crypto) {
|
|
1621
|
+
_syncCrypto = globalThis.crypto;
|
|
1622
|
+
} else {
|
|
1623
|
+
const crypto = await import(
|
|
1624
|
+
/* webpackIgnore: true */
|
|
1625
|
+
'crypto'
|
|
1626
|
+
);
|
|
1627
|
+
_syncCrypto = crypto.webcrypto;
|
|
1628
|
+
}
|
|
1629
|
+
const array = new Uint8Array(DEFAULT_PRNG_POOL_SIZE);
|
|
1630
|
+
_syncCrypto.getRandomValues(array);
|
|
1631
|
+
prngPool = array;
|
|
1632
|
+
} catch (error) {
|
|
1633
|
+
throw new Error("no available csprng, abort.");
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
__name(initRNGPool, "initRNGPool");
|
|
1638
|
+
initRNGPool();
|
|
1639
|
+
function consumePool(length) {
|
|
1640
|
+
if (prngPool.length > length) {
|
|
1641
|
+
const prng = prngPool.slice(0, length);
|
|
1642
|
+
prngPool = prngPool.slice(length);
|
|
1643
|
+
initRNGPool();
|
|
1644
|
+
return prng;
|
|
1645
|
+
} else {
|
|
1646
|
+
throw new Error("random number pool is not ready or insufficient, prevent getting too long random values or too often.");
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
__name(consumePool, "consumePool");
|
|
1650
|
+
function randomBytes(length = 0) {
|
|
1651
|
+
const array = new Uint8Array(length);
|
|
1652
|
+
if (_syncCrypto) {
|
|
1653
|
+
return _syncCrypto.getRandomValues(array);
|
|
1654
|
+
} else {
|
|
1655
|
+
const result = consumePool(length);
|
|
1656
|
+
return result;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
__name(randomBytes, "randomBytes");
|
|
1660
|
+
var u8a2 = /* @__PURE__ */ __name((a) => a instanceof Uint8Array, "u8a");
|
|
1661
|
+
var createView = /* @__PURE__ */ __name((arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength), "createView");
|
|
1662
|
+
var isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
|
|
1663
|
+
if (!isLE)
|
|
1664
|
+
throw new Error("Non little-endian hardware is not supported");
|
|
1665
|
+
var hexes2 = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, "0"));
|
|
1666
|
+
function bytesToHex2(bytes) {
|
|
1667
|
+
if (!u8a2(bytes))
|
|
1668
|
+
throw new Error("Uint8Array expected");
|
|
1669
|
+
let hex = "";
|
|
1670
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1671
|
+
hex += hexes2[bytes[i]];
|
|
1672
|
+
}
|
|
1673
|
+
return hex;
|
|
1674
|
+
}
|
|
1675
|
+
__name(bytesToHex2, "bytesToHex");
|
|
1676
|
+
function utf8ToBytes2(str) {
|
|
1677
|
+
if (typeof str !== "string")
|
|
1678
|
+
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
|
1679
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
1680
|
+
}
|
|
1681
|
+
__name(utf8ToBytes2, "utf8ToBytes");
|
|
1682
|
+
function toBytes(data) {
|
|
1683
|
+
if (typeof data === "string")
|
|
1684
|
+
data = utf8ToBytes2(data);
|
|
1685
|
+
if (!u8a2(data))
|
|
1686
|
+
throw new Error(`expected Uint8Array, got ${typeof data}`);
|
|
1687
|
+
return data;
|
|
1688
|
+
}
|
|
1689
|
+
__name(toBytes, "toBytes");
|
|
1690
|
+
var _a5;
|
|
1691
|
+
var Hash = (_a5 = class {
|
|
1692
|
+
clone() {
|
|
1693
|
+
return this._cloneInto();
|
|
1694
|
+
}
|
|
1695
|
+
}, __name(_a5, "Hash"), _a5);
|
|
1696
|
+
function wrapConstructor(hashCons) {
|
|
1697
|
+
const hashC = /* @__PURE__ */ __name((msg) => hashCons().update(toBytes(msg)).digest(), "hashC");
|
|
1698
|
+
const tmp2 = hashCons();
|
|
1699
|
+
hashC.outputLen = tmp2.outputLen;
|
|
1700
|
+
hashC.blockLen = tmp2.blockLen;
|
|
1701
|
+
hashC.create = () => hashCons();
|
|
1702
|
+
return hashC;
|
|
1703
|
+
}
|
|
1704
|
+
__name(wrapConstructor, "wrapConstructor");
|
|
1705
|
+
var BoolA = /* @__PURE__ */ __name((A, B, C) => A & B | A & C | B & C, "BoolA");
|
|
1706
|
+
var BoolB = /* @__PURE__ */ __name((A, B, C) => A ^ B ^ C, "BoolB");
|
|
1707
|
+
var BoolC = /* @__PURE__ */ __name((A, B, C) => A & B | ~A & C, "BoolC");
|
|
1708
|
+
function setBigUint64(view, byteOffset, value, isLE2) {
|
|
1709
|
+
if (typeof view.setBigUint64 === "function")
|
|
1710
|
+
return view.setBigUint64(byteOffset, value, isLE2);
|
|
1711
|
+
const _32n = BigInt(32);
|
|
1712
|
+
const _u32_max = BigInt(4294967295);
|
|
1713
|
+
const wh = Number(value >> _32n & _u32_max);
|
|
1714
|
+
const wl = Number(value & _u32_max);
|
|
1715
|
+
const h = isLE2 ? 4 : 0;
|
|
1716
|
+
const l = isLE2 ? 0 : 4;
|
|
1717
|
+
view.setUint32(byteOffset + h, wh, isLE2);
|
|
1718
|
+
view.setUint32(byteOffset + l, wl, isLE2);
|
|
1719
|
+
}
|
|
1720
|
+
__name(setBigUint64, "setBigUint64");
|
|
1721
|
+
function rotl(x2, n) {
|
|
1722
|
+
const s = n & 31;
|
|
1723
|
+
return x2 << s | x2 >>> 32 - s;
|
|
1724
|
+
}
|
|
1725
|
+
__name(rotl, "rotl");
|
|
1726
|
+
function P0(X) {
|
|
1727
|
+
return X ^ rotl(X, 9) ^ rotl(X, 17);
|
|
1728
|
+
}
|
|
1729
|
+
__name(P0, "P0");
|
|
1730
|
+
function P1(X) {
|
|
1731
|
+
return X ^ rotl(X, 15) ^ rotl(X, 23);
|
|
1732
|
+
}
|
|
1733
|
+
__name(P1, "P1");
|
|
1734
|
+
var _a6;
|
|
1735
|
+
var SHA2 = (_a6 = class extends Hash {
|
|
1736
|
+
constructor(blockLen, outputLen, padOffset, isLE2) {
|
|
1737
|
+
super();
|
|
1738
|
+
this.blockLen = blockLen;
|
|
1739
|
+
this.outputLen = outputLen;
|
|
1740
|
+
this.padOffset = padOffset;
|
|
1741
|
+
this.isLE = isLE2;
|
|
1742
|
+
this.buffer = new Uint8Array(blockLen);
|
|
1743
|
+
this.view = createView(this.buffer);
|
|
1744
|
+
}
|
|
1745
|
+
buffer;
|
|
1746
|
+
view;
|
|
1747
|
+
finished = false;
|
|
1748
|
+
length = 0;
|
|
1749
|
+
pos = 0;
|
|
1750
|
+
destroyed = false;
|
|
1751
|
+
update(data) {
|
|
1752
|
+
const { view, buffer, blockLen } = this;
|
|
1753
|
+
data = toBytes(data);
|
|
1754
|
+
const len = data.length;
|
|
1755
|
+
for (let pos = 0; pos < len; ) {
|
|
1756
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
1757
|
+
if (take === blockLen) {
|
|
1758
|
+
const dataView = createView(data);
|
|
1759
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
1760
|
+
this.process(dataView, pos);
|
|
1761
|
+
continue;
|
|
1762
|
+
}
|
|
1763
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
1764
|
+
this.pos += take;
|
|
1765
|
+
pos += take;
|
|
1766
|
+
if (this.pos === blockLen) {
|
|
1767
|
+
this.process(view, 0);
|
|
1768
|
+
this.pos = 0;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
this.length += data.length;
|
|
1772
|
+
this.roundClean();
|
|
1773
|
+
return this;
|
|
1774
|
+
}
|
|
1775
|
+
digestInto(out) {
|
|
1776
|
+
this.finished = true;
|
|
1777
|
+
const { buffer, view, blockLen, isLE: isLE2 } = this;
|
|
1778
|
+
let { pos } = this;
|
|
1779
|
+
buffer[pos++] = 128;
|
|
1780
|
+
this.buffer.subarray(pos).fill(0);
|
|
1781
|
+
if (this.padOffset > blockLen - pos) {
|
|
1782
|
+
this.process(view, 0);
|
|
1783
|
+
pos = 0;
|
|
1784
|
+
}
|
|
1785
|
+
for (let i = pos; i < blockLen; i++)
|
|
1786
|
+
buffer[i] = 0;
|
|
1787
|
+
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE2);
|
|
1788
|
+
this.process(view, 0);
|
|
1789
|
+
const oview = createView(out);
|
|
1790
|
+
const len = this.outputLen;
|
|
1791
|
+
if (len % 4)
|
|
1792
|
+
throw new Error("_sha2: outputLen should be aligned to 32bit");
|
|
1793
|
+
const outLen = len / 4;
|
|
1794
|
+
const state = this.get();
|
|
1795
|
+
if (outLen > state.length)
|
|
1796
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
1797
|
+
for (let i = 0; i < outLen; i++)
|
|
1798
|
+
oview.setUint32(4 * i, state[i], isLE2);
|
|
1799
|
+
}
|
|
1800
|
+
digest() {
|
|
1801
|
+
const { buffer, outputLen } = this;
|
|
1802
|
+
this.digestInto(buffer);
|
|
1803
|
+
const res = buffer.slice(0, outputLen);
|
|
1804
|
+
this.destroy();
|
|
1805
|
+
return res;
|
|
1806
|
+
}
|
|
1807
|
+
_cloneInto(to) {
|
|
1808
|
+
to ||= new this.constructor();
|
|
1809
|
+
to.set(...this.get());
|
|
1810
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
1811
|
+
to.length = length;
|
|
1812
|
+
to.pos = pos;
|
|
1813
|
+
to.finished = finished;
|
|
1814
|
+
to.destroyed = destroyed;
|
|
1815
|
+
if (length % blockLen)
|
|
1816
|
+
to.buffer.set(buffer);
|
|
1817
|
+
return to;
|
|
1818
|
+
}
|
|
1819
|
+
}, __name(_a6, "SHA2"), _a6);
|
|
1820
|
+
var IV = new Uint32Array([1937774191, 1226093241, 388252375, 3666478592, 2842636476, 372324522, 3817729613, 2969243214]);
|
|
1821
|
+
var SM3_W = new Uint32Array(68);
|
|
1822
|
+
var SM3_M = new Uint32Array(64);
|
|
1823
|
+
var T1 = 2043430169;
|
|
1824
|
+
var T2 = 2055708042;
|
|
1825
|
+
var _a7;
|
|
1826
|
+
var SM3 = (_a7 = class extends SHA2 {
|
|
1827
|
+
A = IV[0] | 0;
|
|
1828
|
+
B = IV[1] | 0;
|
|
1829
|
+
C = IV[2] | 0;
|
|
1830
|
+
D = IV[3] | 0;
|
|
1831
|
+
E = IV[4] | 0;
|
|
1832
|
+
F = IV[5] | 0;
|
|
1833
|
+
G = IV[6] | 0;
|
|
1834
|
+
H = IV[7] | 0;
|
|
1835
|
+
constructor() {
|
|
1836
|
+
super(64, 32, 8, false);
|
|
1837
|
+
}
|
|
1838
|
+
get() {
|
|
1839
|
+
const { A, B, C, D, E, F, G, H } = this;
|
|
1840
|
+
return [A, B, C, D, E, F, G, H];
|
|
1841
|
+
}
|
|
1842
|
+
set(A, B, C, D, E, F, G, H) {
|
|
1843
|
+
this.A = A | 0;
|
|
1844
|
+
this.B = B | 0;
|
|
1845
|
+
this.C = C | 0;
|
|
1846
|
+
this.D = D | 0;
|
|
1847
|
+
this.E = E | 0;
|
|
1848
|
+
this.F = F | 0;
|
|
1849
|
+
this.G = G | 0;
|
|
1850
|
+
this.H = H | 0;
|
|
1851
|
+
}
|
|
1852
|
+
process(view, offset) {
|
|
1853
|
+
for (let i = 0; i < 16; i++, offset += 4)
|
|
1854
|
+
SM3_W[i] = view.getUint32(offset, false);
|
|
1855
|
+
for (let i = 16; i < 68; i++) {
|
|
1856
|
+
SM3_W[i] = P1(SM3_W[i - 16] ^ SM3_W[i - 9] ^ rotl(SM3_W[i - 3], 15)) ^ rotl(SM3_W[i - 13], 7) ^ SM3_W[i - 6];
|
|
1857
|
+
}
|
|
1858
|
+
for (let i = 0; i < 64; i++) {
|
|
1859
|
+
SM3_M[i] = SM3_W[i] ^ SM3_W[i + 4];
|
|
1860
|
+
}
|
|
1861
|
+
let { A, B, C, D, E, F, G, H } = this;
|
|
1862
|
+
for (let j = 0; j < 64; j++) {
|
|
1863
|
+
let small = j >= 0 && j <= 15;
|
|
1864
|
+
let T = small ? T1 : T2;
|
|
1865
|
+
let SS1 = rotl(rotl(A, 12) + E + rotl(T, j), 7);
|
|
1866
|
+
let SS2 = SS1 ^ rotl(A, 12);
|
|
1867
|
+
let TT1 = (small ? BoolB(A, B, C) : BoolA(A, B, C)) + D + SS2 + SM3_M[j] | 0;
|
|
1868
|
+
let TT2 = (small ? BoolB(E, F, G) : BoolC(E, F, G)) + H + SS1 + SM3_W[j] | 0;
|
|
1869
|
+
D = C;
|
|
1870
|
+
C = rotl(B, 9);
|
|
1871
|
+
B = A;
|
|
1872
|
+
A = TT1;
|
|
1873
|
+
H = G;
|
|
1874
|
+
G = rotl(F, 19);
|
|
1875
|
+
F = E;
|
|
1876
|
+
E = P0(TT2);
|
|
1877
|
+
}
|
|
1878
|
+
A = A ^ this.A | 0;
|
|
1879
|
+
B = B ^ this.B | 0;
|
|
1880
|
+
C = C ^ this.C | 0;
|
|
1881
|
+
D = D ^ this.D | 0;
|
|
1882
|
+
E = E ^ this.E | 0;
|
|
1883
|
+
F = F ^ this.F | 0;
|
|
1884
|
+
G = G ^ this.G | 0;
|
|
1885
|
+
H = H ^ this.H | 0;
|
|
1886
|
+
this.set(A, B, C, D, E, F, G, H);
|
|
1887
|
+
}
|
|
1888
|
+
roundClean() {
|
|
1889
|
+
SM3_W.fill(0);
|
|
1890
|
+
}
|
|
1891
|
+
destroy() {
|
|
1892
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
1893
|
+
this.buffer.fill(0);
|
|
1894
|
+
}
|
|
1895
|
+
}, __name(_a7, "SM3"), _a7);
|
|
1896
|
+
var sm3 = wrapConstructor(() => new SM3());
|
|
1897
|
+
var _a8;
|
|
1898
|
+
var HMAC = (_a8 = class extends Hash {
|
|
1899
|
+
oHash;
|
|
1900
|
+
iHash;
|
|
1901
|
+
blockLen;
|
|
1902
|
+
outputLen;
|
|
1903
|
+
finished = false;
|
|
1904
|
+
destroyed = false;
|
|
1905
|
+
constructor(hash, _key) {
|
|
1906
|
+
super();
|
|
1907
|
+
const key = toBytes(_key);
|
|
1908
|
+
this.iHash = hash.create();
|
|
1909
|
+
if (typeof this.iHash.update !== "function")
|
|
1910
|
+
throw new Error("Expected instance of class which extends utils.Hash");
|
|
1911
|
+
this.blockLen = this.iHash.blockLen;
|
|
1912
|
+
this.outputLen = this.iHash.outputLen;
|
|
1913
|
+
const blockLen = this.blockLen;
|
|
1914
|
+
const pad = new Uint8Array(blockLen);
|
|
1915
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
|
1916
|
+
for (let i = 0; i < pad.length; i++)
|
|
1917
|
+
pad[i] ^= 54;
|
|
1918
|
+
this.iHash.update(pad);
|
|
1919
|
+
this.oHash = hash.create();
|
|
1920
|
+
for (let i = 0; i < pad.length; i++)
|
|
1921
|
+
pad[i] ^= 54 ^ 92;
|
|
1922
|
+
this.oHash.update(pad);
|
|
1923
|
+
pad.fill(0);
|
|
1924
|
+
}
|
|
1925
|
+
update(buf) {
|
|
1926
|
+
this.iHash.update(buf);
|
|
1927
|
+
return this;
|
|
1928
|
+
}
|
|
1929
|
+
digestInto(out) {
|
|
1930
|
+
this.finished = true;
|
|
1931
|
+
this.iHash.digestInto(out);
|
|
1932
|
+
this.oHash.update(out);
|
|
1933
|
+
this.oHash.digestInto(out);
|
|
1934
|
+
this.destroy();
|
|
1935
|
+
}
|
|
1936
|
+
digest() {
|
|
1937
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
|
1938
|
+
this.digestInto(out);
|
|
1939
|
+
return out;
|
|
1940
|
+
}
|
|
1941
|
+
_cloneInto(to) {
|
|
1942
|
+
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
1943
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
1944
|
+
to = to;
|
|
1945
|
+
to.finished = finished;
|
|
1946
|
+
to.destroyed = destroyed;
|
|
1947
|
+
to.blockLen = blockLen;
|
|
1948
|
+
to.outputLen = outputLen;
|
|
1949
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
|
1950
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
|
1951
|
+
return to;
|
|
1952
|
+
}
|
|
1953
|
+
destroy() {
|
|
1954
|
+
this.destroyed = true;
|
|
1955
|
+
this.oHash.destroy();
|
|
1956
|
+
this.iHash.destroy();
|
|
1957
|
+
}
|
|
1958
|
+
}, __name(_a8, "HMAC"), _a8);
|
|
1959
|
+
var hmac = /* @__PURE__ */ __name((hash, key, message) => new HMAC(hash, key).update(message).digest(), "hmac");
|
|
1960
|
+
hmac.create = (hash, key) => new HMAC(hash, key);
|
|
1961
|
+
var sm2Fp = Field(BigInt("115792089210356248756420345214020892766250353991924191454421193933289684991999"));
|
|
1962
|
+
var sm2Curve = weierstrass({
|
|
1963
|
+
a: BigInt("115792089210356248756420345214020892766250353991924191454421193933289684991996"),
|
|
1964
|
+
b: BigInt("18505919022281880113072981827955639221458448578012075254857346196103069175443"),
|
|
1965
|
+
Fp: sm2Fp,
|
|
1966
|
+
h: ONE,
|
|
1967
|
+
n: BigInt("115792089210356248756420345214020892766061623724957744567843809356293439045923"),
|
|
1968
|
+
Gx: BigInt("22963146547237050559479531362550074578802567295341616970375194840604139615431"),
|
|
1969
|
+
Gy: BigInt("85132369209828568825618990617112496413088388631904505083283536607588877201568"),
|
|
1970
|
+
hash: sm3,
|
|
1971
|
+
hmac: (key, ...msgs) => hmac(sm3, key, concatBytes(...msgs)),
|
|
1972
|
+
randomBytes
|
|
1973
|
+
});
|
|
1974
|
+
var field = Field(BigInt(sm2Curve.CURVE.n));
|
|
1975
|
+
function generateKeyPairHex(str) {
|
|
1976
|
+
const privateKey = str ? numberToBytesBE(mod(BigInt(str), ONE) + ONE, 32) : sm2Curve.utils.randomPrivateKey();
|
|
1977
|
+
const publicKey = sm2Curve.getPublicKey(privateKey, false);
|
|
1978
|
+
const privPad = leftPad(bytesToHex(privateKey), 64);
|
|
1979
|
+
const pubPad = leftPad(bytesToHex(publicKey), 64);
|
|
1980
|
+
return { privateKey: privPad, publicKey: pubPad };
|
|
1981
|
+
}
|
|
1982
|
+
__name(generateKeyPairHex, "generateKeyPairHex");
|
|
1983
|
+
function compressPublicKeyHex(s) {
|
|
1984
|
+
if (s.length !== 130)
|
|
1985
|
+
throw new Error("Invalid public key to compress");
|
|
1986
|
+
const len = (s.length - 2) / 2;
|
|
1987
|
+
const xHex = s.substring(2, 2 + len);
|
|
1988
|
+
const y = hexToNumber(s.substring(len + 2, len + len + 2));
|
|
1989
|
+
let prefix = "03";
|
|
1990
|
+
if (mod(y, TWO) === ZERO)
|
|
1991
|
+
prefix = "02";
|
|
1992
|
+
return prefix + xHex;
|
|
1993
|
+
}
|
|
1994
|
+
__name(compressPublicKeyHex, "compressPublicKeyHex");
|
|
1995
|
+
function utf8ToHex(input) {
|
|
1996
|
+
input = decodeURIComponent(encodeURIComponent(input));
|
|
1997
|
+
const length = input.length;
|
|
1998
|
+
const words = new Uint32Array((length >>> 2) + 1);
|
|
1999
|
+
for (let i = 0; i < length; i++) {
|
|
2000
|
+
words[i >>> 2] |= (input.charCodeAt(i) & 255) << 24 - i % 4 * 8;
|
|
2001
|
+
}
|
|
2002
|
+
const hexChars = [];
|
|
2003
|
+
for (let i = 0; i < length; i++) {
|
|
2004
|
+
const bite = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
|
2005
|
+
hexChars.push((bite >>> 4).toString(16));
|
|
2006
|
+
hexChars.push((bite & 15).toString(16));
|
|
2007
|
+
}
|
|
2008
|
+
return hexChars.join("");
|
|
2009
|
+
}
|
|
2010
|
+
__name(utf8ToHex, "utf8ToHex");
|
|
2011
|
+
function leftPad(input, num) {
|
|
2012
|
+
if (input.length >= num)
|
|
2013
|
+
return input;
|
|
2014
|
+
return new Array(num - input.length + 1).join("0") + input;
|
|
2015
|
+
}
|
|
2016
|
+
__name(leftPad, "leftPad");
|
|
2017
|
+
function arrayToHex(arr) {
|
|
2018
|
+
return arr.map((item) => {
|
|
2019
|
+
const hex = item.toString(16);
|
|
2020
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
2021
|
+
}).join("");
|
|
2022
|
+
}
|
|
2023
|
+
__name(arrayToHex, "arrayToHex");
|
|
2024
|
+
function arrayToUtf8(arr) {
|
|
2025
|
+
const str = [];
|
|
2026
|
+
for (let i = 0, len = arr.length; i < len; i++) {
|
|
2027
|
+
if (arr[i] >= 240 && arr[i] <= 247) {
|
|
2028
|
+
str.push(String.fromCodePoint(((arr[i] & 7) << 18) + ((arr[i + 1] & 63) << 12) + ((arr[i + 2] & 63) << 6) + (arr[i + 3] & 63)));
|
|
2029
|
+
i += 3;
|
|
2030
|
+
} else if (arr[i] >= 224 && arr[i] <= 239) {
|
|
2031
|
+
str.push(String.fromCodePoint(((arr[i] & 15) << 12) + ((arr[i + 1] & 63) << 6) + (arr[i + 2] & 63)));
|
|
2032
|
+
i += 2;
|
|
2033
|
+
} else if (arr[i] >= 192 && arr[i] <= 223) {
|
|
2034
|
+
str.push(String.fromCodePoint(((arr[i] & 31) << 6) + (arr[i + 1] & 63)));
|
|
2035
|
+
i++;
|
|
2036
|
+
} else {
|
|
2037
|
+
str.push(String.fromCodePoint(arr[i]));
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
return str.join("");
|
|
2041
|
+
}
|
|
2042
|
+
__name(arrayToUtf8, "arrayToUtf8");
|
|
2043
|
+
function hexToArray(hexStr) {
|
|
2044
|
+
let hexStrLength = hexStr.length;
|
|
2045
|
+
if (hexStrLength % 2 !== 0) {
|
|
2046
|
+
hexStr = leftPad(hexStr, hexStrLength + 1);
|
|
2047
|
+
}
|
|
2048
|
+
hexStrLength = hexStr.length;
|
|
2049
|
+
const wordLength = hexStrLength / 2;
|
|
2050
|
+
const words = new Uint8Array(wordLength);
|
|
2051
|
+
for (let i = 0; i < wordLength; i++) {
|
|
2052
|
+
words[i] = parseInt(hexStr.substring(i * 2, i * 2 + 2), 16);
|
|
2053
|
+
}
|
|
2054
|
+
return words;
|
|
2055
|
+
}
|
|
2056
|
+
__name(hexToArray, "hexToArray");
|
|
2057
|
+
function verifyPublicKey(publicKey) {
|
|
2058
|
+
const point = sm2Curve.ProjectivePoint.fromHex(publicKey);
|
|
2059
|
+
if (!point)
|
|
2060
|
+
return false;
|
|
2061
|
+
try {
|
|
2062
|
+
point.assertValidity();
|
|
2063
|
+
return true;
|
|
2064
|
+
} catch (error) {
|
|
2065
|
+
return false;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
__name(verifyPublicKey, "verifyPublicKey");
|
|
2069
|
+
function comparePublicKeyHex(publicKey1, publicKey2) {
|
|
2070
|
+
const point1 = sm2Curve.ProjectivePoint.fromHex(publicKey1);
|
|
2071
|
+
if (!point1)
|
|
2072
|
+
return false;
|
|
2073
|
+
const point2 = sm2Curve.ProjectivePoint.fromHex(publicKey2);
|
|
2074
|
+
if (!point2)
|
|
2075
|
+
return false;
|
|
2076
|
+
return point1.equals(point2);
|
|
2077
|
+
}
|
|
2078
|
+
__name(comparePublicKeyHex, "comparePublicKeyHex");
|
|
2079
|
+
var wPow2 = hexToNumber("80000000000000000000000000000000");
|
|
2080
|
+
var wPow2Sub1 = hexToNumber("7fffffffffffffffffffffffffffffff");
|
|
2081
|
+
function hkdf(z, keylen) {
|
|
2082
|
+
let msg = new Uint8Array(keylen);
|
|
2083
|
+
let ct = 1;
|
|
2084
|
+
let offset = 0;
|
|
2085
|
+
let t = EmptyArray;
|
|
2086
|
+
const ctShift = new Uint8Array(4);
|
|
2087
|
+
const nextT = /* @__PURE__ */ __name(() => {
|
|
2088
|
+
ctShift[0] = ct >> 24 & 255;
|
|
2089
|
+
ctShift[1] = ct >> 16 & 255;
|
|
2090
|
+
ctShift[2] = ct >> 8 & 255;
|
|
2091
|
+
ctShift[3] = ct & 255;
|
|
2092
|
+
t = sm3(concatBytes(z, ctShift));
|
|
2093
|
+
ct++;
|
|
2094
|
+
offset = 0;
|
|
2095
|
+
}, "nextT");
|
|
2096
|
+
nextT();
|
|
2097
|
+
for (let i = 0, len = msg.length; i < len; i++) {
|
|
2098
|
+
if (offset === t.length)
|
|
2099
|
+
nextT();
|
|
2100
|
+
msg[i] = t[offset++] & 255;
|
|
2101
|
+
}
|
|
2102
|
+
return msg;
|
|
2103
|
+
}
|
|
2104
|
+
__name(hkdf, "hkdf");
|
|
2105
|
+
function calculateSharedKey(keypairA, ephemeralKeypairA, publicKeyB, ephemeralPublicKeyB, sharedKeyLength, isRecipient = false, idA = "1234567812345678", idB = "1234567812345678") {
|
|
2106
|
+
const RA = sm2Curve.ProjectivePoint.fromHex(ephemeralKeypairA.publicKey);
|
|
2107
|
+
const RB = sm2Curve.ProjectivePoint.fromHex(ephemeralPublicKeyB);
|
|
2108
|
+
const PB = sm2Curve.ProjectivePoint.fromHex(publicKeyB);
|
|
2109
|
+
let ZA = getZ(keypairA.publicKey, idA);
|
|
2110
|
+
let ZB = getZ(publicKeyB, idB);
|
|
2111
|
+
if (isRecipient) {
|
|
2112
|
+
[ZA, ZB] = [ZB, ZA];
|
|
2113
|
+
}
|
|
2114
|
+
const rA = hexToNumber(ephemeralKeypairA.privateKey);
|
|
2115
|
+
const dA = hexToNumber(keypairA.privateKey);
|
|
2116
|
+
const x1 = RA.x;
|
|
2117
|
+
const x1_ = wPow2 + (x1 & wPow2Sub1);
|
|
2118
|
+
const tA = field.add(dA, field.mulN(x1_, rA));
|
|
2119
|
+
const x2 = RB.x;
|
|
2120
|
+
const x2_ = field.add(wPow2, x2 & wPow2Sub1);
|
|
2121
|
+
const U = RB.multiply(x2_).add(PB).multiply(tA);
|
|
2122
|
+
const xU = hexToArray(leftPad(numberToHexUnpadded(U.x), 64));
|
|
2123
|
+
const yU = hexToArray(leftPad(numberToHexUnpadded(U.y), 64));
|
|
2124
|
+
const KA = hkdf(concatBytes(xU, yU, ZA, ZB), sharedKeyLength);
|
|
2125
|
+
return KA;
|
|
2126
|
+
}
|
|
2127
|
+
__name(calculateSharedKey, "calculateSharedKey");
|
|
2128
|
+
var C1C2C3 = 0;
|
|
2129
|
+
var EmptyArray = new Uint8Array();
|
|
2130
|
+
function doEncrypt(msg, publicKey, cipherMode = 1) {
|
|
2131
|
+
const msgArr = typeof msg === "string" ? hexToArray(utf8ToHex(msg)) : Uint8Array.from(msg);
|
|
2132
|
+
const publicKeyPoint = typeof publicKey === "string" ? sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey;
|
|
2133
|
+
const keypair = generateKeyPairHex();
|
|
2134
|
+
const k = hexToNumber(keypair.privateKey);
|
|
2135
|
+
let c1 = keypair.publicKey;
|
|
2136
|
+
if (c1.length > 128)
|
|
2137
|
+
c1 = c1.substring(c1.length - 128);
|
|
2138
|
+
const p = publicKeyPoint.multiply(k);
|
|
2139
|
+
const x2 = hexToArray(leftPad(numberToHexUnpadded(p.x), 64));
|
|
2140
|
+
const y2 = hexToArray(leftPad(numberToHexUnpadded(p.y), 64));
|
|
2141
|
+
const c3 = bytesToHex2(sm3(concatBytes(x2, msgArr, y2)));
|
|
2142
|
+
xorCipherStream(x2, y2, msgArr);
|
|
2143
|
+
const c2 = bytesToHex2(msgArr);
|
|
2144
|
+
return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2;
|
|
2145
|
+
}
|
|
2146
|
+
__name(doEncrypt, "doEncrypt");
|
|
2147
|
+
function xorCipherStream(x2, y2, msg) {
|
|
2148
|
+
let ct = 1;
|
|
2149
|
+
let offset = 0;
|
|
2150
|
+
let t = EmptyArray;
|
|
2151
|
+
const ctShift = new Uint8Array(4);
|
|
2152
|
+
const nextT = /* @__PURE__ */ __name(() => {
|
|
2153
|
+
ctShift[0] = ct >> 24 & 255;
|
|
2154
|
+
ctShift[1] = ct >> 16 & 255;
|
|
2155
|
+
ctShift[2] = ct >> 8 & 255;
|
|
2156
|
+
ctShift[3] = ct & 255;
|
|
2157
|
+
t = sm3(concatBytes(x2, y2, ctShift));
|
|
2158
|
+
ct++;
|
|
2159
|
+
offset = 0;
|
|
2160
|
+
}, "nextT");
|
|
2161
|
+
nextT();
|
|
2162
|
+
for (let i = 0, len = msg.length; i < len; i++) {
|
|
2163
|
+
if (offset === t.length)
|
|
2164
|
+
nextT();
|
|
2165
|
+
msg[i] ^= t[offset++] & 255;
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
__name(xorCipherStream, "xorCipherStream");
|
|
2169
|
+
function doDecrypt(encryptData, privateKey, cipherMode = 1, {
|
|
2170
|
+
output = "string"
|
|
2171
|
+
} = {}) {
|
|
2172
|
+
const privateKeyInteger = hexToNumber(privateKey);
|
|
2173
|
+
let c3 = encryptData.substring(128, 128 + 64);
|
|
2174
|
+
let c2 = encryptData.substring(128 + 64);
|
|
2175
|
+
if (cipherMode === C1C2C3) {
|
|
2176
|
+
c3 = encryptData.substring(encryptData.length - 64);
|
|
2177
|
+
c2 = encryptData.substring(128, encryptData.length - 64);
|
|
2178
|
+
}
|
|
2179
|
+
const msg = hexToArray(c2);
|
|
2180
|
+
const c1 = sm2Curve.ProjectivePoint.fromHex("04" + encryptData.substring(0, 128));
|
|
2181
|
+
const p = c1.multiply(privateKeyInteger);
|
|
2182
|
+
const x2 = hexToArray(leftPad(numberToHexUnpadded(p.x), 64));
|
|
2183
|
+
const y2 = hexToArray(leftPad(numberToHexUnpadded(p.y), 64));
|
|
2184
|
+
xorCipherStream(x2, y2, msg);
|
|
2185
|
+
const checkC3 = arrayToHex(Array.from(sm3(concatBytes(x2, msg, y2))));
|
|
2186
|
+
if (checkC3 === c3.toLowerCase()) {
|
|
2187
|
+
return output === "array" ? msg : arrayToUtf8(msg);
|
|
2188
|
+
} else {
|
|
2189
|
+
return output === "array" ? [] : "";
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
__name(doDecrypt, "doDecrypt");
|
|
2193
|
+
function doSignature(msg, privateKey, options = {}) {
|
|
2194
|
+
let {
|
|
2195
|
+
pointPool,
|
|
2196
|
+
der,
|
|
2197
|
+
hash,
|
|
2198
|
+
publicKey,
|
|
2199
|
+
userId
|
|
2200
|
+
} = options;
|
|
2201
|
+
let hashHex = typeof msg === "string" ? utf8ToHex(msg) : arrayToHex(Array.from(msg));
|
|
2202
|
+
if (hash) {
|
|
2203
|
+
publicKey = publicKey || getPublicKeyFromPrivateKey(privateKey);
|
|
2204
|
+
hashHex = getHash(hashHex, publicKey, userId);
|
|
2205
|
+
}
|
|
2206
|
+
const dA = hexToNumber(privateKey);
|
|
2207
|
+
const e = hexToNumber(hashHex);
|
|
2208
|
+
let k = null;
|
|
2209
|
+
let r = null;
|
|
2210
|
+
let s = null;
|
|
2211
|
+
do {
|
|
2212
|
+
do {
|
|
2213
|
+
let point;
|
|
2214
|
+
if (pointPool && pointPool.length) {
|
|
2215
|
+
point = pointPool.pop();
|
|
2216
|
+
} else {
|
|
2217
|
+
point = getPoint();
|
|
2218
|
+
}
|
|
2219
|
+
k = point.k;
|
|
2220
|
+
r = field.add(e, point.x1);
|
|
2221
|
+
} while (r === ZERO || r + k === sm2Curve.CURVE.n);
|
|
2222
|
+
s = field.mul(field.inv(field.addN(dA, ONE)), field.subN(k, field.mulN(r, dA)));
|
|
2223
|
+
} while (s === ZERO);
|
|
2224
|
+
if (der)
|
|
2225
|
+
return encodeDer(r, s);
|
|
2226
|
+
return leftPad(numberToHexUnpadded(r), 64) + leftPad(numberToHexUnpadded(s), 64);
|
|
2227
|
+
}
|
|
2228
|
+
__name(doSignature, "doSignature");
|
|
2229
|
+
function doVerifySignature(msg, signHex, publicKey, options = {}) {
|
|
2230
|
+
let hashHex;
|
|
2231
|
+
const {
|
|
2232
|
+
hash,
|
|
2233
|
+
der,
|
|
2234
|
+
userId
|
|
2235
|
+
} = options;
|
|
2236
|
+
const publicKeyHex = typeof publicKey === "string" ? publicKey : publicKey.toHex(false);
|
|
2237
|
+
if (hash) {
|
|
2238
|
+
hashHex = getHash(typeof msg === "string" ? utf8ToHex(msg) : msg, publicKeyHex, userId);
|
|
2239
|
+
} else {
|
|
2240
|
+
hashHex = typeof msg === "string" ? utf8ToHex(msg) : arrayToHex(Array.from(msg));
|
|
2241
|
+
}
|
|
2242
|
+
let r;
|
|
2243
|
+
let s;
|
|
2244
|
+
if (der) {
|
|
2245
|
+
const decodeDerObj = decodeDer(signHex);
|
|
2246
|
+
r = decodeDerObj.r;
|
|
2247
|
+
s = decodeDerObj.s;
|
|
2248
|
+
} else {
|
|
2249
|
+
r = hexToNumber(signHex.substring(0, 64));
|
|
2250
|
+
s = hexToNumber(signHex.substring(64));
|
|
2251
|
+
}
|
|
2252
|
+
const PA = typeof publicKey === "string" ? sm2Curve.ProjectivePoint.fromHex(publicKey) : publicKey;
|
|
2253
|
+
const e = hexToNumber(hashHex);
|
|
2254
|
+
const t = field.add(r, s);
|
|
2255
|
+
if (t === ZERO)
|
|
2256
|
+
return false;
|
|
2257
|
+
const x1y1 = sm2Curve.ProjectivePoint.BASE.multiply(s).add(PA.multiply(t));
|
|
2258
|
+
const R = field.add(e, x1y1.x);
|
|
2259
|
+
return r === R;
|
|
2260
|
+
}
|
|
2261
|
+
__name(doVerifySignature, "doVerifySignature");
|
|
2262
|
+
function getZ(publicKey, userId = "1234567812345678") {
|
|
2263
|
+
userId = utf8ToHex(userId);
|
|
2264
|
+
const a = leftPad(numberToHexUnpadded(sm2Curve.CURVE.a), 64);
|
|
2265
|
+
const b = leftPad(numberToHexUnpadded(sm2Curve.CURVE.b), 64);
|
|
2266
|
+
const gx = leftPad(numberToHexUnpadded(sm2Curve.ProjectivePoint.BASE.x), 64);
|
|
2267
|
+
const gy = leftPad(numberToHexUnpadded(sm2Curve.ProjectivePoint.BASE.y), 64);
|
|
2268
|
+
let px;
|
|
2269
|
+
let py;
|
|
2270
|
+
if (publicKey.length === 128) {
|
|
2271
|
+
px = publicKey.substring(0, 64);
|
|
2272
|
+
py = publicKey.substring(64, 128);
|
|
2273
|
+
} else {
|
|
2274
|
+
const point = sm2Curve.ProjectivePoint.fromHex(publicKey);
|
|
2275
|
+
px = leftPad(numberToHexUnpadded(point.x), 64);
|
|
2276
|
+
py = leftPad(numberToHexUnpadded(point.y), 64);
|
|
2277
|
+
}
|
|
2278
|
+
const data = hexToArray(userId + a + b + gx + gy + px + py);
|
|
2279
|
+
const entl = userId.length * 4;
|
|
2280
|
+
const z = sm3(concatBytes(new Uint8Array([entl >> 8 & 255, entl & 255]), data));
|
|
2281
|
+
return z;
|
|
2282
|
+
}
|
|
2283
|
+
__name(getZ, "getZ");
|
|
2284
|
+
function getHash(hashHex, publicKey, userId = "1234567812345678") {
|
|
2285
|
+
const z = getZ(publicKey, userId);
|
|
2286
|
+
return bytesToHex2(sm3(concatBytes(z, typeof hashHex === "string" ? hexToArray(hashHex) : hashHex)));
|
|
2287
|
+
}
|
|
2288
|
+
__name(getHash, "getHash");
|
|
2289
|
+
function precomputePublicKey(publicKey, windowSize) {
|
|
2290
|
+
const point = sm2Curve.ProjectivePoint.fromHex(publicKey);
|
|
2291
|
+
return sm2Curve.utils.precompute(windowSize, point);
|
|
2292
|
+
}
|
|
2293
|
+
__name(precomputePublicKey, "precomputePublicKey");
|
|
2294
|
+
function getPublicKeyFromPrivateKey(privateKey) {
|
|
2295
|
+
const pubKey = sm2Curve.getPublicKey(privateKey, false);
|
|
2296
|
+
const pubPad = leftPad(bytesToHex(pubKey), 64);
|
|
2297
|
+
return pubPad;
|
|
2298
|
+
}
|
|
2299
|
+
__name(getPublicKeyFromPrivateKey, "getPublicKeyFromPrivateKey");
|
|
2300
|
+
function getPoint() {
|
|
2301
|
+
const keypair = generateKeyPairHex();
|
|
2302
|
+
const PA = sm2Curve.ProjectivePoint.fromHex(keypair.publicKey);
|
|
2303
|
+
const k = hexToNumber(keypair.privateKey);
|
|
2304
|
+
return {
|
|
2305
|
+
...keypair,
|
|
2306
|
+
k,
|
|
2307
|
+
x1: PA.x
|
|
2308
|
+
};
|
|
2309
|
+
}
|
|
2310
|
+
__name(getPoint, "getPoint");
|
|
2311
|
+
function utf8ToArray(str) {
|
|
2312
|
+
const arr = [];
|
|
2313
|
+
for (let i = 0, len = str.length; i < len; i++) {
|
|
2314
|
+
const point = str.codePointAt(i);
|
|
2315
|
+
if (point <= 127) {
|
|
2316
|
+
arr.push(point);
|
|
2317
|
+
} else if (point <= 2047) {
|
|
2318
|
+
arr.push(192 | point >>> 6);
|
|
2319
|
+
arr.push(128 | point & 63);
|
|
2320
|
+
} else if (point <= 55295 || point >= 57344 && point <= 65535) {
|
|
2321
|
+
arr.push(224 | point >>> 12);
|
|
2322
|
+
arr.push(128 | point >>> 6 & 63);
|
|
2323
|
+
arr.push(128 | point & 63);
|
|
2324
|
+
} else if (point >= 65536 && point <= 1114111) {
|
|
2325
|
+
i++;
|
|
2326
|
+
arr.push(240 | point >>> 18 & 28);
|
|
2327
|
+
arr.push(128 | point >>> 12 & 63);
|
|
2328
|
+
arr.push(128 | point >>> 6 & 63);
|
|
2329
|
+
arr.push(128 | point & 63);
|
|
2330
|
+
} else {
|
|
2331
|
+
arr.push(point);
|
|
2332
|
+
throw new Error("input is not supported");
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
return new Uint8Array(arr);
|
|
2336
|
+
}
|
|
2337
|
+
__name(utf8ToArray, "utf8ToArray");
|
|
2338
|
+
var sm4_exports = {};
|
|
2339
|
+
__export2(sm4_exports, {
|
|
2340
|
+
decrypt: () => decrypt,
|
|
2341
|
+
encrypt: () => encrypt,
|
|
2342
|
+
sm4: () => sm4
|
|
2343
|
+
});
|
|
2344
|
+
var DECRYPT = 0;
|
|
2345
|
+
var ROUND = 32;
|
|
2346
|
+
var BLOCK = 16;
|
|
2347
|
+
var Sbox = Uint8Array.from([
|
|
2348
|
+
214,
|
|
2349
|
+
144,
|
|
2350
|
+
233,
|
|
2351
|
+
254,
|
|
2352
|
+
204,
|
|
2353
|
+
225,
|
|
2354
|
+
61,
|
|
2355
|
+
183,
|
|
2356
|
+
22,
|
|
2357
|
+
182,
|
|
2358
|
+
20,
|
|
2359
|
+
194,
|
|
2360
|
+
40,
|
|
2361
|
+
251,
|
|
2362
|
+
44,
|
|
2363
|
+
5,
|
|
2364
|
+
43,
|
|
2365
|
+
103,
|
|
2366
|
+
154,
|
|
2367
|
+
118,
|
|
2368
|
+
42,
|
|
2369
|
+
190,
|
|
2370
|
+
4,
|
|
2371
|
+
195,
|
|
2372
|
+
170,
|
|
2373
|
+
68,
|
|
2374
|
+
19,
|
|
2375
|
+
38,
|
|
2376
|
+
73,
|
|
2377
|
+
134,
|
|
2378
|
+
6,
|
|
2379
|
+
153,
|
|
2380
|
+
156,
|
|
2381
|
+
66,
|
|
2382
|
+
80,
|
|
2383
|
+
244,
|
|
2384
|
+
145,
|
|
2385
|
+
239,
|
|
2386
|
+
152,
|
|
2387
|
+
122,
|
|
2388
|
+
51,
|
|
2389
|
+
84,
|
|
2390
|
+
11,
|
|
2391
|
+
67,
|
|
2392
|
+
237,
|
|
2393
|
+
207,
|
|
2394
|
+
172,
|
|
2395
|
+
98,
|
|
2396
|
+
228,
|
|
2397
|
+
179,
|
|
2398
|
+
28,
|
|
2399
|
+
169,
|
|
2400
|
+
201,
|
|
2401
|
+
8,
|
|
2402
|
+
232,
|
|
2403
|
+
149,
|
|
2404
|
+
128,
|
|
2405
|
+
223,
|
|
2406
|
+
148,
|
|
2407
|
+
250,
|
|
2408
|
+
117,
|
|
2409
|
+
143,
|
|
2410
|
+
63,
|
|
2411
|
+
166,
|
|
2412
|
+
71,
|
|
2413
|
+
7,
|
|
2414
|
+
167,
|
|
2415
|
+
252,
|
|
2416
|
+
243,
|
|
2417
|
+
115,
|
|
2418
|
+
23,
|
|
2419
|
+
186,
|
|
2420
|
+
131,
|
|
2421
|
+
89,
|
|
2422
|
+
60,
|
|
2423
|
+
25,
|
|
2424
|
+
230,
|
|
2425
|
+
133,
|
|
2426
|
+
79,
|
|
2427
|
+
168,
|
|
2428
|
+
104,
|
|
2429
|
+
107,
|
|
2430
|
+
129,
|
|
2431
|
+
178,
|
|
2432
|
+
113,
|
|
2433
|
+
100,
|
|
2434
|
+
218,
|
|
2435
|
+
139,
|
|
2436
|
+
248,
|
|
2437
|
+
235,
|
|
2438
|
+
15,
|
|
2439
|
+
75,
|
|
2440
|
+
112,
|
|
2441
|
+
86,
|
|
2442
|
+
157,
|
|
2443
|
+
53,
|
|
2444
|
+
30,
|
|
2445
|
+
36,
|
|
2446
|
+
14,
|
|
2447
|
+
94,
|
|
2448
|
+
99,
|
|
2449
|
+
88,
|
|
2450
|
+
209,
|
|
2451
|
+
162,
|
|
2452
|
+
37,
|
|
2453
|
+
34,
|
|
2454
|
+
124,
|
|
2455
|
+
59,
|
|
2456
|
+
1,
|
|
2457
|
+
33,
|
|
2458
|
+
120,
|
|
2459
|
+
135,
|
|
2460
|
+
212,
|
|
2461
|
+
0,
|
|
2462
|
+
70,
|
|
2463
|
+
87,
|
|
2464
|
+
159,
|
|
2465
|
+
211,
|
|
2466
|
+
39,
|
|
2467
|
+
82,
|
|
2468
|
+
76,
|
|
2469
|
+
54,
|
|
2470
|
+
2,
|
|
2471
|
+
231,
|
|
2472
|
+
160,
|
|
2473
|
+
196,
|
|
2474
|
+
200,
|
|
2475
|
+
158,
|
|
2476
|
+
234,
|
|
2477
|
+
191,
|
|
2478
|
+
138,
|
|
2479
|
+
210,
|
|
2480
|
+
64,
|
|
2481
|
+
199,
|
|
2482
|
+
56,
|
|
2483
|
+
181,
|
|
2484
|
+
163,
|
|
2485
|
+
247,
|
|
2486
|
+
242,
|
|
2487
|
+
206,
|
|
2488
|
+
249,
|
|
2489
|
+
97,
|
|
2490
|
+
21,
|
|
2491
|
+
161,
|
|
2492
|
+
224,
|
|
2493
|
+
174,
|
|
2494
|
+
93,
|
|
2495
|
+
164,
|
|
2496
|
+
155,
|
|
2497
|
+
52,
|
|
2498
|
+
26,
|
|
2499
|
+
85,
|
|
2500
|
+
173,
|
|
2501
|
+
147,
|
|
2502
|
+
50,
|
|
2503
|
+
48,
|
|
2504
|
+
245,
|
|
2505
|
+
140,
|
|
2506
|
+
177,
|
|
2507
|
+
227,
|
|
2508
|
+
29,
|
|
2509
|
+
246,
|
|
2510
|
+
226,
|
|
2511
|
+
46,
|
|
2512
|
+
130,
|
|
2513
|
+
102,
|
|
2514
|
+
202,
|
|
2515
|
+
96,
|
|
2516
|
+
192,
|
|
2517
|
+
41,
|
|
2518
|
+
35,
|
|
2519
|
+
171,
|
|
2520
|
+
13,
|
|
2521
|
+
83,
|
|
2522
|
+
78,
|
|
2523
|
+
111,
|
|
2524
|
+
213,
|
|
2525
|
+
219,
|
|
2526
|
+
55,
|
|
2527
|
+
69,
|
|
2528
|
+
222,
|
|
2529
|
+
253,
|
|
2530
|
+
142,
|
|
2531
|
+
47,
|
|
2532
|
+
3,
|
|
2533
|
+
255,
|
|
2534
|
+
106,
|
|
2535
|
+
114,
|
|
2536
|
+
109,
|
|
2537
|
+
108,
|
|
2538
|
+
91,
|
|
2539
|
+
81,
|
|
2540
|
+
141,
|
|
2541
|
+
27,
|
|
2542
|
+
175,
|
|
2543
|
+
146,
|
|
2544
|
+
187,
|
|
2545
|
+
221,
|
|
2546
|
+
188,
|
|
2547
|
+
127,
|
|
2548
|
+
17,
|
|
2549
|
+
217,
|
|
2550
|
+
92,
|
|
2551
|
+
65,
|
|
2552
|
+
31,
|
|
2553
|
+
16,
|
|
2554
|
+
90,
|
|
2555
|
+
216,
|
|
2556
|
+
10,
|
|
2557
|
+
193,
|
|
2558
|
+
49,
|
|
2559
|
+
136,
|
|
2560
|
+
165,
|
|
2561
|
+
205,
|
|
2562
|
+
123,
|
|
2563
|
+
189,
|
|
2564
|
+
45,
|
|
2565
|
+
116,
|
|
2566
|
+
208,
|
|
2567
|
+
18,
|
|
2568
|
+
184,
|
|
2569
|
+
229,
|
|
2570
|
+
180,
|
|
2571
|
+
176,
|
|
2572
|
+
137,
|
|
2573
|
+
105,
|
|
2574
|
+
151,
|
|
2575
|
+
74,
|
|
2576
|
+
12,
|
|
2577
|
+
150,
|
|
2578
|
+
119,
|
|
2579
|
+
126,
|
|
2580
|
+
101,
|
|
2581
|
+
185,
|
|
2582
|
+
241,
|
|
2583
|
+
9,
|
|
2584
|
+
197,
|
|
2585
|
+
110,
|
|
2586
|
+
198,
|
|
2587
|
+
132,
|
|
2588
|
+
24,
|
|
2589
|
+
240,
|
|
2590
|
+
125,
|
|
2591
|
+
236,
|
|
2592
|
+
58,
|
|
2593
|
+
220,
|
|
2594
|
+
77,
|
|
2595
|
+
32,
|
|
2596
|
+
121,
|
|
2597
|
+
238,
|
|
2598
|
+
95,
|
|
2599
|
+
62,
|
|
2600
|
+
215,
|
|
2601
|
+
203,
|
|
2602
|
+
57,
|
|
2603
|
+
72
|
|
2604
|
+
]);
|
|
2605
|
+
var CK = new Uint32Array([
|
|
2606
|
+
462357,
|
|
2607
|
+
472066609,
|
|
2608
|
+
943670861,
|
|
2609
|
+
1415275113,
|
|
2610
|
+
1886879365,
|
|
2611
|
+
2358483617,
|
|
2612
|
+
2830087869,
|
|
2613
|
+
3301692121,
|
|
2614
|
+
3773296373,
|
|
2615
|
+
4228057617,
|
|
2616
|
+
404694573,
|
|
2617
|
+
876298825,
|
|
2618
|
+
1347903077,
|
|
2619
|
+
1819507329,
|
|
2620
|
+
2291111581,
|
|
2621
|
+
2762715833,
|
|
2622
|
+
3234320085,
|
|
2623
|
+
3705924337,
|
|
2624
|
+
4177462797,
|
|
2625
|
+
337322537,
|
|
2626
|
+
808926789,
|
|
2627
|
+
1280531041,
|
|
2628
|
+
1752135293,
|
|
2629
|
+
2223739545,
|
|
2630
|
+
2695343797,
|
|
2631
|
+
3166948049,
|
|
2632
|
+
3638552301,
|
|
2633
|
+
4110090761,
|
|
2634
|
+
269950501,
|
|
2635
|
+
741554753,
|
|
2636
|
+
1213159005,
|
|
2637
|
+
1684763257
|
|
2638
|
+
]);
|
|
2639
|
+
function byteSub(a) {
|
|
2640
|
+
return (Sbox[a >>> 24 & 255] & 255) << 24 | (Sbox[a >>> 16 & 255] & 255) << 16 | (Sbox[a >>> 8 & 255] & 255) << 8 | Sbox[a & 255] & 255;
|
|
2641
|
+
}
|
|
2642
|
+
__name(byteSub, "byteSub");
|
|
2643
|
+
function sms4Crypt(input, output, roundKey) {
|
|
2644
|
+
let x0 = 0, x1 = 0, x2 = 0, x3 = 0, tmp0 = 0, tmp1 = 0, tmp2 = 0, tmp3 = 0;
|
|
2645
|
+
tmp0 = input[0] & 255;
|
|
2646
|
+
tmp1 = input[1] & 255;
|
|
2647
|
+
tmp2 = input[2] & 255;
|
|
2648
|
+
tmp3 = input[3] & 255;
|
|
2649
|
+
x0 = tmp0 << 24 | tmp1 << 16 | tmp2 << 8 | tmp3;
|
|
2650
|
+
tmp0 = input[4] & 255;
|
|
2651
|
+
tmp1 = input[5] & 255;
|
|
2652
|
+
tmp2 = input[6] & 255;
|
|
2653
|
+
tmp3 = input[7] & 255;
|
|
2654
|
+
x1 = tmp0 << 24 | tmp1 << 16 | tmp2 << 8 | tmp3;
|
|
2655
|
+
tmp0 = input[8] & 255;
|
|
2656
|
+
tmp1 = input[9] & 255;
|
|
2657
|
+
tmp2 = input[10] & 255;
|
|
2658
|
+
tmp3 = input[11] & 255;
|
|
2659
|
+
x2 = tmp0 << 24 | tmp1 << 16 | tmp2 << 8 | tmp3;
|
|
2660
|
+
tmp0 = input[12] & 255;
|
|
2661
|
+
tmp1 = input[13] & 255;
|
|
2662
|
+
tmp2 = input[14] & 255;
|
|
2663
|
+
tmp3 = input[15] & 255;
|
|
2664
|
+
x3 = tmp0 << 24 | tmp1 << 16 | tmp2 << 8 | tmp3;
|
|
2665
|
+
for (let r = 0; r < 32; r += 4) {
|
|
2666
|
+
tmp0 = x1 ^ x2 ^ x3 ^ roundKey[r];
|
|
2667
|
+
tmp0 = byteSub(tmp0);
|
|
2668
|
+
x0 ^= tmp0 ^ (tmp0 << 2 | tmp0 >>> 30) ^ (tmp0 << 10 | tmp0 >>> 22) ^ (tmp0 << 18 | tmp0 >>> 14) ^ (tmp0 << 24 | tmp0 >>> 8);
|
|
2669
|
+
tmp1 = x2 ^ x3 ^ x0 ^ roundKey[r + 1];
|
|
2670
|
+
tmp1 = byteSub(tmp1);
|
|
2671
|
+
x1 ^= tmp1 ^ (tmp1 << 2 | tmp1 >>> 30) ^ (tmp1 << 10 | tmp1 >>> 22) ^ (tmp1 << 18 | tmp1 >>> 14) ^ (tmp1 << 24 | tmp1 >>> 8);
|
|
2672
|
+
tmp2 = x3 ^ x0 ^ x1 ^ roundKey[r + 2];
|
|
2673
|
+
tmp2 = byteSub(tmp2);
|
|
2674
|
+
x2 ^= tmp2 ^ (tmp2 << 2 | tmp2 >>> 30) ^ (tmp2 << 10 | tmp2 >>> 22) ^ (tmp2 << 18 | tmp2 >>> 14) ^ (tmp2 << 24 | tmp2 >>> 8);
|
|
2675
|
+
tmp3 = x0 ^ x1 ^ x2 ^ roundKey[r + 3];
|
|
2676
|
+
tmp3 = byteSub(tmp3);
|
|
2677
|
+
x3 ^= tmp3 ^ (tmp3 << 2 | tmp3 >>> 30) ^ (tmp3 << 10 | tmp3 >>> 22) ^ (tmp3 << 18 | tmp3 >>> 14) ^ (tmp3 << 24 | tmp3 >>> 8);
|
|
2678
|
+
}
|
|
2679
|
+
output[0] = x3 >>> 24 & 255;
|
|
2680
|
+
output[1] = x3 >>> 16 & 255;
|
|
2681
|
+
output[2] = x3 >>> 8 & 255;
|
|
2682
|
+
output[3] = x3 & 255;
|
|
2683
|
+
output[4] = x2 >>> 24 & 255;
|
|
2684
|
+
output[5] = x2 >>> 16 & 255;
|
|
2685
|
+
output[6] = x2 >>> 8 & 255;
|
|
2686
|
+
output[7] = x2 & 255;
|
|
2687
|
+
output[8] = x1 >>> 24 & 255;
|
|
2688
|
+
output[9] = x1 >>> 16 & 255;
|
|
2689
|
+
output[10] = x1 >>> 8 & 255;
|
|
2690
|
+
output[11] = x1 & 255;
|
|
2691
|
+
output[12] = x0 >>> 24 & 255;
|
|
2692
|
+
output[13] = x0 >>> 16 & 255;
|
|
2693
|
+
output[14] = x0 >>> 8 & 255;
|
|
2694
|
+
output[15] = x0 & 255;
|
|
2695
|
+
}
|
|
2696
|
+
__name(sms4Crypt, "sms4Crypt");
|
|
2697
|
+
function sms4KeyExt(key, roundKey, cryptFlag) {
|
|
2698
|
+
let x0 = 0, x1 = 0, x2 = 0, x3 = 0, mid = 0;
|
|
2699
|
+
x0 = (key[0] & 255) << 24 | (key[1] & 255) << 16 | (key[2] & 255) << 8 | key[3] & 255;
|
|
2700
|
+
x1 = (key[4] & 255) << 24 | (key[5] & 255) << 16 | (key[6] & 255) << 8 | key[7] & 255;
|
|
2701
|
+
x2 = (key[8] & 255) << 24 | (key[9] & 255) << 16 | (key[10] & 255) << 8 | key[11] & 255;
|
|
2702
|
+
x3 = (key[12] & 255) << 24 | (key[13] & 255) << 16 | (key[14] & 255) << 8 | key[15] & 255;
|
|
2703
|
+
x0 ^= 2746333894;
|
|
2704
|
+
x1 ^= 1453994832;
|
|
2705
|
+
x2 ^= 1736282519;
|
|
2706
|
+
x3 ^= 2993693404;
|
|
2707
|
+
for (let r = 0; r < 32; r += 4) {
|
|
2708
|
+
mid = x1 ^ x2 ^ x3 ^ CK[r + 0];
|
|
2709
|
+
mid = byteSub(mid);
|
|
2710
|
+
x0 ^= mid ^ (mid << 13 | mid >>> 19) ^ (mid << 23 | mid >>> 9);
|
|
2711
|
+
roundKey[r + 0] = x0;
|
|
2712
|
+
mid = x2 ^ x3 ^ x0 ^ CK[r + 1];
|
|
2713
|
+
mid = byteSub(mid);
|
|
2714
|
+
x1 ^= mid ^ (mid << 13 | mid >>> 19) ^ (mid << 23 | mid >>> 9);
|
|
2715
|
+
roundKey[r + 1] = x1;
|
|
2716
|
+
mid = x3 ^ x0 ^ x1 ^ CK[r + 2];
|
|
2717
|
+
mid = byteSub(mid);
|
|
2718
|
+
x2 ^= mid ^ (mid << 13 | mid >>> 19) ^ (mid << 23 | mid >>> 9);
|
|
2719
|
+
roundKey[r + 2] = x2;
|
|
2720
|
+
mid = x0 ^ x1 ^ x2 ^ CK[r + 3];
|
|
2721
|
+
mid = byteSub(mid);
|
|
2722
|
+
x3 ^= mid ^ (mid << 13 | mid >>> 19) ^ (mid << 23 | mid >>> 9);
|
|
2723
|
+
roundKey[r + 3] = x3;
|
|
2724
|
+
}
|
|
2725
|
+
if (cryptFlag === DECRYPT) {
|
|
2726
|
+
for (let r = 0; r < 16; r++) {
|
|
2727
|
+
[roundKey[r], roundKey[31 - r]] = [roundKey[31 - r], roundKey[r]];
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
__name(sms4KeyExt, "sms4KeyExt");
|
|
2732
|
+
var blockOutput = new Uint8Array(16);
|
|
2733
|
+
function sm4(inArray, key, cryptFlag, options = {}) {
|
|
2734
|
+
let {
|
|
2735
|
+
padding = "pkcs#7",
|
|
2736
|
+
mode,
|
|
2737
|
+
iv = new Uint8Array(16),
|
|
2738
|
+
output
|
|
2739
|
+
} = options;
|
|
2740
|
+
if (mode === "cbc") {
|
|
2741
|
+
if (typeof iv === "string")
|
|
2742
|
+
iv = hexToArray(iv);
|
|
2743
|
+
if (iv.length !== 128 / 8) {
|
|
2744
|
+
throw new Error("iv is invalid");
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
if (typeof key === "string")
|
|
2748
|
+
key = hexToArray(key);
|
|
2749
|
+
if (key.length !== 128 / 8) {
|
|
2750
|
+
throw new Error("key is invalid");
|
|
2751
|
+
}
|
|
2752
|
+
if (typeof inArray === "string") {
|
|
2753
|
+
if (cryptFlag !== DECRYPT) {
|
|
2754
|
+
inArray = utf8ToArray(inArray);
|
|
2755
|
+
} else {
|
|
2756
|
+
inArray = hexToArray(inArray);
|
|
2757
|
+
}
|
|
2758
|
+
} else {
|
|
2759
|
+
inArray = Uint8Array.from(inArray);
|
|
2760
|
+
}
|
|
2761
|
+
if ((padding === "pkcs#5" || padding === "pkcs#7") && cryptFlag !== DECRYPT) {
|
|
2762
|
+
const paddingCount = BLOCK - inArray.length % BLOCK;
|
|
2763
|
+
const newArray = new Uint8Array(inArray.length + paddingCount);
|
|
2764
|
+
newArray.set(inArray, 0);
|
|
2765
|
+
for (let i = 0; i < paddingCount; i++)
|
|
2766
|
+
newArray[inArray.length + i] = paddingCount;
|
|
2767
|
+
inArray = newArray;
|
|
2768
|
+
}
|
|
2769
|
+
const roundKey = new Uint32Array(ROUND);
|
|
2770
|
+
sms4KeyExt(key, roundKey, cryptFlag);
|
|
2771
|
+
let outArray = new Uint8Array(inArray.length);
|
|
2772
|
+
let lastVector = iv;
|
|
2773
|
+
let restLen = inArray.length;
|
|
2774
|
+
let point = 0;
|
|
2775
|
+
while (restLen >= BLOCK) {
|
|
2776
|
+
const input = inArray.subarray(point, point + 16);
|
|
2777
|
+
if (mode === "cbc") {
|
|
2778
|
+
for (let i = 0; i < BLOCK; i++) {
|
|
2779
|
+
if (cryptFlag !== DECRYPT) {
|
|
2780
|
+
input[i] ^= lastVector[i];
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
sms4Crypt(input, blockOutput, roundKey);
|
|
2785
|
+
for (let i = 0; i < BLOCK; i++) {
|
|
2786
|
+
if (mode === "cbc") {
|
|
2787
|
+
if (cryptFlag === DECRYPT) {
|
|
2788
|
+
blockOutput[i] ^= lastVector[i];
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
outArray[point + i] = blockOutput[i];
|
|
2792
|
+
}
|
|
2793
|
+
if (mode === "cbc") {
|
|
2794
|
+
if (cryptFlag !== DECRYPT) {
|
|
2795
|
+
lastVector = blockOutput;
|
|
2796
|
+
} else {
|
|
2797
|
+
lastVector = input;
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
restLen -= BLOCK;
|
|
2801
|
+
point += BLOCK;
|
|
2802
|
+
}
|
|
2803
|
+
if ((padding === "pkcs#5" || padding === "pkcs#7") && cryptFlag === DECRYPT) {
|
|
2804
|
+
const len = outArray.length;
|
|
2805
|
+
const paddingCount = outArray[len - 1];
|
|
2806
|
+
for (let i = 1; i <= paddingCount; i++) {
|
|
2807
|
+
if (outArray[len - i] !== paddingCount)
|
|
2808
|
+
throw new Error("padding is invalid");
|
|
2809
|
+
}
|
|
2810
|
+
outArray = outArray.slice(0, len - paddingCount);
|
|
2811
|
+
}
|
|
2812
|
+
if (output !== "array") {
|
|
2813
|
+
if (cryptFlag !== DECRYPT) {
|
|
2814
|
+
return bytesToHex2(outArray);
|
|
2815
|
+
} else {
|
|
2816
|
+
return arrayToUtf8(outArray);
|
|
2817
|
+
}
|
|
2818
|
+
} else {
|
|
2819
|
+
return outArray;
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
__name(sm4, "sm4");
|
|
2823
|
+
function encrypt(inArray, key, options = {}) {
|
|
2824
|
+
return sm4(inArray, key, 1, options);
|
|
2825
|
+
}
|
|
2826
|
+
__name(encrypt, "encrypt");
|
|
2827
|
+
function decrypt(inArray, key, options = {}) {
|
|
2828
|
+
return sm4(inArray, key, 0, options);
|
|
2829
|
+
}
|
|
2830
|
+
__name(decrypt, "decrypt");
|
|
2831
|
+
|
|
2832
|
+
// src/lib/crypto/SM2.ts
|
|
2833
|
+
async function initRNGPool2(constructor) {
|
|
2834
|
+
const metadataKey = "__$$RNGPoolInitialized";
|
|
2835
|
+
if (Reflect.getOwnMetadata(metadataKey, constructor))
|
|
2836
|
+
return;
|
|
2837
|
+
await sm2_exports.initRNGPool();
|
|
2838
|
+
Reflect.defineMetadata(metadataKey, true, constructor);
|
|
2839
|
+
}
|
|
2840
|
+
__name(initRNGPool2, "initRNGPool");
|
|
2841
|
+
var _SM2 = class _SM2 extends AsymmetricEncryption {
|
|
2842
|
+
options = {
|
|
2843
|
+
cipherMode: 1,
|
|
2844
|
+
signatureSM3Hash: true,
|
|
2845
|
+
signatureUserId: void 0
|
|
2846
|
+
};
|
|
2847
|
+
createPrivateKey(privateKeyString) {
|
|
2848
|
+
return privateKeyString;
|
|
2849
|
+
}
|
|
2850
|
+
createPublicKey(publicKeyString) {
|
|
2851
|
+
return publicKeyString;
|
|
2852
|
+
}
|
|
2853
|
+
decrypt(encryptedMessage) {
|
|
2854
|
+
return sm2_exports.doDecrypt(Buffer.from(encryptedMessage, "base64").toString("hex"), this.privateKey, this.options.cipherMode, { output: "string" });
|
|
2855
|
+
}
|
|
2856
|
+
encrypt(message) {
|
|
2857
|
+
return Buffer.from(sm2_exports.doEncrypt(message, this.publicKey, this.options.cipherMode), "hex").toString("base64");
|
|
2858
|
+
}
|
|
2859
|
+
async generateKeyPair(options) {
|
|
2860
|
+
let { publicKey, privateKey } = sm2_exports.generateKeyPairHex();
|
|
2861
|
+
if (options == null ? void 0 : options.compressPublicKey)
|
|
2862
|
+
publicKey = sm2_exports.compressPublicKeyHex(publicKey);
|
|
2863
|
+
return {
|
|
2864
|
+
publicKey,
|
|
2865
|
+
privateKey
|
|
2866
|
+
};
|
|
2867
|
+
}
|
|
2868
|
+
sign(message) {
|
|
2869
|
+
return Buffer.from(sm2_exports.doSignature(message, this.privateKey, {
|
|
2870
|
+
hash: this.options.signatureSM3Hash,
|
|
2871
|
+
publicKey: this.publicKey ? this.publicKey : void 0,
|
|
2872
|
+
userId: this.options.signatureUserId
|
|
2873
|
+
}), "hex").toString("base64");
|
|
2874
|
+
}
|
|
2875
|
+
verify(message, sign) {
|
|
2876
|
+
return sm2_exports.doVerifySignature(message, Buffer.from(sign, "base64").toString("hex"), this.publicKey, {
|
|
2877
|
+
hash: this.options.signatureSM3Hash,
|
|
2878
|
+
userId: this.options.signatureUserId
|
|
2879
|
+
});
|
|
2880
|
+
}
|
|
2881
|
+
static async generateKeyPair(options) {
|
|
2882
|
+
await initRNGPool2(this);
|
|
2883
|
+
return super.generateKeyPair(options);
|
|
2884
|
+
}
|
|
2885
|
+
static async loadKeyPair(keyPair, options) {
|
|
2886
|
+
await initRNGPool2(this);
|
|
2887
|
+
return As(super.loadKeyPair(keyPair, options));
|
|
2888
|
+
}
|
|
2889
|
+
static async loadPublicKey(inp, options) {
|
|
2890
|
+
await initRNGPool2(this);
|
|
2891
|
+
return super.loadPublicKey(inp, options);
|
|
2892
|
+
}
|
|
2893
|
+
static async loadPrivateKey(inp, options) {
|
|
2894
|
+
await initRNGPool2(this);
|
|
2895
|
+
return super.loadPrivateKey(inp, options);
|
|
2896
|
+
}
|
|
2897
|
+
};
|
|
2898
|
+
__name(_SM2, "SM2");
|
|
2899
|
+
var SM2 = _SM2;
|
|
2900
|
+
/*! Bundled license information:
|
|
2901
|
+
|
|
2902
|
+
@noble/curves/esm/abstract/utils.js:
|
|
2903
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
2904
|
+
|
|
2905
|
+
@noble/curves/esm/abstract/modular.js:
|
|
2906
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
2907
|
+
|
|
2908
|
+
@noble/curves/esm/abstract/curve.js:
|
|
2909
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
2910
|
+
|
|
2911
|
+
@noble/curves/esm/abstract/weierstrass.js:
|
|
2912
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
2913
|
+
|
|
2914
|
+
sm-crypto-v2/dist/index.mjs:
|
|
2915
|
+
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
2916
|
+
*/
|
|
2917
|
+
|
|
2918
|
+
export { SM2 };
|
|
2919
|
+
//# sourceMappingURL=out.js.map
|
|
2920
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9saWIvY3J5cHRvL1NNMi50cyIsIi4uL25vZGVfbW9kdWxlcy9zbS1jcnlwdG8tdjIvZGlzdC9pbmRleC5tanMiLCIuLi9ub2RlX21vZHVsZXMvQG5vYmxlL2N1cnZlcy9zcmMvYWJzdHJhY3QvdXRpbHMudHMiLCIuLi9ub2RlX21vZHVsZXMvQG5vYmxlL2N1cnZlcy9zcmMvYWJzdHJhY3Qvd2VpZXJzdHJhc3MudHMiLCIuLi9ub2RlX21vZHVsZXMvQG5vYmxlL2N1cnZlcy9zcmMvYWJzdHJhY3QvbW9kdWxhci50cyIsIi4uL25vZGVfbW9kdWxlcy9Abm9ibGUvY3VydmVzL3NyYy9hYnN0cmFjdC9jdXJ2ZS50cyJdLCJuYW1lcyI6WyJfMG4iLCJfMW4iLCJfMm4iLCJ4IiwiZmllbGQiLCJ0bXAiLCJiaXRMZW4iLCJpc0xFIiwicyIsIl8zbiIsIl80biIsInRvQnl0ZXMiLCJ4MiIsImEiLCJyYW5kb21CeXRlcyIsIl9hIiwiciIsIl9fZXhwb3J0IiwidThhIiwiaGV4ZXMiLCJieXRlc1RvSGV4IiwidXRmOFRvQnl0ZXMiLCJpbml0Uk5HUG9vbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBOzs7QUNBQTs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBS0EsSUFBTSxNQUFNLE9BQU8sQ0FBQztBQUNwQixJQUFNLE1BQU0sT0FBTyxDQUFDO0FBQ3BCLElBQU0sTUFBTSxPQUFPLENBQUM7QUFDcEIsSUFBTSxNQUFNLHdCQUFDLE1BQTRCLGFBQWEsWUFBMUM7QUFXWixJQUFNLFFBQVEsTUFBTSxLQUFLLEVBQUUsUUFBUSxJQUFHLEdBQUksQ0FBQyxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsRUFBRSxTQUFTLEdBQUcsR0FBRyxDQUFDO0FBSTdFLFNBQVUsV0FBVyxPQUFpQjtBQUMxQyxNQUFJLENBQUMsSUFBSSxLQUFLO0FBQUcsVUFBTSxJQUFJLE1BQU0scUJBQXFCO0FBRXRELE1BQUksTUFBTTtBQUNWLFdBQVMsSUFBSSxHQUFH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QUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsVUFBSSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDdEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxHQUFHLEVBQUU7QUFDakIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLEdBQUcsRUFBRTtBQUNqQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxHQUFHLEVBQUU7QUFDakIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FBSyxHQUFHLElBQUksSUFBSSxFQUFFO0FBQ2xCLFdBQUssR0FBRyxJQUFJLElBQUksRUFBRTtBQUNsQixXQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUU7QUFDbEIsV0FB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QUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxF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QUFJO0FBQ3RCLFdBQU8sTUFBTSxnQkFBZ0IsT0FBTztBQUFBLEVBQ3hDO0FBQUEsRUFFQSxhQUFvQixZQUFrRCxTQUFzQyxTQUFrQztBQUMxSSxVQUFNQSxhQUFZLElBQUk7QUFDdEIsV0FBTyxHQUFNLE1BQU0sWUFBaUIsU0FBUyxPQUFPLENBQUM7QUFBQSxFQUN6RDtBQUFBLEVBRUEsYUFBb0IsY0FBYyxLQUF3QixTQUEyRDtBQUNqSCxVQUFNQSxhQUFZLElBQUk7QUFDdEIsV0FBTyxNQUFNLGNBQWMsS0FBSyxPQUFPO0FBQUEsRUFDM0M7QUFBQSxFQUVBLGFBQW9CLGVBQWUsS0FBd0IsU0FBNEQ7QUFDbkgsVUFBTUEsYUFBWSxJQUFJO0FBQ3RCLFdBQU8sTUFBTSxlQUFlLEtBQUssT0FBTztBQUFBLEVBQzVDO0FBQ0o7QUFuRThDO0FBQXZDLElBQU0sTUFBTiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAncmVmbGVjdC1tZXRhZGF0YSdcbmltcG9ydCB7XG4gICAgQXN5bW1ldHJpY0VuY3J5cHRpb24sXG4gICAgQXN5bW1ldHJpY0VuY3J5cHRpb25LZXlQYWlyLCBBc3ltbWV0cmljRW5jcnlwdGlvblByaXZhdGUsXG4gICAgQXN5bW1ldHJpY0VuY3J5cHRpb25QdWJsaWNcbn0gZnJvbSAnLi4vYmFzZS9hYnN0cmFjdHMvQXN5bW1ldHJpY0VuY3J5cHRpb24uanMnXG5pbXBvcnQge3NtMn0gZnJvbSAnc20tY3J5cHRvLXYyJ1xuaW1wb3J0IHtBc30gZnJvbSAnLi4vLi4vVXRpbGl0aWVzLmpzJ1xuaW1wb3J0IHtQYXRoTGlrZX0gZnJvbSAnZnMnXG5pbXBvcnQge0lDb25zdHJ1Y3Rvcn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9JQ29uc3RydWN0b3IuanMnXG5cbmFzeW5jIGZ1bmN0aW9uIGluaXRSTkdQb29sKGNvbnN0cnVjdG9yOiBJQ29uc3RydWN0b3I8U00yPik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1ldGFkYXRhS2V5OiBzdHJpbmcgPSAnX18kJFJOR1Bvb2xJbml0aWFsaXplZCdcbiAgICBpZiAoUmVmbGVjdC5nZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgY29uc3RydWN0b3IpKSByZXR1cm5cbiAgICBhd2FpdCBzbTIuaW5pdFJOR1Bvb2woKVxuICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIHRydWUsIGNvbnN0cnVjdG9yKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNNMktleVBhaXJPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiDmmK/lkKblsIblhazpkqXplb/luqbov5vooYzljovnvKnvvIzku47pu5jorqTlhazpkqXnmoQxMzDkvY3ljovnvKnoh7M2NuS9jVxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgY29tcHJlc3NQdWJsaWNLZXk/OiBib29sZWFuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU00yT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICog5Yqg5a+G5qih5byPXG4gICAgICogMCAtIEMxQzJDM1xuICAgICAqIDEgLSBDMUMzQzJcbiAgICAgKiBAZGVmYXVsdCAxXG4gICAgICovXG4gICAgY2lwaGVyTW9kZT86IDAgfCAxXG4gICAgLyoqXG4gICAgICog5piv5ZCm5Zyo562+5ZCN5oiW6aqM562+5b2T5Lit5L2/55SoU00z5p2C5YeRXG4gICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAqL1xuICAgIHNpZ25hdHVyZVNNM0hhc2g/OiBib29sZWFuXG4gICAgLyoqXG4gICAgICog5Zyo562+5ZCN5oiW6aqM562+5b2T5Lit5L2/55So55qE55So5oi35qCH6K+GXG4gICAgICogQGRlZmF1bHQgdW5kZWZpbmVkXG4gICAgICovXG4gICAgc2lnbmF0dXJlVXNlcklkPzogc3RyaW5nXG59XG5cbmV4cG9ydCBjbGFzcyBTTTIgZXh0ZW5kcyBBc3ltbWV0cmljRW5jcnlwdGlvbiB7XG5cbiAgICBwcm90ZWN0ZWQgb3B0aW9uczogU00yT3B0aW9ucyA9IHtcbiAgICAgICAgY2lwaGVyTW9kZTogMSxcbiAgICAgICAgc2lnbmF0dXJlU00zSGFzaDogdHJ1ZSxcbiAgICAgICAgc2lnbmF0dXJlVXNlcklkOiB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgY3JlYXRlUHJpdmF0ZUtleShwcml2YXRlS2V5U3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gcHJpdmF0ZUtleVN0cmluZ1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBjcmVhdGVQdWJsaWNLZXkocHVibGljS2V5U3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gcHVibGljS2V5U3RyaW5nXG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGRlY3J5cHQoZW5jcnlwdGVkTWVzc2FnZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHNtMi5kb0RlY3J5cHQoQnVmZmVyLmZyb20oZW5jcnlwdGVkTWVzc2FnZSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKSwgdGhpcy5wcml2YXRlS2V5LCB0aGlzLm9wdGlvbnMuY2lwaGVyTW9kZSwge291dHB1dDogJ3N0cmluZyd9KVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBlbmNyeXB0KG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShzbTIuZG9FbmNyeXB0KG1lc3NhZ2UsIHRoaXMucHVibGljS2V5LCB0aGlzLm9wdGlvbnMuY2lwaGVyTW9kZSksICdoZXgnKS50b1N0cmluZygnYmFzZTY0JylcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgZ2VuZXJhdGVLZXlQYWlyKG9wdGlvbnM/OiBTTTJLZXlQYWlyT3B0aW9ucyk6IFByb21pc2U8QXN5bW1ldHJpY0VuY3J5cHRpb25LZXlQYWlyPiB7XG4gICAgICAgIGxldCB7cHVibGljS2V5LCBwcml2YXRlS2V5fSA9IHNtMi5nZW5lcmF0ZUtleVBhaXJIZXgoKVxuICAgICAgICBpZiAob3B0aW9ucz8uY29tcHJlc3NQdWJsaWNLZXkpIHB1YmxpY0tleSA9IHNtMi5jb21wcmVzc1B1YmxpY0tleUhleChwdWJsaWNLZXkpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBwdWJsaWNLZXk6IHB1YmxpY0tleSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHByaXZhdGVLZXlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBzaWduKG1lc3NhZ2U6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShzbTIuZG9TaWduYXR1cmUobWVzc2FnZSwgdGhpcy5wcml2YXRlS2V5LCB7XG4gICAgICAgICAgICBoYXNoOiB0aGlzLm9wdGlvbnMuc2lnbmF0dXJlU00zSGFzaCxcbiAgICAgICAgICAgIHB1YmxpY0tleTogdGhpcy5wdWJsaWNLZXkgPyB0aGlzLnB1YmxpY0tleSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVzZXJJZDogdGhpcy5vcHRpb25zLnNpZ25hdHVyZVVzZXJJZFxuICAgICAgICB9KSwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgIH1cblxuICAgIHByb3RlY3RlZCB2ZXJpZnkobWVzc2FnZTogc3RyaW5nLCBzaWduOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHNtMi5kb1ZlcmlmeVNpZ25hdHVyZShtZXNzYWdlLCBCdWZmZXIuZnJvbShzaWduLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLCB0aGlzLnB1YmxpY0tleSwge1xuICAgICAgICAgICAgaGFzaDogdGhpcy5vcHRpb25zLnNpZ25hdHVyZVNNM0hhc2gsXG4gICAgICAgICAgICB1c2VySWQ6IHRoaXMub3B0aW9ucy5zaWduYXR1cmVVc2VySWRcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGFzeW5jIGdlbmVyYXRlS2V5UGFpcihvcHRpb25zPzogU00yS2V5UGFpck9wdGlvbnMpOiBQcm9taXNlPEFzeW1tZXRyaWNFbmNyeXB0aW9uS2V5UGFpcj4ge1xuICAgICAgICBhd2FpdCBpbml0Uk5HUG9vbCh0aGlzKVxuICAgICAgICByZXR1cm4gc3VwZXIuZ2VuZXJhdGVLZXlQYWlyKG9wdGlvbnMpXG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBsb2FkS2V5UGFpcjxUIGV4dGVuZHMgQXN5bW1ldHJpY0VuY3J5cHRpb24gPSBTTTI+KGtleVBhaXI6IEFzeW1tZXRyaWNFbmNyeXB0aW9uS2V5UGFpciwgb3B0aW9ucz86IFNNMk9wdGlvbnMpOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgYXdhaXQgaW5pdFJOR1Bvb2wodGhpcylcbiAgICAgICAgcmV0dXJuIEFzPFQ+KHN1cGVyLmxvYWRLZXlQYWlyPFNNMj4oa2V5UGFpciwgb3B0aW9ucykpXG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBsb2FkUHVibGljS2V5KGlucDogUGF0aExpa2UgfCBzdHJpbmcsIG9wdGlvbnM/OiBTTTJPcHRpb25zKTogUHJvbWlzZTxBc3ltbWV0cmljRW5jcnlwdGlvblB1YmxpYz4ge1xuICAgICAgICBhd2FpdCBpbml0Uk5HUG9vbCh0aGlzKVxuICAgICAgICByZXR1cm4gc3VwZXIubG9hZFB1YmxpY0tleShpbnAsIG9wdGlvbnMpXG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBhc3luYyBsb2FkUHJpdmF0ZUtleShpbnA6IHN0cmluZyB8IFBhdGhMaWtlLCBvcHRpb25zPzogU00yT3B0aW9ucyk6IFByb21pc2U8QXN5bW1ldHJpY0VuY3J5cHRpb25Qcml2YXRlPiB7XG4gICAgICAgIGF3YWl0IGluaXRSTkdQb29sKHRoaXMpXG4gICAgICAgIHJldHVybiBzdXBlci5sb2FkUHJpdmF0ZUtleShpbnAsIG9wdGlvbnMpXG4gICAgfVxufVxuIiwidmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcbnZhciBfX2V4cG9ydCA9ICh0YXJnZXQsIGFsbCkgPT4ge1xuICBmb3IgKHZhciBuYW1lIGluIGFsbClcbiAgICBfX2RlZlByb3AodGFyZ2V0LCBuYW1lLCB7IGdldDogYWxsW25hbWVdLCBlbnVtZXJhYmxlOiB0cnVlIH0pO1xufTtcblxuLy8gc3JjL3NtMi9pbmRleC50c1xudmFyIHNtMl9leHBvcnRzID0ge307XG5fX2V4cG9ydChzbTJfZXhwb3J0cywge1xuICBFbXB0eUFycmF5OiAoKSA9PiBFbXB0eUFycmF5LFxuICBhcnJheVRvSGV4OiAoKSA9PiBhcnJheVRvSGV4LFxuICBhcnJheVRvVXRmODogKCkgPT4gYXJyYXlUb1V0ZjgsXG4gIGNhbGN1bGF0ZVNoYXJlZEtleTogKCkgPT4gY2FsY3VsYXRlU2hhcmVkS2V5LFxuICBjb21wYXJlUHVibGljS2V5SGV4OiAoKSA9PiBjb21wYXJlUHVibGljS2V5SGV4LFxuICBjb21wcmVzc1B1YmxpY0tleUhleDogKCkgPT4gY29tcHJlc3NQdWJsaWNLZXlIZXgsXG4gIGRvRGVjcnlwdDogKCkgPT4gZG9EZWNyeXB0LFxuICBkb0VuY3J5cHQ6ICgpID0+IGRvRW5jcnlwdCxcbiAgZG9TaWduYXR1cmU6ICgpID0+IGRvU2lnbmF0dXJlLFxuICBkb1ZlcmlmeVNpZ25hdHVyZTogKCkgPT4gZG9WZXJpZnlTaWduYXR1cmUsXG4gIGdlbmVyYXRlS2V5UGFpckhleDogKCkgPT4gZ2VuZXJhdGVLZXlQYWlySGV4LFxuICBnZXRIYXNoOiAoKSA9PiBnZXRIYXNoLFxuICBnZXRQb2ludDogKCkgPT4gZ2V0UG9pbnQsXG4gIGdldFB1YmxpY0tleUZyb21Qcml2YXRlS2V5OiAoKSA9PiBnZXRQdWJsaWNLZXlGcm9tUHJpdmF0ZUtleSxcbiAgZ2V0WjogKCkgPT4gZ2V0WixcbiAgaGV4VG9BcnJheTogKCkgPT4gaGV4VG9BcnJheSxcbiAgaW5pdFJOR1Bvb2w6ICgpID0+IGluaXRSTkdQb29sLFxuICBsZWZ0UGFkOiAoKSA9PiBsZWZ0UGFkLFxuICBwcmVjb21wdXRlUHVibGljS2V5OiAoKSA9PiBwcmVjb21wdXRlUHVibGljS2V5LFxuICB1dGY4VG9IZXg6ICgpID0+IHV0ZjhUb0hleCxcbiAgdmVyaWZ5UHVibGljS2V5OiAoKSA9PiB2ZXJpZnlQdWJsaWNLZXlcbn0pO1xuXG4vLyBzcmMvc20yL2FzbjEudHNcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gXCJAbm9ibGUvY3VydmVzL2Fic3RyYWN0L3V0aWxzXCI7XG5cbi8vIHNyYy9zbTIvYm4udHNcbnZhciBaRVJPID0gQmlnSW50KDApO1xudmFyIE9ORSA9IEJpZ0ludCgxKTtcbnZhciBUV08gPSBCaWdJbnQoMik7XG52YXIgVEhSRUUgPSBCaWdJbnQoMyk7XG5cbi8vIHNyYy9zbTIvYXNuMS50c1xuZnVuY3Rpb24gYmlnaW50VG9WYWx1ZShiaWdpbnQpIHtcbiAgbGV0IGggPSBiaWdpbnQudG9TdHJpbmcoMTYpO1xuICBpZiAoaFswXSAhPT0gXCItXCIpIHtcbiAgICBpZiAoaC5sZW5ndGggJSAyID09PSAxKVxuICAgICAgaCA9IFwiMFwiICsgaDtcbiAgICBlbHNlIGlmICghaC5tYXRjaCgvXlswLTddLykpXG4gICAgICBoID0gXCIwMFwiICsgaDtcbiAgfSBlbHNlIHtcbiAgICBoID0gaC5zdWJzdHJpbmcoMSk7XG4gICAgbGV0IGxlbiA9IGgubGVuZ3RoO1xuICAgIGlmIChsZW4gJSAyID09PSAxKVxuICAgICAgbGVuICs9IDE7XG4gICAgZWxzZSBpZiAoIWgubWF0Y2goL15bMC03XS8pKVxuICAgICAgbGVuICs9IDI7XG4gICAgbGV0IG1hc2tTdHJpbmcgPSBcIlwiO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBtYXNrU3RyaW5nICs9IFwiZlwiO1xuICAgIGxldCBtYXNrID0gdXRpbHMuaGV4VG9OdW1iZXIobWFza1N0cmluZyk7XG4gICAgbGV0IG91dHB1dCA9IChtYXNrIF4gYmlnaW50KSArIE9ORTtcbiAgICBoID0gb3V0cHV0LnRvU3RyaW5nKDE2KS5yZXBsYWNlKC9eLS8sIFwiXCIpO1xuICB9XG4gIHJldHVybiBoO1xufVxudmFyIEFTTjFPYmplY3QgPSBjbGFzcyB7XG4gIGNvbnN0cnVjdG9yKHRsdiA9IG51bGwsIHQgPSBcIjAwXCIsIGwgPSBcIjAwXCIsIHYgPSBcIlwiKSB7XG4gICAgdGhpcy50bHYgPSB0bHY7XG4gICAgdGhpcy50ID0gdDtcbiAgICB0aGlzLmwgPSBsO1xuICAgIHRoaXMudiA9IHY7XG4gIH1cbiAgZ2V0RW5jb2RlZEhleCgpIHtcbiAgICBpZiAoIXRoaXMudGx2KSB7XG4gICAgICB0aGlzLnYgPSB0aGlzLmdldFZhbHVlKCk7XG4gICAgICB0aGlzLmwgPSB0aGlzLmdldExlbmd0aCgpO1xuICAgICAgdGhpcy50bHYgPSB0aGlzLnQgKyB0aGlzLmwgKyB0aGlzLnY7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRsdjtcbiAgfVxuICBnZXRMZW5ndGgoKSB7XG4gICAgY29uc3QgbiA9IHRoaXMudi5sZW5ndGggLyAyO1xuICAgIGxldCBuSGV4ID0gbi50b1N0cmluZygxNik7XG4gICAgaWYgKG5IZXgubGVuZ3RoICUgMiA9PT0gMSlcbiAgICAgIG5IZXggPSBcIjBcIiArIG5IZXg7XG4gICAgaWYgKG4gPCAxMjgpIHtcbiAgICAgIHJldHVybiBuSGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoZWFkID0gMTI4ICsgbkhleC5sZW5ndGggLyAyO1xuICAgICAgcmV0dXJuIGhlYWQudG9TdHJpbmcoMTYpICsgbkhleDtcbiAgICB9XG4gIH1cbiAgZ2V0VmFsdWUoKSB7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbn07XG52YXIgREVSSW50ZWdlciA9IGNsYXNzIGV4dGVuZHMgQVNOMU9iamVjdCB7XG4gIGNvbnN0cnVjdG9yKGJpZ2ludCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy50ID0gXCIwMlwiO1xuICAgIGlmIChiaWdpbnQpXG4gICAgICB0aGlzLnYgPSBiaWdpbnRUb1ZhbHVlKGJpZ2ludCk7XG4gIH1cbiAgZ2V0VmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMudjtcbiAgfVxufTtcbnZhciBERVJTZXF1ZW5jZSA9IGNsYXNzIGV4dGVuZHMgQVNOMU9iamVjdCB7XG4gIGNvbnN0cnVjdG9yKGFzbjFBcnJheSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hc24xQXJyYXkgPSBhc24xQXJyYXk7XG4gIH1cbiAgdCA9IFwiMzBcIjtcbiAgZ2V0VmFsdWUoKSB7XG4gICAgdGhpcy52ID0gdGhpcy5hc24xQXJyYXkubWFwKChhc24xT2JqZWN0KSA9PiBhc24xT2JqZWN0LmdldEVuY29kZWRIZXgoKSkuam9pbihcIlwiKTtcbiAgICByZXR1cm4gdGhpcy52O1xuICB9XG59O1xuZnVuY3Rpb24gZ2V0TGVuT2ZMKHN0ciwgc3RhcnQpIHtcbiAgaWYgKCtzdHJbc3RhcnQgKyAyXSA8IDgpXG4gICAgcmV0dXJuIDE7XG4gIHJldHVybiArc3RyLnN1YnN0cmluZyhzdGFydCArIDIsIHN0YXJ0ICsgNCkgJiAxMjcgKyAxO1xufVxuZnVuY3Rpb24gZ2V0TChzdHIsIHN0YXJ0KSB7XG4gIGNvbnN0IGxlbiA9IGdldExlbk9mTChzdHIsIHN0YXJ0KTtcbiAgY29uc3QgbCA9IHN0ci5zdWJzdHJpbmcoc3RhcnQgKyAyLCBzdGFydCArIDIgKyBsZW4gKiAyKTtcbiAgaWYgKCFsKVxuICAgIHJldHVybiAtMTtcbiAgY29uc3QgYmlnaW50ID0gK2xbMF0gPCA4ID8gdXRpbHMuaGV4VG9OdW1iZXIobCkgOiB1dGlscy5oZXhUb051bWJlcihsLnN1YnN0cmluZygyKSk7XG4gIHJldHVybiArYmlnaW50LnRvU3RyaW5nKCk7XG59XG5mdW5jdGlvbiBnZXRTdGFydE9mVihzdHIsIHN0YXJ0KSB7XG4gIGNvbnN0IGxlbiA9IGdldExlbk9mTChzdHIsIHN0YXJ0KTtcbiAgcmV0dXJuIHN0YXJ0ICsgKGxlbiArIDEpICogMjtcbn1cbmZ1bmN0aW9uIGVuY29kZURlcihyLCBzKSB7XG4gIGNvbnN0IGRlclIgPSBuZXcgREVSSW50ZWdlcihyKTtcbiAgY29uc3QgZGVyUyA9IG5ldyBERVJJbnRlZ2VyKHMpO1xuICBjb25zdCBkZXJTZXEgPSBuZXcgREVSU2VxdWVuY2UoW2RlclIsIGRlclNdKTtcbiAgcmV0dXJuIGRlclNlcS5nZXRFbmNvZGVkSGV4KCk7XG59XG5mdW5jdGlvbiBkZWNvZGVEZXIoaW5wdXQpIHtcbiAgY29uc3Qgc3RhcnQgPSBnZXRTdGFydE9mVihpbnB1dCwgMCk7XG4gIGNvbnN0IHZJbmRleFIgPSBnZXRTdGFydE9mVihpbnB1dCwgc3RhcnQpO1xuICBjb25zdCBsUiA9IGdldEwoaW5wdXQsIHN0YXJ0KTtcbiAgY29uc3QgdlIgPSBpbnB1dC5zdWJzdHIodkluZGV4UiwgbFIgKiAyKTtcbiAgY29uc3QgbmV4dFN0YXJ0ID0gdkluZGV4UiArIHZSLmxlbmd0aDtcbiAgY29uc3QgdkluZGV4UyA9IGdldFN0YXJ0T2ZWKGlucHV0LCBuZXh0U3RhcnQpO1xuICBjb25zdCBsUyA9IGdldEwoaW5wdXQsIG5leHRTdGFydCk7XG4gIGNvbnN0IHZTID0gaW5wdXQuc3Vic3RyaW5nKHZJbmRleFMsIHZJbmRleFMgKyBsUyAqIDIpO1xuICBjb25zdCByID0gdXRpbHMuaGV4VG9OdW1iZXIodlIpO1xuICBjb25zdCBzID0gdXRpbHMuaGV4VG9OdW1iZXIodlMpO1xuICByZXR1cm4geyByLCBzIH07XG59XG5cbi8vIHNyYy9zbTIvdXRpbHMudHNcbmltcG9ydCAqIGFzIHV0aWxzMiBmcm9tIFwiQG5vYmxlL2N1cnZlcy9hYnN0cmFjdC91dGlsc1wiO1xuXG4vLyBzcmMvc20yL2VjLnRzXG5pbXBvcnQgeyB3ZWllcnN0cmFzcyB9IGZyb20gXCJAbm9ibGUvY3VydmVzL2Fic3RyYWN0L3dlaWVyc3RyYXNzXCI7XG5pbXBvcnQgeyBGaWVsZCB9IGZyb20gXCJAbm9ibGUvY3VydmVzL2Fic3RyYWN0L21vZHVsYXJcIjtcblxuLy8gc3JjL3NtMi9ybmcudHNcbnZhciBERUZBVUxUX1BSTkdfUE9PTF9TSVpFID0gMTYzODQ7XG52YXIgcHJuZ1Bvb2wgPSBuZXcgVWludDhBcnJheSgwKTtcbnZhciBfc3luY0NyeXB0bztcbmFzeW5jIGZ1bmN0aW9uIGluaXRSTkdQb29sKCkge1xuICBpZiAoXCJjcnlwdG9cIiBpbiBnbG9iYWxUaGlzKSB7XG4gICAgX3N5bmNDcnlwdG8gPSBnbG9iYWxUaGlzLmNyeXB0bztcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHBybmdQb29sLmxlbmd0aCA+IERFRkFVTFRfUFJOR19QT09MX1NJWkUgLyAyKVxuICAgIHJldHVybjtcbiAgaWYgKFwid3hcIiBpbiBnbG9iYWxUaGlzICYmIFwiZ2V0UmFuZG9tVmFsdWVzXCIgaW4gZ2xvYmFsVGhpcy53eCkge1xuICAgIHBybmdQb29sID0gYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHtcbiAgICAgIHd4LmdldFJhbmRvbVZhbHVlcyh7XG4gICAgICAgIGxlbmd0aDogREVGQVVMVF9QUk5HX1BPT0xfU0laRSxcbiAgICAgICAgc3VjY2VzcyhyZXMpIHtcbiAgICAgICAgICByKG5ldyBVaW50OEFycmF5KHJlcy5yYW5kb21WYWx1ZXMpKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChnbG9iYWxUaGlzLmNyeXB0bykge1xuICAgICAgICBfc3luY0NyeXB0byA9IGdsb2JhbFRoaXMuY3J5cHRvO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgY3J5cHRvID0gYXdhaXQgaW1wb3J0KFxuICAgICAgICAgIC8qIHdlYnBhY2tJZ25vcmU6IHRydWUgKi9cbiAgICAgICAgICBcImNyeXB0b1wiXG4gICAgICAgICk7XG4gICAgICAgIF9zeW5jQ3J5cHRvID0gY3J5cHRvLndlYmNyeXB0bztcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoREVGQVVMVF9QUk5HX1BPT0xfU0laRSk7XG4gICAgICBfc3luY0NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyYXkpO1xuICAgICAgcHJuZ1Bvb2wgPSBhcnJheTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm8gYXZhaWxhYmxlIGNzcHJuZywgYWJvcnQuXCIpO1xuICAgIH1cbiAgfVxufVxuaW5pdFJOR1Bvb2woKTtcbmZ1bmN0aW9uIGNvbnN1bWVQb29sKGxlbmd0aCkge1xuICBpZiAocHJuZ1Bvb2wubGVuZ3RoID4gbGVuZ3RoKSB7XG4gICAgY29uc3QgcHJuZyA9IHBybmdQb29sLnNsaWNlKDAsIGxlbmd0aCk7XG4gICAgcHJuZ1Bvb2wgPSBwcm5nUG9vbC5zbGljZShsZW5ndGgpO1xuICAgIGluaXRSTkdQb29sKCk7XG4gICAgcmV0dXJuIHBybmc7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwicmFuZG9tIG51bWJlciBwb29sIGlzIG5vdCByZWFkeSBvciBpbnN1ZmZpY2llbnQsIHByZXZlbnQgZ2V0dGluZyB0b28gbG9uZyByYW5kb20gdmFsdWVzIG9yIHRvbyBvZnRlbi5cIik7XG4gIH1cbn1cbmZ1bmN0aW9uIHJhbmRvbUJ5dGVzKGxlbmd0aCA9IDApIHtcbiAgY29uc3QgYXJyYXkgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICBpZiAoX3N5bmNDcnlwdG8pIHtcbiAgICByZXR1cm4gX3N5bmNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycmF5KTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCByZXN1bHQgPSBjb25zdW1lUG9vbChsZW5ndGgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cblxuLy8gc3JjL3NtMy91dGlscy50c1xudmFyIHU4YSA9IChhKSA9PiBhIGluc3RhbmNlb2YgVWludDhBcnJheTtcbnZhciBjcmVhdGVWaWV3ID0gKGFycikgPT4gbmV3IERhdGFWaWV3KGFyci5idWZmZXIsIGFyci5ieXRlT2Zmc2V0LCBhcnIuYnl0ZUxlbmd0aCk7XG52YXIgaXNMRSA9IG5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXSA9PT0gNjg7XG5pZiAoIWlzTEUpXG4gIHRocm93IG5ldyBFcnJvcihcIk5vbiBsaXR0bGUtZW5kaWFuIGhhcmR3YXJlIGlzIG5vdCBzdXBwb3J0ZWRcIik7XG52YXIgaGV4ZXMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiAyNTYgfSwgKHYsIGkpID0+IGkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKSk7XG5mdW5jdGlvbiBieXRlc1RvSGV4KGJ5dGVzKSB7XG4gIGlmICghdThhKGJ5dGVzKSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJVaW50OEFycmF5IGV4cGVjdGVkXCIpO1xuICBsZXQgaGV4ID0gXCJcIjtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgIGhleCArPSBoZXhlc1tieXRlc1tpXV07XG4gIH1cbiAgcmV0dXJuIGhleDtcbn1cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzKHN0cikge1xuICBpZiAodHlwZW9mIHN0ciAhPT0gXCJzdHJpbmdcIilcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHV0ZjhUb0J5dGVzIGV4cGVjdGVkIHN0cmluZywgZ290ICR7dHlwZW9mIHN0cn1gKTtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzdHIpKTtcbn1cbmZ1bmN0aW9uIHRvQnl0ZXMoZGF0YSkge1xuICBpZiAodHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIpXG4gICAgZGF0YSA9IHV0ZjhUb0J5dGVzKGRhdGEpO1xuICBpZiAoIXU4YShkYXRhKSlcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGV4cGVjdGVkIFVpbnQ4QXJyYXksIGdvdCAke3R5cGVvZiBkYXRhfWApO1xuICByZXR1cm4gZGF0YTtcbn1cbnZhciBIYXNoID0gY2xhc3Mge1xuICBjbG9uZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY2xvbmVJbnRvKCk7XG4gIH1cbn07XG5mdW5jdGlvbiB3cmFwQ29uc3RydWN0b3IoaGFzaENvbnMpIHtcbiAgY29uc3QgaGFzaEMgPSAobXNnKSA9PiBoYXNoQ29ucygpLnVwZGF0ZSh0b0J5dGVzKG1zZykpLmRpZ2VzdCgpO1xuICBjb25zdCB0bXAyID0gaGFzaENvbnMoKTtcbiAgaGFzaEMub3V0cHV0TGVuID0gdG1wMi5vdXRwdXRMZW47XG4gIGhhc2hDLmJsb2NrTGVuID0gdG1wMi5ibG9ja0xlbjtcbiAgaGFzaEMuY3JlYXRlID0gKCkgPT4gaGFzaENvbnMoKTtcbiAgcmV0dXJuIGhhc2hDO1xufVxuXG4vLyBzcmMvc20yL3NtMy50c1xudmFyIEJvb2xBID0gKEEsIEIsIEMpID0+IEEgJiBCIHwgQSAmIEMgfCBCICYgQztcbnZhciBCb29sQiA9IChBLCBCLCBDKSA9PiBBIF4gQiBeIEM7XG52YXIgQm9vbEMgPSAoQSwgQiwgQykgPT4gQSAmIEIgfCB+QSAmIEM7XG5mdW5jdGlvbiBzZXRCaWdVaW50NjQodmlldywgYnl0ZU9mZnNldCwgdmFsdWUsIGlzTEUyKSB7XG4gIGlmICh0eXBlb2Ygdmlldy5zZXRCaWdVaW50NjQgPT09IFwiZnVuY3Rpb25cIilcbiAgICByZXR1cm4gdmlldy5zZXRCaWdVaW50NjQoYnl0ZU9mZnNldCwgdmFsdWUsIGlzTEUyKTtcbiAgY29uc3QgXzMybiA9IEJpZ0ludCgzMik7XG4gIGNvbnN0IF91MzJfbWF4ID0gQmlnSW50KDQyOTQ5NjcyOTUpO1xuICBjb25zdCB3aCA9IE51bWJlcih2YWx1ZSA+PiBfMzJuICYgX3UzMl9tYXgpO1xuICBjb25zdCB3bCA9IE51bWJlcih2YWx1ZSAmIF91MzJfbWF4KTtcbiAgY29uc3QgaCA9IGlzTEUyID8gNCA6IDA7XG4gIGNvbnN0IGwgPSBpc0xFMiA/IDAgOiA0O1xuICB2aWV3LnNldFVpbnQzMihieXRlT2Zmc2V0ICsgaCwgd2gsIGlzTEUyKTtcbiAgdmlldy5zZXRVaW50MzIoYnl0ZU9mZnNldCArIGwsIHdsLCBpc0xFMik7XG59XG5mdW5jdGlvbiByb3RsKHgyLCBuKSB7XG4gIGNvbnN0IHMgPSBuICYgMzE7XG4gIHJldHVybiB4MiA8PCBzIHwgeDIgPj4+IDMyIC0gcztcbn1cbmZ1bmN0aW9uIFAwKFgpIHtcbiAgcmV0dXJuIFggXiByb3RsKFgsIDkpIF4gcm90bChYLCAxNyk7XG59XG5mdW5jdGlvbiBQMShYKSB7XG4gIHJldHVybiBYIF4gcm90bChYLCAxNSkgXiByb3RsKFgsIDIzKTtcbn1cbnZhciBTSEEyID0gY2xhc3MgZXh0ZW5kcyBIYXNoIHtcbiAgY29uc3RydWN0b3IoYmxvY2tMZW4sIG91dHB1dExlbiwgcGFkT2Zmc2V0LCBpc0xFMikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5ibG9ja0xlbiA9IGJsb2NrTGVuO1xuICAgIHRoaXMub3V0cHV0TGVuID0gb3V0cHV0TGVuO1xuICAgIHRoaXMucGFkT2Zmc2V0ID0gcGFkT2Zmc2V0O1xuICAgIHRoaXMuaXNMRSA9IGlzTEUyO1xuICAgIHRoaXMuYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoYmxvY2tMZW4pO1xuICAgIHRoaXMudmlldyA9IGNyZWF0ZVZpZXcodGhpcy5idWZmZXIpO1xuICB9XG4gIGJ1ZmZlcjtcbiAgdmlldztcbiAgZmluaXNoZWQgPSBmYWxzZTtcbiAgbGVuZ3RoID0gMDtcbiAgcG9zID0gMDtcbiAgZGVzdHJveWVkID0gZmFsc2U7XG4gIHVwZGF0ZShkYXRhKSB7XG4gICAgY29uc3QgeyB2aWV3LCBidWZmZXIsIGJsb2NrTGVuIH0gPSB0aGlzO1xuICAgIGRhdGEgPSB0b0J5dGVzKGRhdGEpO1xuICAgIGNvbnN0IGxlbiA9IGRhdGEubGVuZ3RoO1xuICAgIGZvciAobGV0IHBvcyA9IDA7IHBvcyA8IGxlbjsgKSB7XG4gICAgICBjb25zdCB0YWtlID0gTWF0aC5taW4oYmxvY2tMZW4gLSB0aGlzLnBvcywgbGVuIC0gcG9zKTtcbiAgICAgIGlmICh0YWtlID09PSBibG9ja0xlbikge1xuICAgICAgICBjb25zdCBkYXRhVmlldyA9IGNyZWF0ZVZpZXcoZGF0YSk7XG4gICAgICAgIGZvciAoOyBibG9ja0xlbiA8PSBsZW4gLSBwb3M7IHBvcyArPSBibG9ja0xlbilcbiAgICAgICAgICB0aGlzLnByb2Nlc3MoZGF0YVZpZXcsIHBvcyk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnVmZmVyLnNldChkYXRhLnN1YmFycmF5KHBvcywgcG9zICsgdGFrZSksIHRoaXMucG9zKTtcbiAgICAgIHRoaXMucG9zICs9IHRha2U7XG4gICAgICBwb3MgKz0gdGFrZTtcbiAgICAgIGlmICh0aGlzLnBvcyA9PT0gYmxvY2tMZW4pIHtcbiAgICAgICAgdGhpcy5wcm9jZXNzKHZpZXcsIDApO1xuICAgICAgICB0aGlzLnBvcyA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubGVuZ3RoICs9IGRhdGEubGVuZ3RoO1xuICAgIHRoaXMucm91bmRDbGVhbigpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGRpZ2VzdEludG8ob3V0KSB7XG4gICAgdGhpcy5maW5pc2hlZCA9IHRydWU7XG4gICAgY29uc3QgeyBidWZmZXIsIHZpZXcsIGJsb2NrTGVuLCBpc0xFOiBpc0xFMiB9ID0gdGhpcztcbiAgICBsZXQgeyBwb3MgfSA9IHRoaXM7XG4gICAgYnVmZmVyW3BvcysrXSA9IDEyODtcbiAgICB0aGlzLmJ1ZmZlci5zdWJhcnJheShwb3MpLmZpbGwoMCk7XG4gICAgaWYgKHRoaXMucGFkT2Zmc2V0ID4gYmxvY2tMZW4gLSBwb3MpIHtcbiAgICAgIHRoaXMucHJvY2Vzcyh2aWV3LCAwKTtcbiAgICAgIHBvcyA9IDA7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBwb3M7IGkgPCBibG9ja0xlbjsgaSsrKVxuICAgICAgYnVmZmVyW2ldID0gMDtcbiAgICBzZXRCaWdVaW50NjQodmlldywgYmxvY2tMZW4gLSA4LCBCaWdJbnQodGhpcy5sZW5ndGggKiA4KSwgaXNMRTIpO1xuICAgIHRoaXMucHJvY2Vzcyh2aWV3LCAwKTtcbiAgICBjb25zdCBvdmlldyA9IGNyZWF0ZVZpZXcob3V0KTtcbiAgICBjb25zdCBsZW4gPSB0aGlzLm91dHB1dExlbjtcbiAgICBpZiAobGVuICUgNClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIl9zaGEyOiBvdXRwdXRMZW4gc2hvdWxkIGJlIGFsaWduZWQgdG8gMzJiaXRcIik7XG4gICAgY29uc3Qgb3V0TGVuID0gbGVuIC8gNDtcbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuZ2V0KCk7XG4gICAgaWYgKG91dExlbiA+IHN0YXRlLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIl9zaGEyOiBvdXRwdXRMZW4gYmlnZ2VyIHRoYW4gc3RhdGVcIik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRMZW47IGkrKylcbiAgICAgIG92aWV3LnNldFVpbnQzMig0ICogaSwgc3RhdGVbaV0sIGlzTEUyKTtcbiAgfVxuICBkaWdlc3QoKSB7XG4gICAgY29uc3QgeyBidWZmZXIsIG91dHB1dExlbiB9ID0gdGhpcztcbiAgICB0aGlzLmRpZ2VzdEludG8oYnVmZmVyKTtcbiAgICBjb25zdCByZXMgPSBidWZmZXIuc2xpY2UoMCwgb3V0cHV0TGVuKTtcbiAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICByZXR1cm4gcmVzO1xuICB9XG4gIF9jbG9uZUludG8odG8pIHtcbiAgICB0byB8fD0gbmV3IHRoaXMuY29uc3RydWN0b3IoKTtcbiAgICB0by5zZXQoLi4udGhpcy5nZXQoKSk7XG4gICAgY29uc3QgeyBibG9ja0xlbiwgYnVmZmVyLCBsZW5ndGgsIGZpbmlzaGVkLCBkZXN0cm95ZWQsIHBvcyB9ID0gdGhpcztcbiAgICB0by5sZW5ndGggPSBsZW5ndGg7XG4gICAgdG8ucG9zID0gcG9zO1xuICAgIHRvLmZpbmlzaGVkID0gZmluaXNoZWQ7XG4gICAgdG8uZGVzdHJveWVkID0gZGVzdHJveWVkO1xuICAgIGlmIChsZW5ndGggJSBibG9ja0xlbilcbiAgICAgIHRvLmJ1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICByZXR1cm4gdG87XG4gIH1cbn07XG52YXIgSVYgPSBuZXcgVWludDMyQXJyYXkoWzE5Mzc3NzQxOTEsIDEyMjYwOTMyNDEsIDM4ODI1MjM3NSwgMzY2NjQ3ODU5MiwgMjg0MjYzNjQ3NiwgMzcyMzI0NTIyLCAzODE3NzI5NjEzLCAyOTY5MjQzMjE0XSk7XG52YXIgU00zX1cgPSBuZXcgVWludDMyQXJyYXkoNjgpO1xudmFyIFNNM19NID0gbmV3IFVpbnQzMkFycmF5KDY0KTtcbnZhciBUMSA9IDIwNDM0MzAxNjk7XG52YXIgVDIgPSAyMDU1NzA4MDQyO1xudmFyIFNNMyA9IGNsYXNzIGV4dGVuZHMgU0hBMiB7XG4gIEEgPSBJVlswXSB8IDA7XG4gIEIgPSBJVlsxXSB8IDA7XG4gIEMgPSBJVlsyXSB8IDA7XG4gIEQgPSBJVlszXSB8IDA7XG4gIEUgPSBJVls0XSB8IDA7XG4gIEYgPSBJVls1XSB8IDA7XG4gIEcgPSBJVls2XSB8IDA7XG4gIEggPSBJVls3XSB8IDA7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKDY0LCAzMiwgOCwgZmFsc2UpO1xuICB9XG4gIGdldCgpIHtcbiAgICBjb25zdCB7IEEsIEIsIEMsIEQsIEUsIEYsIEcsIEggfSA9IHRoaXM7XG4gICAgcmV0dXJuIFtBLCBCLCBDLCBELCBFLCBGLCBHLCBIXTtcbiAgfVxuICBzZXQoQSwgQiwgQywgRCwgRSwgRiwgRywgSCkge1xuICAgIHRoaXMuQSA9IEEgfCAwO1xuICAgIHRoaXMuQiA9IEIgfCAwO1xuICAgIHRoaXMuQyA9IEMgfCAwO1xuICAgIHRoaXMuRCA9IEQgfCAwO1xuICAgIHRoaXMuRSA9IEUgfCAwO1xuICAgIHRoaXMuRiA9IEYgfCAwO1xuICAgIHRoaXMuRyA9IEcgfCAwO1xuICAgIHRoaXMuSCA9IEggfCAwO1xuICB9XG4gIHByb2Nlc3Modmlldywgb2Zmc2V0KSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxNjsgaSsrLCBvZmZzZXQgKz0gNClcbiAgICAgIFNNM19XW2ldID0gdmlldy5nZXRVaW50MzIob2Zmc2V0LCBmYWxzZSk7XG4gICAgZm9yIChsZXQgaSA9IDE2OyBpIDwgNjg7IGkrKykge1xuICAgICAgU00zX1dbaV0gPSBQMShTTTNfV1tpIC0gMTZdIF4gU00zX1dbaSAtIDldIF4gcm90bChTTTNfV1tpIC0gM10sIDE1KSkgXiByb3RsKFNNM19XW2kgLSAxM10sIDcpIF4gU00zX1dbaSAtIDZdO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY0OyBpKyspIHtcbiAgICAgIFNNM19NW2ldID0gU00zX1dbaV0gXiBTTTNfV1tpICsgNF07XG4gICAgfVxuICAgIGxldCB7IEEsIEIsIEMsIEQsIEUsIEYsIEcsIEggfSA9IHRoaXM7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCA2NDsgaisrKSB7XG4gICAgICBsZXQgc21hbGwgPSBqID49IDAgJiYgaiA8PSAxNTtcbiAgICAgIGxldCBUID0gc21hbGwgPyBUMSA6IFQyO1xuICAgICAgbGV0IFNTMSA9IHJvdGwocm90bChBLCAxMikgKyBFICsgcm90bChULCBqKSwgNyk7XG4gICAgICBsZXQgU1MyID0gU1MxIF4gcm90bChBLCAxMik7XG4gICAgICBsZXQgVFQxID0gKHNtYWxsID8gQm9vbEIoQSwgQiwgQykgOiBCb29sQShBLCBCLCBDKSkgKyBEICsgU1MyICsgU00zX01bal0gfCAwO1xuICAgICAgbGV0IFRUMiA9IChzbWFsbCA/IEJvb2xCKEUsIEYsIEcpIDogQm9vbEMoRSwgRiwgRykpICsgSCArIFNTMSArIFNNM19XW2pdIHwgMDtcbiAgICAgIEQgPSBDO1xuICAgICAgQyA9IHJvdGwoQiwgOSk7XG4gICAgICBCID0gQTtcbiAgICAgIEEgPSBUVDE7XG4gICAgICBIID0gRztcbiAgICAgIEcgPSByb3RsKEYsIDE5KTtcbiAgICAgIEYgPSBFO1xuICAgICAgRSA9IFAwKFRUMik7XG4gICAgfVxuICAgIEEgPSBBIF4gdGhpcy5BIHwgMDtcbiAgICBCID0gQiBeIHRoaXMuQiB8IDA7XG4gICAgQyA9IEMgXiB0aGlzLkMgfCAwO1xuICAgIEQgPSBEIF4gdGhpcy5EIHwgMDtcbiAgICBFID0gRSBeIHRoaXMuRSB8IDA7XG4gICAgRiA9IEYgXiB0aGlzLkYgfCAwO1xuICAgIEcgPSBHIF4gdGhpcy5HIHwgMDtcbiAgICBIID0gSCBeIHRoaXMuSCB8IDA7XG4gICAgdGhpcy5zZXQoQSwgQiwgQywgRCwgRSwgRiwgRywgSCk7XG4gIH1cbiAgcm91bmRDbGVhbigpIHtcbiAgICBTTTNfVy5maWxsKDApO1xuICB9XG4gIGRlc3Ryb3koKSB7XG4gICAgdGhpcy5zZXQoMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCk7XG4gICAgdGhpcy5idWZmZXIuZmlsbCgwKTtcbiAgfVxufTtcbnZhciBzbTMgPSB3cmFwQ29uc3RydWN0b3IoKCkgPT4gbmV3IFNNMygpKTtcblxuLy8gc3JjL3NtMi9obWFjLnRzXG52YXIgSE1BQyA9IGNsYXNzIGV4dGVuZHMgSGFzaCB7XG4gIG9IYXNoO1xuICBpSGFzaDtcbiAgYmxvY2tMZW47XG4gIG91dHB1dExlbjtcbiAgZmluaXNoZWQgPSBmYWxzZTtcbiAgZGVzdHJveWVkID0gZmFsc2U7XG4gIGNvbnN0cnVjdG9yKGhhc2gsIF9rZXkpIHtcbiAgICBzdXBlcigpO1xuICAgIGNvbnN0IGtleSA9IHRvQnl0ZXMoX2tleSk7XG4gICAgdGhpcy5pSGFzaCA9IGhhc2guY3JlYXRlKCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmlIYXNoLnVwZGF0ZSAhPT0gXCJmdW5jdGlvblwiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgaW5zdGFuY2Ugb2YgY2xhc3Mgd2hpY2ggZXh0ZW5kcyB1dGlscy5IYXNoXCIpO1xuICAgIHRoaXMuYmxvY2tMZW4gPSB0aGlzLmlIYXNoLmJsb2NrTGVuO1xuICAgIHRoaXMub3V0cHV0TGVuID0gdGhpcy5pSGFzaC5vdXRwdXRMZW47XG4gICAgY29uc3QgYmxvY2tMZW4gPSB0aGlzLmJsb2NrTGVuO1xuICAgIGNvbnN0IHBhZCA9IG5ldyBVaW50OEFycmF5KGJsb2NrTGVuKTtcbiAgICBwYWQuc2V0KGtleS5sZW5ndGggPiBibG9ja0xlbiA/IGhhc2guY3JlYXRlKCkudXBkYXRlKGtleSkuZGlnZXN0KCkgOiBrZXkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFkLmxlbmd0aDsgaSsrKVxuICAgICAgcGFkW2ldIF49IDU0O1xuICAgIHRoaXMuaUhhc2gudXBkYXRlKHBhZCk7XG4gICAgdGhpcy5vSGFzaCA9IGhhc2guY3JlYXRlKCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYWQubGVuZ3RoOyBpKyspXG4gICAgICBwYWRbaV0gXj0gNTQgXiA5MjtcbiAgICB0aGlzLm9IYXNoLnVwZGF0ZShwYWQpO1xuICAgIHBhZC5maWxsKDApO1xuICB9XG4gIHVwZGF0ZShidWYpIHtcbiAgICB0aGlzLmlIYXNoLnVwZGF0ZShidWYpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIGRpZ2VzdEludG8ob3V0KSB7XG4gICAgdGhpcy5maW5pc2hlZCA9IHRydWU7XG4gICAgdGhpcy5pSGFzaC5kaWdlc3RJbnRvKG91dCk7XG4gICAgdGhpcy5vSGFzaC51cGRhdGUob3V0KTtcbiAgICB0aGlzLm9IYXNoLmRpZ2VzdEludG8ob3V0KTtcbiAgICB0aGlzLmRlc3Ryb3koKTtcbiAgfVxuICBkaWdlc3QoKSB7XG4gICAgY29uc3Qgb3V0ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5vSGFzaC5vdXRwdXRMZW4pO1xuICAgIHRoaXMuZGlnZXN0SW50byhvdXQpO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cbiAgX2Nsb25lSW50byh0bykge1xuICAgIHRvIHx8PSBPYmplY3QuY3JlYXRlKE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSwge30pO1xuICAgIGNvbnN0IHsgb0hhc2gsIGlIYXNoLCBmaW5pc2hlZCwgZGVzdHJveWVkLCBibG9ja0xlbiwgb3V0cHV0TGVuIH0gPSB0aGlzO1xuICAgIHRvID0gdG87XG4gICAgdG8uZmluaXNoZWQgPSBmaW5pc2hlZDtcbiAgICB0by5kZXN0cm95ZWQgPSBkZXN0cm95ZWQ7XG4gICAgdG8uYmxvY2tMZW4gPSBibG9ja0xlbjtcbiAgICB0by5vdXRwdXRMZW4gPSBvdXRwdXRMZW47XG4gICAgdG8ub0hhc2ggPSBvSGFzaC5fY2xvbmVJbnRvKHRvLm9IYXNoKTtcbiAgICB0by5pSGFzaCA9IGlIYXNoLl9jbG9uZUludG8odG8uaUhhc2gpO1xuICAgIHJldHVybiB0bztcbiAgfVxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZTtcbiAgICB0aGlzLm9IYXNoLmRlc3Ryb3koKTtcbiAgICB0aGlzLmlIYXNoLmRlc3Ryb3koKTtcbiAgfVxufTtcbnZhciBobWFjID0gKGhhc2gsIGtleSwgbWVzc2FnZSkgPT4gbmV3IEhNQUMoaGFzaCwga2V5KS51cGRhdGUobWVzc2FnZSkuZGlnZXN0KCk7XG5obWFjLmNyZWF0ZSA9IChoYXNoLCBrZXkpID0+IG5ldyBITUFDKGhhc2gsIGtleSk7XG5cbi8vIHNyYy9zbTIvZWMudHNcbmltcG9ydCB7IGNvbmNhdEJ5dGVzIH0gZnJvbSBcIkBub2JsZS9jdXJ2ZXMvYWJzdHJhY3QvdXRpbHNcIjtcbnZhciBzbTJGcCA9IEZpZWxkKEJpZ0ludChcIjExNTc5MjA4OTIxMDM1NjI0ODc1NjQyMDM0NTIxNDAyMDg5Mjc2NjI1MDM1Mzk5MTkyNDE5MTQ1NDQyMTE5MzkzMzI4OTY4NDk5MTk5OVwiKSk7XG52YXIgc20yQ3VydmUgPSB3ZWllcnN0cmFzcyh7XG4gIGE6IEJpZ0ludChcIjExNTc5MjA4OTIxMDM1NjI0ODc1NjQyMDM0NTIxNDAyMDg5Mjc2NjI1MDM1Mzk5MTkyNDE5MTQ1NDQyMTE5MzkzMzI4OTY4NDk5MTk5NlwiKSxcbiAgYjogQmlnSW50KFwiMTg1MDU5MTkwMjIyODE4ODAxMTMwNzI5ODE4Mjc5NTU2MzkyMjE0NTg0NDg1NzgwMTIwNzUyNTQ4NTczNDYxOTYxMDMwNjkxNzU0NDNcIiksXG4gIEZwOiBzbTJGcCxcbiAgaDogT05FLFxuICBuOiBCaWdJbnQoXCIxMTU3OTIwODkyMTAzNTYyNDg3NTY0MjAzNDUyMTQwMjA4OTI3NjYwNjE2MjM3MjQ5NTc3NDQ1Njc4NDM4MDkzNTYyOTM0MzkwNDU5MjNcIiksXG4gIEd4OiBCaWdJbnQoXCIyMjk2MzE0NjU0NzIzNzA1MDU1OTQ3OTUzMTM2MjU1MDA3NDU3ODgwMjU2NzI5NTM0MTYxNjk3MDM3NTE5NDg0MDYwNDEzOTYxNTQzMVwiKSxcbiAgR3k6IEJpZ0ludChcIjg1MTMyMzY5MjA5ODI4NTY4ODI1NjE4OTkwNjE3MTEyNDk2NDEzMDg4Mzg4NjMxOTA0NTA1MDgzMjgzNTM2NjA3NTg4ODc3MjAxNTY4XCIpLFxuICBoYXNoOiBzbTMsXG4gIGhtYWM6IChrZXksIC4uLm1zZ3MpID0+IGhtYWMoc20zLCBrZXksIGNvbmNhdEJ5dGVzKC4uLm1zZ3MpKSxcbiAgcmFuZG9tQnl0ZXNcbn0pO1xudmFyIGZpZWxkID0gRmllbGQoQmlnSW50KHNtMkN1cnZlLkNVUlZFLm4pKTtcblxuLy8gc3JjL3NtMi91dGlscy50c1xuaW1wb3J0IHsgbW9kIH0gZnJvbSBcIkBub2JsZS9jdXJ2ZXMvYWJzdHJhY3QvbW9kdWxhclwiO1xuZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlySGV4KHN0cikge1xuICBjb25zdCBwcml2YXRlS2V5ID0gc3RyID8gdXRpbHMyLm51bWJlclRvQnl0ZXNCRShtb2QoQmlnSW50KHN0ciksIE9ORSkgKyBPTkUsIDMyKSA6IHNtMkN1cnZlLnV0aWxzLnJhbmRvbVByaXZhdGVLZXkoKTtcbiAgY29uc3QgcHVibGljS2V5ID0gc20yQ3VydmUuZ2V0UHVibGljS2V5KHByaXZhdGVLZXksIGZhbHNlKTtcbiAgY29uc3QgcHJpdlBhZCA9IGxlZnRQYWQodXRpbHMyLmJ5dGVzVG9IZXgocHJpdmF0ZUtleSksIDY0KTtcbiAgY29uc3QgcHViUGFkID0gbGVmdFBhZCh1dGlsczIuYnl0ZXNUb0hleChwdWJsaWNLZXkpLCA2NCk7XG4gIHJldHVybiB7IHByaXZhdGVLZXk6IHByaXZQYWQsIHB1YmxpY0tleTogcHViUGFkIH07XG59XG5mdW5jdGlvbiBjb21wcmVzc1B1YmxpY0tleUhleChzKSB7XG4gIGlmIChzLmxlbmd0aCAhPT0gMTMwKVxuICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcHVibGljIGtleSB0byBjb21wcmVzc1wiKTtcbiAgY29uc3QgbGVuID0gKHMubGVuZ3RoIC0gMikgLyAyO1xuICBjb25zdCB4SGV4ID0gcy5zdWJzdHJpbmcoMiwgMiArIGxlbik7XG4gIGNvbnN0IHkgPSB1dGlsczIuaGV4VG9OdW1iZXIocy5zdWJzdHJpbmcobGVuICsgMiwgbGVuICsgbGVuICsgMikpO1xuICBsZXQgcHJlZml4ID0gXCIwM1wiO1xuICBpZiAobW9kKHksIFRXTykgPT09IFpFUk8pXG4gICAgcHJlZml4ID0gXCIwMlwiO1xuICByZXR1cm4gcHJlZml4ICsgeEhleDtcbn1cbmZ1bmN0aW9uIHV0ZjhUb0hleChpbnB1dCkge1xuICBpbnB1dCA9IGRlY29kZVVSSUNvbXBvbmVudChlbmNvZGVVUklDb21wb25lbnQoaW5wdXQpKTtcbiAgY29uc3QgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICBjb25zdCB3b3JkcyA9IG5ldyBVaW50MzJBcnJheSgobGVuZ3RoID4+PiAyKSArIDEpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgd29yZHNbaSA+Pj4gMl0gfD0gKGlucHV0LmNoYXJDb2RlQXQoaSkgJiAyNTUpIDw8IDI0IC0gaSAlIDQgKiA4O1xuICB9XG4gIGNvbnN0IGhleENoYXJzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBiaXRlID0gd29yZHNbaSA+Pj4gMl0gPj4+IDI0IC0gaSAlIDQgKiA4ICYgMjU1O1xuICAgIGhleENoYXJzLnB1c2goKGJpdGUgPj4+IDQpLnRvU3RyaW5nKDE2KSk7XG4gICAgaGV4Q2hhcnMucHVzaCgoYml0ZSAmIDE1KS50b1N0cmluZygxNikpO1xuICB9XG4gIHJldHVybiBoZXhDaGFycy5qb2luKFwiXCIpO1xufVxuZnVuY3Rpb24gbGVmdFBhZChpbnB1dCwgbnVtKSB7XG4gIGlmIChpbnB1dC5sZW5ndGggPj0gbnVtKVxuICAgIHJldHVybiBpbnB1dDtcbiAgcmV0dXJuIG5ldyBBcnJheShudW0gLSBpbnB1dC5sZW5ndGggKyAxKS5qb2luKFwiMFwiKSArIGlucHV0O1xufVxuZnVuY3Rpb24gYXJyYXlUb0hleChhcnIpIHtcbiAgcmV0dXJuIGFyci5tYXAoKGl0ZW0pID0+IHtcbiAgICBjb25zdCBoZXggPSBpdGVtLnRvU3RyaW5nKDE2KTtcbiAgICByZXR1cm4gaGV4Lmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaGV4IDogaGV4O1xuICB9KS5qb2luKFwiXCIpO1xufVxuZnVuY3Rpb24gYXJyYXlUb1V0ZjgoYXJyKSB7XG4gIGNvbnN0IHN0ciA9IFtdO1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gYXJyLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGFycltpXSA+PSAyNDAgJiYgYXJyW2ldIDw9IDI0Nykge1xuICAgICAgc3RyLnB1c2goU3RyaW5nLmZyb21Db2RlUG9pbnQoKChhcnJbaV0gJiA3KSA8PCAxOCkgKyAoKGFycltpICsgMV0gJiA2MykgPDwgMTIpICsgKChhcnJbaSArIDJdICYgNjMpIDw8IDYpICsgKGFycltpICsgM10gJiA2MykpKTtcbiAgICAgIGkgKz0gMztcbiAgICB9IGVsc2UgaWYgKGFycltpXSA+PSAyMjQgJiYgYXJyW2ldIDw9IDIzOSkge1xuICAgICAgc3RyLnB1c2goU3RyaW5nLmZyb21Db2RlUG9pbnQoKChhcnJbaV0gJiAxNSkgPDwgMTIpICsgKChhcnJbaSArIDFdICYgNjMpIDw8IDYpICsgKGFycltpICsgMl0gJiA2MykpKTtcbiAgICAgIGkgKz0gMjtcbiAgICB9IGVsc2UgaWYgKGFycltpXSA+PSAxOTIgJiYgYXJyW2ldIDw9IDIyMykge1xuICAgICAgc3RyLnB1c2goU3RyaW5nLmZyb21Db2RlUG9pbnQoKChhcnJbaV0gJiAzMSkgPDwgNikgKyAoYXJyW2kgKyAxXSAmIDYzKSkpO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIucHVzaChTdHJpbmcuZnJvbUNvZGVQb2ludChhcnJbaV0pKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0ci5qb2luKFwiXCIpO1xufVxuZnVuY3Rpb24gaGV4VG9BcnJheShoZXhTdHIpIHtcbiAgbGV0IGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG4gIGlmIChoZXhTdHJMZW5ndGggJSAyICE9PSAwKSB7XG4gICAgaGV4U3RyID0gbGVmdFBhZChoZXhTdHIsIGhleFN0ckxlbmd0aCArIDEpO1xuICB9XG4gIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG4gIGNvbnN0IHdvcmRMZW5ndGggPSBoZXhTdHJMZW5ndGggLyAyO1xuICBjb25zdCB3b3JkcyA9IG5ldyBVaW50OEFycmF5KHdvcmRMZW5ndGgpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHdvcmRMZW5ndGg7IGkrKykge1xuICAgIHdvcmRzW2ldID0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cmluZyhpICogMiwgaSAqIDIgKyAyKSwgMTYpO1xuICB9XG4gIHJldHVybiB3b3Jkcztcbn1cbmZ1bmN0aW9uIHZlcmlmeVB1YmxpY0tleShwdWJsaWNLZXkpIHtcbiAgY29uc3QgcG9pbnQgPSBzbTJDdXJ2ZS5Qcm9qZWN0aXZlUG9pbnQuZnJvbUhleChwdWJsaWNLZXkpO1xuICBpZiAoIXBvaW50KVxuICAgIHJldHVybiBmYWxzZTtcbiAgdHJ5IHtcbiAgICBwb2ludC5hc3NlcnRWYWxpZGl0eSgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gY29tcGFyZVB1YmxpY0tleUhleChwdWJsaWNLZXkxLCBwdWJsaWNLZXkyKSB7XG4gIGNvbnN0IHBvaW50MSA9IHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5mcm9tSGV4KHB1YmxpY0tleTEpO1xuICBpZiAoIXBvaW50MSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IHBvaW50MiA9IHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5mcm9tSGV4KHB1YmxpY0tleTIpO1xuICBpZiAoIXBvaW50MilcbiAgICByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBwb2ludDEuZXF1YWxzKHBvaW50Mik7XG59XG5cbi8vIHNyYy9zbTIvaW5kZXgudHNcbmltcG9ydCAqIGFzIHV0aWxzNCBmcm9tIFwiQG5vYmxlL2N1cnZlcy9hYnN0cmFjdC91dGlsc1wiO1xuXG4vLyBzcmMvc20yL2t4LnRzXG5pbXBvcnQgKiBhcyB1dGlsczMgZnJvbSBcIkBub2JsZS9jdXJ2ZXMvYWJzdHJhY3QvdXRpbHNcIjtcbnZhciB3UG93MiA9IHV0aWxzMy5oZXhUb051bWJlcihcIjgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXCIpO1xudmFyIHdQb3cyU3ViMSA9IHV0aWxzMy5oZXhUb051bWJlcihcIjdmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXCIpO1xuZnVuY3Rpb24gaGtkZih6LCBrZXlsZW4pIHtcbiAgbGV0IG1zZyA9IG5ldyBVaW50OEFycmF5KGtleWxlbik7XG4gIGxldCBjdCA9IDE7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBsZXQgdCA9IEVtcHR5QXJyYXk7XG4gIGNvbnN0IGN0U2hpZnQgPSBuZXcgVWludDhBcnJheSg0KTtcbiAgY29uc3QgbmV4dFQgPSAoKSA9PiB7XG4gICAgY3RTaGlmdFswXSA9IGN0ID4+IDI0ICYgMjU1O1xuICAgIGN0U2hpZnRbMV0gPSBjdCA+PiAxNiAmIDI1NTtcbiAgICBjdFNoaWZ0WzJdID0gY3QgPj4gOCAmIDI1NTtcbiAgICBjdFNoaWZ0WzNdID0gY3QgJiAyNTU7XG4gICAgdCA9IHNtMyh1dGlsczMuY29uY2F0Qnl0ZXMoeiwgY3RTaGlmdCkpO1xuICAgIGN0Kys7XG4gICAgb2Zmc2V0ID0gMDtcbiAgfTtcbiAgbmV4dFQoKTtcbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IG1zZy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChvZmZzZXQgPT09IHQubGVuZ3RoKVxuICAgICAgbmV4dFQoKTtcbiAgICBtc2dbaV0gPSB0W29mZnNldCsrXSAmIDI1NTtcbiAgfVxuICByZXR1cm4gbXNnO1xufVxuZnVuY3Rpb24gY2FsY3VsYXRlU2hhcmVkS2V5KGtleXBhaXJBLCBlcGhlbWVyYWxLZXlwYWlyQSwgcHVibGljS2V5QiwgZXBoZW1lcmFsUHVibGljS2V5Qiwgc2hhcmVkS2V5TGVuZ3RoLCBpc1JlY2lwaWVudCA9IGZhbHNlLCBpZEEgPSBcIjEyMzQ1Njc4MTIzNDU2NzhcIiwgaWRCID0gXCIxMjM0NTY3ODEyMzQ1Njc4XCIpIHtcbiAgY29uc3QgUkEgPSBzbTJDdXJ2ZS5Qcm9qZWN0aXZlUG9pbnQuZnJvbUhleChlcGhlbWVyYWxLZXlwYWlyQS5wdWJsaWNLZXkpO1xuICBjb25zdCBSQiA9IHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5mcm9tSGV4KGVwaGVtZXJhbFB1YmxpY0tleUIpO1xuICBjb25zdCBQQiA9IHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5mcm9tSGV4KHB1YmxpY0tleUIpO1xuICBsZXQgWkEgPSBnZXRaKGtleXBhaXJBLnB1YmxpY0tleSwgaWRBKTtcbiAgbGV0IFpCID0gZ2V0WihwdWJsaWNLZXlCLCBpZEIpO1xuICBpZiAoaXNSZWNpcGllbnQpIHtcbiAgICBbWkEsIFpCXSA9IFtaQiwgWkFdO1xuICB9XG4gIGNvbnN0IHJBID0gdXRpbHMzLmhleFRvTnVtYmVyKGVwaGVtZXJhbEtleXBhaXJBLnByaXZhdGVLZXkpO1xuICBjb25zdCBkQSA9IHV0aWxzMy5oZXhUb051bWJlcihrZXlwYWlyQS5wcml2YXRlS2V5KTtcbiAgY29uc3QgeDEgPSBSQS54O1xuICBjb25zdCB4MV8gPSB3UG93MiArICh4MSAmIHdQb3cyU3ViMSk7XG4gIGNvbnN0IHRBID0gZmllbGQuYWRkKGRBLCBmaWVsZC5tdWxOKHgxXywgckEpKTtcbiAgY29uc3QgeDIgPSBSQi54O1xuICBjb25zdCB4Ml8gPSBmaWVsZC5hZGQod1BvdzIsIHgyICYgd1BvdzJTdWIxKTtcbiAgY29uc3QgVSA9IFJCLm11bHRpcGx5KHgyXykuYWRkKFBCKS5tdWx0aXBseSh0QSk7XG4gIGNvbnN0IHhVID0gaGV4VG9BcnJheShsZWZ0UGFkKHV0aWxzMy5udW1iZXJUb0hleFVucGFkZGVkKFUueCksIDY0KSk7XG4gIGNvbnN0IHlVID0gaGV4VG9BcnJheShsZWZ0UGFkKHV0aWxzMy5udW1iZXJUb0hleFVucGFkZGVkKFUueSksIDY0KSk7XG4gIGNvbnN0IEtBID0gaGtkZih1dGlsczMuY29uY2F0Qnl0ZXMoeFUsIHlVLCBaQSwgWkIpLCBzaGFyZWRLZXlMZW5ndGgpO1xuICByZXR1cm4gS0E7XG59XG5cbi8vIHNyYy9zbTIvaW5kZXgudHNcbnZhciBDMUMyQzMgPSAwO1xudmFyIEVtcHR5QXJyYXkgPSBuZXcgVWludDhBcnJheSgpO1xuZnVuY3Rpb24gZG9FbmNyeXB0KG1zZywgcHVibGljS2V5LCBjaXBoZXJNb2RlID0gMSkge1xuICBjb25zdCBtc2dBcnIgPSB0eXBlb2YgbXNnID09PSBcInN0cmluZ1wiID8gaGV4VG9BcnJheSh1dGY4VG9IZXgobXNnKSkgOiBVaW50OEFycmF5LmZyb20obXNnKTtcbiAgY29uc3QgcHVibGljS2V5UG9pbnQgPSB0eXBlb2YgcHVibGljS2V5ID09PSBcInN0cmluZ1wiID8gc20yQ3VydmUuUHJvamVjdGl2ZVBvaW50LmZyb21IZXgocHVibGljS2V5KSA6IHB1YmxpY0tleTtcbiAgY29uc3Qga2V5cGFpciA9IGdlbmVyYXRlS2V5UGFpckhleCgpO1xuICBjb25zdCBrID0gdXRpbHM0LmhleFRvTnVtYmVyKGtleXBhaXIucHJpdmF0ZUtleSk7XG4gIGxldCBjMSA9IGtleXBhaXIucHVibGljS2V5O1xuICBpZiAoYzEubGVuZ3RoID4gMTI4KVxuICAgIGMxID0gYzEuc3Vic3RyaW5nKGMxLmxlbmd0aCAtIDEyOCk7XG4gIGNvbnN0IHAgPSBwdWJsaWNLZXlQb2ludC5tdWx0aXBseShrKTtcbiAgY29uc3QgeDIgPSBoZXhUb0FycmF5KGxlZnRQYWQodXRpbHM0Lm51bWJlclRvSGV4VW5wYWRkZWQocC54KSwgNjQpKTtcbiAgY29uc3QgeTIgPSBoZXhUb0FycmF5KGxlZnRQYWQodXRpbHM0Lm51bWJlclRvSGV4VW5wYWRkZWQocC55KSwgNjQpKTtcbiAgY29uc3QgYzMgPSBieXRlc1RvSGV4KHNtMyh1dGlsczQuY29uY2F0Qnl0ZXMoeDIsIG1zZ0FyciwgeTIpKSk7XG4gIHhvckNpcGhlclN0cmVhbSh4MiwgeTIsIG1zZ0Fycik7XG4gIGNvbnN0IGMyID0gYnl0ZXNUb0hleChtc2dBcnIpO1xuICByZXR1cm4gY2lwaGVyTW9kZSA9PT0gQzFDMkMzID8gYzEgKyBjMiArIGMzIDogYzEgKyBjMyArIGMyO1xufVxuZnVuY3Rpb24geG9yQ2lwaGVyU3RyZWFtKHgyLCB5MiwgbXNnKSB7XG4gIGxldCBjdCA9IDE7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBsZXQgdCA9IEVtcHR5QXJyYXk7XG4gIGNvbnN0IGN0U2hpZnQgPSBuZXcgVWludDhBcnJheSg0KTtcbiAgY29uc3QgbmV4dFQgPSAoKSA9PiB7XG4gICAgY3RTaGlmdFswXSA9IGN0ID4+IDI0ICYgMjU1O1xuICAgIGN0U2hpZnRbMV0gPSBjdCA+PiAxNiAmIDI1NTtcbiAgICBjdFNoaWZ0WzJdID0gY3QgPj4gOCAmIDI1NTtcbiAgICBjdFNoaWZ0WzNdID0gY3QgJiAyNTU7XG4gICAgdCA9IHNtMyh1dGlsczQuY29uY2F0Qnl0ZXMoeDIsIHkyLCBjdFNoaWZ0KSk7XG4gICAgY3QrKztcbiAgICBvZmZzZXQgPSAwO1xuICB9O1xuICBuZXh0VCgpO1xuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbXNnLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKG9mZnNldCA9PT0gdC5sZW5ndGgpXG4gICAgICBuZXh0VCgpO1xuICAgIG1zZ1tpXSBePSB0W29mZnNldCsrXSAmIDI1NTtcbiAgfVxufVxuZnVuY3Rpb24gZG9EZWNyeXB0KGVuY3J5cHREYXRhLCBwcml2YXRlS2V5LCBjaXBoZXJNb2RlID0gMSwge1xuICBvdXRwdXQgPSBcInN0cmluZ1wiXG59ID0ge30pIHtcbiAgY29uc3QgcHJpdmF0ZUtleUludGVnZXIgPSB1dGlsczQuaGV4VG9OdW1iZXIocHJpdmF0ZUtleSk7XG4gIGxldCBjMyA9IGVuY3J5cHREYXRhLnN1YnN0cmluZygxMjgsIDEyOCArIDY0KTtcbiAgbGV0IGMyID0gZW5jcnlwdERhdGEuc3Vic3RyaW5nKDEyOCArIDY0KTtcbiAgaWYgKGNpcGhlck1vZGUgPT09IEMxQzJDMykge1xuICAgIGMzID0gZW5jcnlwdERhdGEuc3Vic3RyaW5nKGVuY3J5cHREYXRhLmxlbmd0aCAtIDY0KTtcbiAgICBjMiA9IGVuY3J5cHREYXRhLnN1YnN0cmluZygxMjgsIGVuY3J5cHREYXRhLmxlbmd0aCAtIDY0KTtcbiAgfVxuICBjb25zdCBtc2cgPSBoZXhUb0FycmF5KGMyKTtcbiAgY29uc3QgYzEgPSBzbTJDdXJ2ZS5Qcm9qZWN0aXZlUG9pbnQuZnJvbUhleChcIjA0XCIgKyBlbmNyeXB0RGF0YS5zdWJzdHJpbmcoMCwgMTI4KSk7XG4gIGNvbnN0IHAgPSBjMS5tdWx0aXBseShwcml2YXRlS2V5SW50ZWdlcik7XG4gIGNvbnN0IHgyID0gaGV4VG9BcnJheShsZWZ0UGFkKHV0aWxzNC5udW1iZXJUb0hleFVucGFkZGVkKHAueCksIDY0KSk7XG4gIGNvbnN0IHkyID0gaGV4VG9BcnJheShsZWZ0UGFkKHV0aWxzNC5udW1iZXJUb0hleFVucGFkZGVkKHAueSksIDY0KSk7XG4gIHhvckNpcGhlclN0cmVhbSh4MiwgeTIsIG1zZyk7XG4gIGNvbnN0IGNoZWNrQzMgPSBhcnJheVRvSGV4KEFycmF5LmZyb20oc20zKHV0aWxzNC5jb25jYXRCeXRlcyh4MiwgbXNnLCB5MikpKSk7XG4gIGlmIChjaGVja0MzID09PSBjMy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgcmV0dXJuIG91dHB1dCA9PT0gXCJhcnJheVwiID8gbXNnIDogYXJyYXlUb1V0ZjgobXNnKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb3V0cHV0ID09PSBcImFycmF5XCIgPyBbXSA6IFwiXCI7XG4gIH1cbn1cbmZ1bmN0aW9uIGRvU2lnbmF0dXJlKG1zZywgcHJpdmF0ZUtleSwgb3B0aW9ucyA9IHt9KSB7XG4gIGxldCB7XG4gICAgcG9pbnRQb29sLFxuICAgIGRlcixcbiAgICBoYXNoLFxuICAgIHB1YmxpY0tleSxcbiAgICB1c2VySWRcbiAgfSA9IG9wdGlvbnM7XG4gIGxldCBoYXNoSGV4ID0gdHlwZW9mIG1zZyA9PT0gXCJzdHJpbmdcIiA/IHV0ZjhUb0hleChtc2cpIDogYXJyYXlUb0hleChBcnJheS5mcm9tKG1zZykpO1xuICBpZiAoaGFzaCkge1xuICAgIHB1YmxpY0tleSA9IHB1YmxpY0tleSB8fCBnZXRQdWJsaWNLZXlGcm9tUHJpdmF0ZUtleShwcml2YXRlS2V5KTtcbiAgICBoYXNoSGV4ID0gZ2V0SGFzaChoYXNoSGV4LCBwdWJsaWNLZXksIHVzZXJJZCk7XG4gIH1cbiAgY29uc3QgZEEgPSB1dGlsczQuaGV4VG9OdW1iZXIocHJpdmF0ZUtleSk7XG4gIGNvbnN0IGUgPSB1dGlsczQuaGV4VG9OdW1iZXIoaGFzaEhleCk7XG4gIGxldCBrID0gbnVsbDtcbiAgbGV0IHIgPSBudWxsO1xuICBsZXQgcyA9IG51bGw7XG4gIGRvIHtcbiAgICBkbyB7XG4gICAgICBsZXQgcG9pbnQ7XG4gICAgICBpZiAocG9pbnRQb29sICYmIHBvaW50UG9vbC5sZW5ndGgpIHtcbiAgICAgICAgcG9pbnQgPSBwb2ludFBvb2wucG9wKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwb2ludCA9IGdldFBvaW50KCk7XG4gICAgICB9XG4gICAgICBrID0gcG9pbnQuaztcbiAgICAgIHIgPSBmaWVsZC5hZGQoZSwgcG9pbnQueDEpO1xuICAgIH0gd2hpbGUgKHIgPT09IFpFUk8gfHwgciArIGsgPT09IHNtMkN1cnZlLkNVUlZFLm4pO1xuICAgIHMgPSBmaWVsZC5tdWwoZmllbGQuaW52KGZpZWxkLmFkZE4oZEEsIE9ORSkpLCBmaWVsZC5zdWJOKGssIGZpZWxkLm11bE4ociwgZEEpKSk7XG4gIH0gd2hpbGUgKHMgPT09IFpFUk8pO1xuICBpZiAoZGVyKVxuICAgIHJldHVybiBlbmNvZGVEZXIociwgcyk7XG4gIHJldHVybiBsZWZ0UGFkKHV0aWxzNC5udW1iZXJUb0hleFVucGFkZGVkKHIpLCA2NCkgKyBsZWZ0UGFkKHV0aWxzNC5udW1iZXJUb0hleFVucGFkZGVkKHMpLCA2NCk7XG59XG5mdW5jdGlvbiBkb1ZlcmlmeVNpZ25hdHVyZShtc2csIHNpZ25IZXgsIHB1YmxpY0tleSwgb3B0aW9ucyA9IHt9KSB7XG4gIGxldCBoYXNoSGV4O1xuICBjb25zdCB7XG4gICAgaGFzaCxcbiAgICBkZXIsXG4gICAgdXNlcklkXG4gIH0gPSBvcHRpb25zO1xuICBjb25zdCBwdWJsaWNLZXlIZXggPSB0eXBlb2YgcHVibGljS2V5ID09PSBcInN0cmluZ1wiID8gcHVibGljS2V5IDogcHVibGljS2V5LnRvSGV4KGZhbHNlKTtcbiAgaWYgKGhhc2gpIHtcbiAgICBoYXNoSGV4ID0gZ2V0SGFzaCh0eXBlb2YgbXNnID09PSBcInN0cmluZ1wiID8gdXRmOFRvSGV4KG1zZykgOiBtc2csIHB1YmxpY0tleUhleCwgdXNlcklkKTtcbiAgfSBlbHNlIHtcbiAgICBoYXNoSGV4ID0gdHlwZW9mIG1zZyA9PT0gXCJzdHJpbmdcIiA/IHV0ZjhUb0hleChtc2cpIDogYXJyYXlUb0hleChBcnJheS5mcm9tKG1zZykpO1xuICB9XG4gIGxldCByO1xuICBsZXQgcztcbiAgaWYgKGRlcikge1xuICAgIGNvbnN0IGRlY29kZURlck9iaiA9IGRlY29kZURlcihzaWduSGV4KTtcbiAgICByID0gZGVjb2RlRGVyT2JqLnI7XG4gICAgcyA9IGRlY29kZURlck9iai5zO1xuICB9IGVsc2Uge1xuICAgIHIgPSB1dGlsczQuaGV4VG9OdW1iZXIoc2lnbkhleC5zdWJzdHJpbmcoMCwgNjQpKTtcbiAgICBzID0gdXRpbHM0LmhleFRvTnVtYmVyKHNpZ25IZXguc3Vic3RyaW5nKDY0KSk7XG4gIH1cbiAgY29uc3QgUEEgPSB0eXBlb2YgcHVibGljS2V5ID09PSBcInN0cmluZ1wiID8gc20yQ3VydmUuUHJvamVjdGl2ZVBvaW50LmZyb21IZXgocHVibGljS2V5KSA6IHB1YmxpY0tleTtcbiAgY29uc3QgZSA9IHV0aWxzNC5oZXhUb051bWJlcihoYXNoSGV4KTtcbiAgY29uc3QgdCA9IGZpZWxkLmFkZChyLCBzKTtcbiAgaWYgKHQgPT09IFpFUk8pXG4gICAgcmV0dXJuIGZhbHNlO1xuICBjb25zdCB4MXkxID0gc20yQ3VydmUuUHJvamVjdGl2ZVBvaW50LkJBU0UubXVsdGlwbHkocykuYWRkKFBBLm11bHRpcGx5KHQpKTtcbiAgY29uc3QgUiA9IGZpZWxkLmFkZChlLCB4MXkxLngpO1xuICByZXR1cm4gciA9PT0gUjtcbn1cbmZ1bmN0aW9uIGdldFoocHVibGljS2V5LCB1c2VySWQgPSBcIjEyMzQ1Njc4MTIzNDU2NzhcIikge1xuICB1c2VySWQgPSB1dGY4VG9IZXgodXNlcklkKTtcbiAgY29uc3QgYSA9IGxlZnRQYWQodXRpbHM0Lm51bWJlclRvSGV4VW5wYWRkZWQoc20yQ3VydmUuQ1VSVkUuYSksIDY0KTtcbiAgY29uc3QgYiA9IGxlZnRQYWQodXRpbHM0Lm51bWJlclRvSGV4VW5wYWRkZWQoc20yQ3VydmUuQ1VSVkUuYiksIDY0KTtcbiAgY29uc3QgZ3ggPSBsZWZ0UGFkKHV0aWxzNC5udW1iZXJUb0hleFVucGFkZGVkKHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5CQVNFLngpLCA2NCk7XG4gIGNvbnN0IGd5ID0gbGVmdFBhZCh1dGlsczQubnVtYmVyVG9IZXhVbnBhZGRlZChzbTJDdXJ2ZS5Qcm9qZWN0aXZlUG9pbnQuQkFTRS55KSwgNjQpO1xuICBsZXQgcHg7XG4gIGxldCBweTtcbiAgaWYgKHB1YmxpY0tleS5sZW5ndGggPT09IDEyOCkge1xuICAgIHB4ID0gcHVibGljS2V5LnN1YnN0cmluZygwLCA2NCk7XG4gICAgcHkgPSBwdWJsaWNLZXkuc3Vic3RyaW5nKDY0LCAxMjgpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHBvaW50ID0gc20yQ3VydmUuUHJvamVjdGl2ZVBvaW50LmZyb21IZXgocHVibGljS2V5KTtcbiAgICBweCA9IGxlZnRQYWQodXRpbHM0Lm51bWJlclRvSGV4VW5wYWRkZWQocG9pbnQueCksIDY0KTtcbiAgICBweSA9IGxlZnRQYWQodXRpbHM0Lm51bWJlclRvSGV4VW5wYWRkZWQocG9pbnQueSksIDY0KTtcbiAgfVxuICBjb25zdCBkYXRhID0gaGV4VG9BcnJheSh1c2VySWQgKyBhICsgYiArIGd4ICsgZ3kgKyBweCArIHB5KTtcbiAgY29uc3QgZW50bCA9IHVzZXJJZC5sZW5ndGggKiA0O1xuICBjb25zdCB6ID0gc20zKHV0aWxzNC5jb25jYXRCeXRlcyhuZXcgVWludDhBcnJheShbZW50bCA+PiA4ICYgMjU1LCBlbnRsICYgMjU1XSksIGRhdGEpKTtcbiAgcmV0dXJuIHo7XG59XG5mdW5jdGlvbiBnZXRIYXNoKGhhc2hIZXgsIHB1YmxpY0tleSwgdXNlcklkID0gXCIxMjM0NTY3ODEyMzQ1Njc4XCIpIHtcbiAgY29uc3QgeiA9IGdldFoocHVibGljS2V5LCB1c2VySWQpO1xuICByZXR1cm4gYnl0ZXNUb0hleChzbTModXRpbHM0LmNvbmNhdEJ5dGVzKHosIHR5cGVvZiBoYXNoSGV4ID09PSBcInN0cmluZ1wiID8gaGV4VG9BcnJheShoYXNoSGV4KSA6IGhhc2hIZXgpKSk7XG59XG5mdW5jdGlvbiBwcmVjb21wdXRlUHVibGljS2V5KHB1YmxpY0tleSwgd2luZG93U2l6ZSkge1xuICBjb25zdCBwb2ludCA9IHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5mcm9tSGV4KHB1YmxpY0tleSk7XG4gIHJldHVybiBzbTJDdXJ2ZS51dGlscy5wcmVjb21wdXRlKHdpbmRvd1NpemUsIHBvaW50KTtcbn1cbmZ1bmN0aW9uIGdldFB1YmxpY0tleUZyb21Qcml2YXRlS2V5KHByaXZhdGVLZXkpIHtcbiAgY29uc3QgcHViS2V5ID0gc20yQ3VydmUuZ2V0UHVibGljS2V5KHByaXZhdGVLZXksIGZhbHNlKTtcbiAgY29uc3QgcHViUGFkID0gbGVmdFBhZCh1dGlsczQuYnl0ZXNUb0hleChwdWJLZXkpLCA2NCk7XG4gIHJldHVybiBwdWJQYWQ7XG59XG5mdW5jdGlvbiBnZXRQb2ludCgpIHtcbiAgY29uc3Qga2V5cGFpciA9IGdlbmVyYXRlS2V5UGFpckhleCgpO1xuICBjb25zdCBQQSA9IHNtMkN1cnZlLlByb2plY3RpdmVQb2ludC5mcm9tSGV4KGtleXBhaXIucHVibGljS2V5KTtcbiAgY29uc3QgayA9IHV0aWxzNC5oZXhUb051bWJlcihrZXlwYWlyLnByaXZhdGVLZXkpO1xuICByZXR1cm4ge1xuICAgIC4uLmtleXBhaXIsXG4gICAgayxcbiAgICB4MTogUEEueFxuICB9O1xufVxuXG4vLyBzcmMvc20zL2luZGV4LnRzXG5mdW5jdGlvbiB1dGY4VG9BcnJheShzdHIpIHtcbiAgY29uc3QgYXJyID0gW107XG4gIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBwb2ludCA9IHN0ci5jb2RlUG9pbnRBdChpKTtcbiAgICBpZiAocG9pbnQgPD0gMTI3KSB7XG4gICAgICBhcnIucHVzaChwb2ludCk7XG4gICAgfSBlbHNlIGlmIChwb2ludCA8PSAyMDQ3KSB7XG4gICAgICBhcnIucHVzaCgxOTIgfCBwb2ludCA+Pj4gNik7XG4gICAgICBhcnIucHVzaCgxMjggfCBwb2ludCAmIDYzKTtcbiAgICB9IGVsc2UgaWYgKHBvaW50IDw9IDU1Mjk1IHx8IHBvaW50ID49IDU3MzQ0ICYmIHBvaW50IDw9IDY1NTM1KSB7XG4gICAgICBhcnIucHVzaCgyMjQgfCBwb2ludCA+Pj4gMTIpO1xuICAgICAgYXJyLnB1c2goMTI4IHwgcG9pbnQgPj4+IDYgJiA2Myk7XG4gICAgICBhcnIucHVzaCgxMjggfCBwb2ludCAmIDYzKTtcbiAgICB9IGVsc2UgaWYgKHBvaW50ID49IDY1NTM2ICYmIHBvaW50IDw9IDExMTQxMTEpIHtcbiAgICAgIGkrKztcbiAgICAgIGFyci5wdXNoKDI0MCB8IHBvaW50ID4+PiAxOCAmIDI4KTtcbiAgICAgIGFyci5wdXNoKDEyOCB8IHBvaW50ID4+PiAxMiAmIDYzKTtcbiAgICAgIGFyci5wdXNoKDEyOCB8IHBvaW50ID4+PiA2ICYgNjMpO1xuICAgICAgYXJyLnB1c2goMTI4IHwgcG9pbnQgJiA2Myk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFyci5wdXNoKHBvaW50KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlucHV0IGlzIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgVWludDhBcnJheShhcnIpO1xufVxuZnVuY3Rpb24gc20zMihpbnB1dCwgb3B0aW9ucykge1xuICBpbnB1dCA9IHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIiA/IHV0ZjhUb0FycmF5KGlucHV0KSA6IGlucHV0O1xuICBpZiAob3B0aW9ucykge1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zLm1vZGUgfHwgXCJobWFjXCI7XG4gICAgaWYgKG1vZGUgIT09IFwiaG1hY1wiKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBtb2RlXCIpO1xuICAgIGxldCBrZXkgPSBvcHRpb25zLmtleTtcbiAgICBpZiAoIWtleSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImludmFsaWQga2V5XCIpO1xuICAgIGtleSA9IHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIgPyBoZXhUb0FycmF5KGtleSkgOiBrZXk7XG4gICAgcmV0dXJuIGJ5dGVzVG9IZXgoaG1hYyhzbTMsIGtleSwgaW5wdXQpKTtcbiAgfVxuICByZXR1cm4gYnl0ZXNUb0hleChzbTMoaW5wdXQpKTtcbn1cblxuLy8gc3JjL3NtNC9pbmRleC50c1xudmFyIHNtNF9leHBvcnRzID0ge307XG5fX2V4cG9ydChzbTRfZXhwb3J0cywge1xuICBkZWNyeXB0OiAoKSA9PiBkZWNyeXB0LFxuICBlbmNyeXB0OiAoKSA9PiBlbmNyeXB0LFxuICBzbTQ6ICgpID0+IHNtNFxufSk7XG52YXIgREVDUllQVCA9IDA7XG52YXIgUk9VTkQgPSAzMjtcbnZhciBCTE9DSyA9IDE2O1xudmFyIFNib3ggPSBVaW50OEFycmF5LmZyb20oW1xuICAyMTQsXG4gIDE0NCxcbiAgMjMzLFxuICAyNTQsXG4gIDIwNCxcbiAgMjI1LFxuICA2MSxcbiAgMTgzLFxuICAyMixcbiAgMTgyLFxuICAyMCxcbiAgMTk0LFxuICA0MCxcbiAgMjUxLFxuICA0NCxcbiAgNSxcbiAgNDMsXG4gIDEwMyxcbiAgMTU0LFxuICAxMTgsXG4gIDQyLFxuICAxOTAsXG4gIDQsXG4gIDE5NSxcbiAgMTcwLFxuICA2OCxcbiAgMTksXG4gIDM4LFxuICA3MyxcbiAgMTM0LFxuICA2LFxuICAxNTMsXG4gIDE1NixcbiAgNjYsXG4gIDgwLFxuICAyNDQsXG4gIDE0NSxcbiAgMjM5LFxuICAxNTIsXG4gIDEyMixcbiAgNTEsXG4gIDg0LFxuICAxMSxcbiAgNjcsXG4gIDIzNyxcbiAgMjA3LFxuICAxNzIsXG4gIDk4LFxuICAyMjgsXG4gIDE3OSxcbiAgMjgsXG4gIDE2OSxcbiAgMjAxLFxuICA4LFxuICAyMzIsXG4gIDE0OSxcbiAgMTI4LFxuICAyMjMsXG4gIDE0OCxcbiAgMjUwLFxuICAxMTcsXG4gIDE0MyxcbiAgNjMsXG4gIDE2NixcbiAgNzEsXG4gIDcsXG4gIDE2NyxcbiAgMjUyLFxuICAyNDMsXG4gIDExNSxcbiAgMjMsXG4gIDE4NixcbiAgMTMxLFxuICA4OSxcbiAgNjAsXG4gIDI1LFxuICAyMzAsXG4gIDEzMyxcbiAgNzksXG4gIDE2OCxcbiAgMTA0LFxuICAxMDcsXG4gIDEyOSxcbiAgMTc4LFxuICAxMTMsXG4gIDEwMCxcbiAgMjE4LFxuICAxMzksXG4gIDI0OCxcbiAgMjM1LFxuICAxNSxcbiAgNzUsXG4gIDExMixcbiAgODYsXG4gIDE1NyxcbiAgNTMsXG4gIDMwLFxuICAzNixcbiAgMTQsXG4gIDk0LFxuICA5OSxcbiAgODgsXG4gIDIwOSxcbiAgMTYyLFxuICAzNyxcbiAgMzQsXG4gIDEyNCxcbiAgNTksXG4gIDEsXG4gIDMzLFxuICAxMjAsXG4gIDEzNSxcbiAgMjEyLFxuICAwLFxuICA3MCxcbiAgODcsXG4gIDE1OSxcbiAgMjExLFxuICAzOSxcbiAgODIsXG4gIDc2LFxuICA1NCxcbiAgMixcbiAgMjMxLFxuICAxNjAsXG4gIDE5NixcbiAgMjAwLFxuICAxNTgsXG4gIDIzNCxcbiAgMTkxLFxuICAxMzgsXG4gIDIxMCxcbiAgNjQsXG4gIDE5OSxcbiAgNTYsXG4gIDE4MSxcbiAgMTYzLFxuICAyNDcsXG4gIDI0MixcbiAgMjA2LFxuICAyNDksXG4gIDk3LFxuICAyMSxcbiAgMTYxLFxuICAyMjQsXG4gIDE3NCxcbiAgOTMsXG4gIDE2NCxcbiAgMTU1LFxuICA1MixcbiAgMjYsXG4gIDg1LFxuICAxNzMsXG4gIDE0NyxcbiAgNTAsXG4gIDQ4LFxuICAyNDUsXG4gIDE0MCxcbiAgMTc3LFxuICAyMjcsXG4gIDI5LFxuICAyNDYsXG4gIDIyNixcbiAgNDYsXG4gIDEzMCxcbiAgMTAyLFxuICAyMDIsXG4gIDk2LFxuICAxOTIsXG4gIDQxLFxuICAzNSxcbiAgMTcxLFxuICAxMyxcbiAgODMsXG4gIDc4LFxuICAxMTEsXG4gIDIxMyxcbiAgMjE5LFxuICA1NSxcbiAgNjksXG4gIDIyMixcbiAgMjUzLFxuICAxNDIsXG4gIDQ3LFxuICAzLFxuICAyNTUsXG4gIDEwNixcbiAgMTE0LFxuICAxMDksXG4gIDEwOCxcbiAgOTEsXG4gIDgxLFxuICAxNDEsXG4gIDI3LFxuICAxNzUsXG4gIDE0NixcbiAgMTg3LFxuICAyMjEsXG4gIDE4OCxcbiAgMTI3LFxuICAxNyxcbiAgMjE3LFxuICA5MixcbiAgNjUsXG4gIDMxLFxuICAxNixcbiAgOTAsXG4gIDIxNixcbiAgMTAsXG4gIDE5MyxcbiAgNDksXG4gIDEzNixcbiAgMTY1LFxuICAyMDUsXG4gIDEyMyxcbiAgMTg5LFxuICA0NSxcbiAgMTE2LFxuICAyMDgsXG4gIDE4LFxuICAxODQsXG4gIDIyOSxcbiAgMTgwLFxuICAxNzYsXG4gIDEzNyxcbiAgMTA1LFxuICAxNTEsXG4gIDc0LFxuICAxMixcbiAgMTUwLFxuICAxMTksXG4gIDEyNixcbiAgMTAxLFxuICAxODUsXG4gIDI0MSxcbiAgOSxcbiAgMTk3LFxuICAxMTAsXG4gIDE5OCxcbiAgMTMyLFxuICAyNCxcbiAgMjQwLFxuICAxMjUsXG4gIDIzNixcbiAgNTgsXG4gIDIyMCxcbiAgNzcsXG4gIDMyLFxuICAxMjEsXG4gIDIzOCxcbiAgOTUsXG4gIDYyLFxuICAyMTUsXG4gIDIwMyxcbiAgNTcsXG4gIDcyXG5dKTtcbnZhciBDSyA9IG5ldyBVaW50MzJBcnJheShbXG4gIDQ2MjM1NyxcbiAgNDcyMDY2NjA5LFxuICA5NDM2NzA4NjEsXG4gIDE0MTUyNzUxMTMsXG4gIDE4ODY4NzkzNjUsXG4gIDIzNTg0ODM2MTcsXG4gIDI4MzAwODc4NjksXG4gIDMzMDE2OTIxMjEsXG4gIDM3NzMyOTYzNzMsXG4gIDQyMjgwNTc2MTcsXG4gIDQwNDY5NDU3MyxcbiAgODc2Mjk4ODI1LFxuICAxMzQ3OTAzMDc3LFxuICAxODE5NTA3MzI5LFxuICAyMjkxMTExNTgxLFxuICAyNzYyNzE1ODMzLFxuICAzMjM0MzIwMDg1LFxuICAzNzA1OTI0MzM3LFxuICA0MTc3NDYyNzk3LFxuICAzMzczMjI1MzcsXG4gIDgwODkyNjc4OSxcbiAgMTI4MDUzMTA0MSxcbiAgMTc1MjEzNTI5MyxcbiAgMjIyMzczOTU0NSxcbiAgMjY5NTM0Mzc5NyxcbiAgMzE2Njk0ODA0OSxcbiAgMzYzODU1MjMwMSxcbiAgNDExMDA5MDc2MSxcbiAgMjY5OTUwNTAxLFxuICA3NDE1NTQ3NTMsXG4gIDEyMTMxNTkwMDUsXG4gIDE2ODQ3NjMyNTdcbl0pO1xuZnVuY3Rpb24gYnl0ZVN1YihhKSB7XG4gIHJldHVybiAoU2JveFthID4+PiAyNCAmIDI1NV0gJiAyNTUpIDw8IDI0IHwgKFNib3hbYSA+Pj4gMTYgJiAyNTVdICYgMjU1KSA8PCAxNiB8IChTYm94W2EgPj4+IDggJiAyNTVdICYgMjU1KSA8PCA4IHwgU2JveFthICYgMjU1XSAmIDI1NTtcbn1cbnZhciB4ID0gbmV3IFVpbnQzMkFycmF5KDQpO1xudmFyIHRtcCA9IG5ldyBVaW50MzJBcnJheSg0KTtcbmZ1bmN0aW9uIHNtczRDcnlwdChpbnB1dCwgb3V0cHV0LCByb3VuZEtleSkge1xuICBsZXQgeDAgPSAwLCB4MSA9IDAsIHgyID0gMCwgeDMgPSAwLCB0bXAwID0gMCwgdG1wMSA9IDAsIHRtcDIgPSAwLCB0bXAzID0gMDtcbiAgdG1wMCA9IGlucHV0WzBdICYgMjU1O1xuICB0bXAxID0gaW5wdXRbMV0gJiAyNTU7XG4gIHRtcDIgPSBpbnB1dFsyXSAmIDI1NTtcbiAgdG1wMyA9IGlucHV0WzNdICYgMjU1O1xuICB4MCA9IHRtcDAgPDwgMjQgfCB0bXAxIDw8IDE2IHwgdG1wMiA8PCA4IHwgdG1wMztcbiAgdG1wMCA9IGlucHV0WzRdICYgMjU1O1xuICB0bXAxID0gaW5wdXRbNV0gJiAyNTU7XG4gIHRtcDIgPSBpbnB1dFs2XSAmIDI1NTtcbiAgdG1wMyA9IGlucHV0WzddICYgMjU1O1xuICB4MSA9IHRtcDAgPDwgMjQgfCB0bXAxIDw8IDE2IHwgdG1wMiA8PCA4IHwgdG1wMztcbiAgdG1wMCA9IGlucHV0WzhdICYgMjU1O1xuICB0bXAxID0gaW5wdXRbOV0gJiAyNTU7XG4gIHRtcDIgPSBpbnB1dFsxMF0gJiAyNTU7XG4gIHRtcDMgPSBpbnB1dFsxMV0gJiAyNTU7XG4gIHgyID0gdG1wMCA8PCAyNCB8IHRtcDEgPDwgMTYgfCB0bXAyIDw8IDggfCB0bXAzO1xuICB0bXAwID0gaW5wdXRbMTJdICYgMjU1O1xuICB0bXAxID0gaW5wdXRbMTNdICYgMjU1O1xuICB0bXAyID0gaW5wdXRbMTRdICYgMjU1O1xuICB0bXAzID0gaW5wdXRbMTVdICYgMjU1O1xuICB4MyA9IHRtcDAgPDwgMjQgfCB0bXAxIDw8IDE2IHwgdG1wMiA8PCA4IHwgdG1wMztcbiAgZm9yIChsZXQgciA9IDA7IHIgPCAzMjsgciArPSA0KSB7XG4gICAgdG1wMCA9IHgxIF4geDIgXiB4MyBeIHJvdW5kS2V5W3JdO1xuICAgIHRtcDAgPSBieXRlU3ViKHRtcDApO1xuICAgIHgwIF49IHRtcDAgXiAodG1wMCA8PCAyIHwgdG1wMCA+Pj4gMzApIF4gKHRtcDAgPDwgMTAgfCB0bXAwID4+PiAyMikgXiAodG1wMCA8PCAxOCB8IHRtcDAgPj4+IDE0KSBeICh0bXAwIDw8IDI0IHwgdG1wMCA+Pj4gOCk7XG4gICAgdG1wMSA9IHgyIF4geDMgXiB4MCBeIHJvdW5kS2V5W3IgKyAxXTtcbiAgICB0bXAxID0gYnl0ZVN1Yih0bXAxKTtcbiAgICB4MSBePSB0bXAxIF4gKHRtcDEgPDwgMiB8IHRtcDEgPj4+IDMwKSBeICh0bXAxIDw8IDEwIHwgdG1wMSA+Pj4gMjIpIF4gKHRtcDEgPDwgMTggfCB0bXAxID4+PiAxNCkgXiAodG1wMSA8PCAyNCB8IHRtcDEgPj4+IDgpO1xuICAgIHRtcDIgPSB4MyBeIHgwIF4geDEgXiByb3VuZEtleVtyICsgMl07XG4gICAgdG1wMiA9IGJ5dGVTdWIodG1wMik7XG4gICAgeDIgXj0gdG1wMiBeICh0bXAyIDw8IDIgfCB0bXAyID4+PiAzMCkgXiAodG1wMiA8PCAxMCB8IHRtcDIgPj4+IDIyKSBeICh0bXAyIDw8IDE4IHwgdG1wMiA+Pj4gMTQpIF4gKHRtcDIgPDwgMjQgfCB0bXAyID4+PiA4KTtcbiAgICB0bXAzID0geDAgXiB4MSBeIHgyIF4gcm91bmRLZXlbciArIDNdO1xuICAgIHRtcDMgPSBieXRlU3ViKHRtcDMpO1xuICAgIHgzIF49IHRtcDMgXiAodG1wMyA8PCAyIHwgdG1wMyA+Pj4gMzApIF4gKHRtcDMgPDwgMTAgfCB0bXAzID4+PiAyMikgXiAodG1wMyA8PCAxOCB8IHRtcDMgPj4+IDE0KSBeICh0bXAzIDw8IDI0IHwgdG1wMyA+Pj4gOCk7XG4gIH1cbiAgb3V0cHV0WzBdID0geDMgPj4+IDI0ICYgMjU1O1xuICBvdXRwdXRbMV0gPSB4MyA+Pj4gMTYgJiAyNTU7XG4gIG91dHB1dFsyXSA9IHgzID4+PiA4ICYgMjU1O1xuICBvdXRwdXRbM10gPSB4MyAmIDI1NTtcbiAgb3V0cHV0WzRdID0geDIgPj4+IDI0ICYgMjU1O1xuICBvdXRwdXRbNV0gPSB4MiA+Pj4gMTYgJiAyNTU7XG4gIG91dHB1dFs2XSA9IHgyID4+PiA4ICYgMjU1O1xuICBvdXRwdXRbN10gPSB4MiAmIDI1NTtcbiAgb3V0cHV0WzhdID0geDEgPj4+IDI0ICYgMjU1O1xuICBvdXRwdXRbOV0gPSB4MSA+Pj4gMTYgJiAyNTU7XG4gIG91dHB1dFsxMF0gPSB4MSA+Pj4gOCAmIDI1NTtcbiAgb3V0cHV0WzExXSA9IHgxICYgMjU1O1xuICBvdXRwdXRbMTJdID0geDAgPj4+IDI0ICYgMjU1O1xuICBvdXRwdXRbMTNdID0geDAgPj4+IDE2ICYgMjU1O1xuICBvdXRwdXRbMTRdID0geDAgPj4+IDggJiAyNTU7XG4gIG91dHB1dFsxNV0gPSB4MCAmIDI1NTtcbn1cbmZ1bmN0aW9uIHNtczRLZXlFeHQoa2V5LCByb3VuZEtleSwgY3J5cHRGbGFnKSB7XG4gIGxldCB4MCA9IDAsIHgxID0gMCwgeDIgPSAwLCB4MyA9IDAsIG1pZCA9IDA7XG4gIHgwID0gKGtleVswXSAmIDI1NSkgPDwgMjQgfCAoa2V5WzFdICYgMjU1KSA8PCAxNiB8IChrZXlbMl0gJiAyNTUpIDw8IDggfCBrZXlbM10gJiAyNTU7XG4gIHgxID0gKGtleVs0XSAmIDI1NSkgPDwgMjQgfCAoa2V5WzVdICYgMjU1KSA8PCAxNiB8IChrZXlbNl0gJiAyNTUpIDw8IDggfCBrZXlbN10gJiAyNTU7XG4gIHgyID0gKGtleVs4XSAmIDI1NSkgPDwgMjQgfCAoa2V5WzldICYgMjU1KSA8PCAxNiB8IChrZXlbMTBdICYgMjU1KSA8PCA4IHwga2V5WzExXSAmIDI1NTtcbiAgeDMgPSAoa2V5WzEyXSAmIDI1NSkgPDwgMjQgfCAoa2V5WzEzXSAmIDI1NSkgPDwgMTYgfCAoa2V5WzE0XSAmIDI1NSkgPDwgOCB8IGtleVsxNV0gJiAyNTU7XG4gIHgwIF49IDI3NDYzMzM4OTQ7XG4gIHgxIF49IDE0NTM5OTQ4MzI7XG4gIHgyIF49IDE3MzYyODI1MTk7XG4gIHgzIF49IDI5OTM2OTM0MDQ7XG4gIGZvciAobGV0IHIgPSAwOyByIDwgMzI7IHIgKz0gNCkge1xuICAgIG1pZCA9IHgxIF4geDIgXiB4MyBeIENLW3IgKyAwXTtcbiAgICBtaWQgPSBieXRlU3ViKG1pZCk7XG4gICAgeDAgXj0gbWlkIF4gKG1pZCA8PCAxMyB8IG1pZCA+Pj4gMTkpIF4gKG1pZCA8PCAyMyB8IG1pZCA+Pj4gOSk7XG4gICAgcm91bmRLZXlbciArIDBdID0geDA7XG4gICAgbWlkID0geDIgXiB4MyBeIHgwIF4gQ0tbciArIDFdO1xuICAgIG1pZCA9IGJ5dGVTdWIobWlkKTtcbiAgICB4MSBePSBtaWQgXiAobWlkIDw8IDEzIHwgbWlkID4+PiAxOSkgXiAobWlkIDw8IDIzIHwgbWlkID4+PiA5KTtcbiAgICByb3VuZEtleVtyICsgMV0gPSB4MTtcbiAgICBtaWQgPSB4MyBeIHgwIF4geDEgXiBDS1tyICsgMl07XG4gICAgbWlkID0gYnl0ZVN1YihtaWQpO1xuICAgIHgyIF49IG1pZCBeIChtaWQgPDwgMTMgfCBtaWQgPj4+IDE5KSBeIChtaWQgPDwgMjMgfCBtaWQgPj4+IDkpO1xuICAgIHJvdW5kS2V5W3IgKyAyXSA9IHgyO1xuICAgIG1pZCA9IHgwIF4geDEgXiB4MiBeIENLW3IgKyAzXTtcbiAgICBtaWQgPSBieXRlU3ViKG1pZCk7XG4gICAgeDMgXj0gbWlkIF4gKG1pZCA8PCAxMyB8IG1pZCA+Pj4gMTkpIF4gKG1pZCA8PCAyMyB8IG1pZCA+Pj4gOSk7XG4gICAgcm91bmRLZXlbciArIDNdID0geDM7XG4gIH1cbiAgaWYgKGNyeXB0RmxhZyA9PT0gREVDUllQVCkge1xuICAgIGZvciAobGV0IHIgPSAwOyByIDwgMTY7IHIrKykge1xuICAgICAgW3JvdW5kS2V5W3JdLCByb3VuZEtleVszMSAtIHJdXSA9IFtyb3VuZEtleVszMSAtIHJdLCByb3VuZEtleVtyXV07XG4gICAgfVxuICB9XG59XG52YXIgYmxvY2tPdXRwdXQgPSBuZXcgVWludDhBcnJheSgxNik7XG5mdW5jdGlvbiBzbTQoaW5BcnJheSwga2V5LCBjcnlwdEZsYWcsIG9wdGlvbnMgPSB7fSkge1xuICBsZXQge1xuICAgIHBhZGRpbmcgPSBcInBrY3MjN1wiLFxuICAgIG1vZGUsXG4gICAgaXYgPSBuZXcgVWludDhBcnJheSgxNiksXG4gICAgb3V0cHV0XG4gIH0gPSBvcHRpb25zO1xuICBpZiAobW9kZSA9PT0gXCJjYmNcIikge1xuICAgIGlmICh0eXBlb2YgaXYgPT09IFwic3RyaW5nXCIpXG4gICAgICBpdiA9IGhleFRvQXJyYXkoaXYpO1xuICAgIGlmIChpdi5sZW5ndGggIT09IDEyOCAvIDgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIml2IGlzIGludmFsaWRcIik7XG4gICAgfVxuICB9XG4gIGlmICh0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiKVxuICAgIGtleSA9IGhleFRvQXJyYXkoa2V5KTtcbiAgaWYgKGtleS5sZW5ndGggIT09IDEyOCAvIDgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJrZXkgaXMgaW52YWxpZFwiKTtcbiAgfVxuICBpZiAodHlwZW9mIGluQXJyYXkgPT09IFwic3RyaW5nXCIpIHtcbiAgICBpZiAoY3J5cHRGbGFnICE9PSBERUNSWVBUKSB7XG4gICAgICBpbkFycmF5ID0gdXRmOFRvQXJyYXkoaW5BcnJheSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGluQXJyYXkgPSBoZXhUb0FycmF5KGluQXJyYXkpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpbkFycmF5ID0gVWludDhBcnJheS5mcm9tKGluQXJyYXkpO1xuICB9XG4gIGlmICgocGFkZGluZyA9PT0gXCJwa2NzIzVcIiB8fCBwYWRkaW5nID09PSBcInBrY3MjN1wiKSAmJiBjcnlwdEZsYWcgIT09IERFQ1JZUFQpIHtcbiAgICBjb25zdCBwYWRkaW5nQ291bnQgPSBCTE9DSyAtIGluQXJyYXkubGVuZ3RoICUgQkxPQ0s7XG4gICAgY29uc3QgbmV3QXJyYXkgPSBuZXcgVWludDhBcnJheShpbkFycmF5Lmxlbmd0aCArIHBhZGRpbmdDb3VudCk7XG4gICAgbmV3QXJyYXkuc2V0KGluQXJyYXksIDApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFkZGluZ0NvdW50OyBpKyspXG4gICAgICBuZXdBcnJheVtpbkFycmF5Lmxlbmd0aCArIGldID0gcGFkZGluZ0NvdW50O1xuICAgIGluQXJyYXkgPSBuZXdBcnJheTtcbiAgfVxuICBjb25zdCByb3VuZEtleSA9IG5ldyBVaW50MzJBcnJheShST1VORCk7XG4gIHNtczRLZXlFeHQoa2V5LCByb3VuZEtleSwgY3J5cHRGbGFnKTtcbiAgbGV0IG91dEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoaW5BcnJheS5sZW5ndGgpO1xuICBsZXQgbGFzdFZlY3RvciA9IGl2O1xuICBsZXQgcmVzdExlbiA9IGluQXJyYXkubGVuZ3RoO1xuICBsZXQgcG9pbnQgPSAwO1xuICB3aGlsZSAocmVzdExlbiA+PSBCTE9DSykge1xuICAgIGNvbnN0IGlucHV0ID0gaW5BcnJheS5zdWJhcnJheShwb2ludCwgcG9pbnQgKyAxNik7XG4gICAgaWYgKG1vZGUgPT09IFwiY2JjXCIpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQkxPQ0s7IGkrKykge1xuICAgICAgICBpZiAoY3J5cHRGbGFnICE9PSBERUNSWVBUKSB7XG4gICAgICAgICAgaW5wdXRbaV0gXj0gbGFzdFZlY3RvcltpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBzbXM0Q3J5cHQoaW5wdXQsIGJsb2NrT3V0cHV0LCByb3VuZEtleSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBCTE9DSzsgaSsrKSB7XG4gICAgICBpZiAobW9kZSA9PT0gXCJjYmNcIikge1xuICAgICAgICBpZiAoY3J5cHRGbGFnID09PSBERUNSWVBUKSB7XG4gICAgICAgICAgYmxvY2tPdXRwdXRbaV0gXj0gbGFzdFZlY3RvcltpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgb3V0QXJyYXlbcG9pbnQgKyBpXSA9IGJsb2NrT3V0cHV0W2ldO1xuICAgIH1cbiAgICBpZiAobW9kZSA9PT0gXCJjYmNcIikge1xuICAgICAgaWYgKGNyeXB0RmxhZyAhPT0gREVDUllQVCkge1xuICAgICAgICBsYXN0VmVjdG9yID0gYmxvY2tPdXRwdXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsYXN0VmVjdG9yID0gaW5wdXQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3RMZW4gLT0gQkxPQ0s7XG4gICAgcG9pbnQgKz0gQkxPQ0s7XG4gIH1cbiAgaWYgKChwYWRkaW5nID09PSBcInBrY3MjNVwiIHx8IHBhZGRpbmcgPT09IFwicGtjcyM3XCIpICYmIGNyeXB0RmxhZyA9PT0gREVDUllQVCkge1xuICAgIGNvbnN0IGxlbiA9IG91dEFycmF5Lmxlbmd0aDtcbiAgICBjb25zdCBwYWRkaW5nQ291bnQgPSBvdXRBcnJheVtsZW4gLSAxXTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBwYWRkaW5nQ291bnQ7IGkrKykge1xuICAgICAgaWYgKG91dEFycmF5W2xlbiAtIGldICE9PSBwYWRkaW5nQ291bnQpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInBhZGRpbmcgaXMgaW52YWxpZFwiKTtcbiAgICB9XG4gICAgb3V0QXJyYXkgPSBvdXRBcnJheS5zbGljZSgwLCBsZW4gLSBwYWRkaW5nQ291bnQpO1xuICB9XG4gIGlmIChvdXRwdXQgIT09IFwiYXJyYXlcIikge1xuICAgIGlmIChjcnlwdEZsYWcgIT09IERFQ1JZUFQpIHtcbiAgICAgIHJldHVybiBieXRlc1RvSGV4KG91dEFycmF5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFycmF5VG9VdGY4KG91dEFycmF5KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG91dEFycmF5O1xuICB9XG59XG5mdW5jdGlvbiBlbmNyeXB0KGluQXJyYXksIGtleSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBzbTQoaW5BcnJheSwga2V5LCAxLCBvcHRpb25zKTtcbn1cbmZ1bmN0aW9uIGRlY3J5cHQoaW5BcnJheSwga2V5LCBvcHRpb25zID0ge30pIHtcbiAgcmV0dXJuIHNtNChpbkFycmF5LCBrZXksIDAsIG9wdGlvbnMpO1xufVxuZXhwb3J0IHtcbiAgc20yX2V4cG9ydHMgYXMgc20yLFxuICBzbTMyIGFzIHNtMyxcbiAgc200X2V4cG9ydHMgYXMgc200XG59O1xuLyohIG5vYmxlLWhhc2hlcyAtIE1JVCBMaWNlbnNlIChjKSAyMDIyIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL1xuIiwiLyohIG5vYmxlLWN1cnZlcyAtIE1JVCBMaWNlbnNlIChjKSAyMDIyIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL1xuLy8gMTAwIGxpbmVzIG9mIGNvZGUgaW4gdGhlIGZpbGUgYXJlIGR1cGxpY2F0ZWQgZnJvbSBub2JsZS1oYXNoZXMgKHV0aWxzKS5cbi8vIFRoaXMgaXMgT0s6IGBhYnN0cmFjdGAgZGlyZWN0b3J5IGRvZXMgbm90IHVzZSBub2JsZS1oYXNoZXMuXG4vLyBVc2VyIG1heSBvcHQtaW4gaW50byB1c2luZyBkaWZmZXJlbnQgaGFzaGluZyBsaWJyYXJ5LiBUaGlzIHdheSwgbm9ibGUtaGFzaGVzXG4vLyB3b24ndCBiZSBpbmNsdWRlZCBpbnRvIHRoZWlyIGJ1bmRsZS5cbmNvbnN0IF8wbiA9IEJpZ0ludCgwKTtcbmNvbnN0IF8xbiA9IEJpZ0ludCgxKTtcbmNvbnN0IF8ybiA9IEJpZ0ludCgyKTtcbmNvbnN0IHU4YSA9IChhOiBhbnkpOiBhIGlzIFVpbnQ4QXJyYXkgPT4gYSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk7XG5leHBvcnQgdHlwZSBIZXggPSBVaW50OEFycmF5IHwgc3RyaW5nOyAvLyBoZXggc3RyaW5ncyBhcmUgYWNjZXB0ZWQgZm9yIHNpbXBsaWNpdHlcbmV4cG9ydCB0eXBlIFByaXZLZXkgPSBIZXggfCBiaWdpbnQ7IC8vIGJpZ2ludHMgYXJlIGFjY2VwdGVkIHRvIGVhc2UgbGVhcm5pbmcgY3VydmVcbmV4cG9ydCB0eXBlIENIYXNoID0ge1xuICAobWVzc2FnZTogVWludDhBcnJheSB8IHN0cmluZyk6IFVpbnQ4QXJyYXk7XG4gIGJsb2NrTGVuOiBudW1iZXI7XG4gIG91dHB1dExlbjogbnVtYmVyO1xuICBjcmVhdGUob3B0cz86IHsgZGtMZW4/OiBudW1iZXIgfSk6IGFueTsgLy8gRm9yIHNoYWtlXG59O1xuZXhwb3J0IHR5cGUgRkhhc2ggPSAobWVzc2FnZTogVWludDhBcnJheSB8IHN0cmluZykgPT4gVWludDhBcnJheTtcblxuY29uc3QgaGV4ZXMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiAyNTYgfSwgKHYsIGkpID0+IGkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJykpO1xuLyoqXG4gKiBAZXhhbXBsZSBieXRlc1RvSGV4KFVpbnQ4QXJyYXkuZnJvbShbMHhjYSwgMHhmZSwgMHgwMSwgMHgyM10pKSAvLyAnY2FmZTAxMjMnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBieXRlc1RvSGV4KGJ5dGVzOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgaWYgKCF1OGEoYnl0ZXMpKSB0aHJvdyBuZXcgRXJyb3IoJ1VpbnQ4QXJyYXkgZXhwZWN0ZWQnKTtcbiAgLy8gcHJlLWNhY2hpbmcgaW1wcm92ZXMgdGhlIHNwZWVkIDZ4XG4gIGxldCBoZXggPSAnJztcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuICAgIGhleCArPSBoZXhlc1tieXRlc1tpXV07XG4gIH1cbiAgcmV0dXJuIGhleDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlclRvSGV4VW5wYWRkZWQobnVtOiBudW1iZXIgfCBiaWdpbnQpOiBzdHJpbmcge1xuICBjb25zdCBoZXggPSBudW0udG9TdHJpbmcoMTYpO1xuICByZXR1cm4gaGV4Lmxlbmd0aCAmIDEgPyBgMCR7aGV4fWAgOiBoZXg7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoZXhUb051bWJlcihoZXg6IHN0cmluZyk6IGJpZ2ludCB7XG4gIGlmICh0eXBlb2YgaGV4ICE9PSAnc3RyaW5nJykgdGhyb3cgbmV3IEVycm9yKCdoZXggc3RyaW5nIGV4cGVjdGVkLCBnb3QgJyArIHR5cGVvZiBoZXgpO1xuICAvLyBCaWcgRW5kaWFuXG4gIHJldHVybiBCaWdJbnQoaGV4ID09PSAnJyA/ICcwJyA6IGAweCR7aGV4fWApO1xufVxuXG4vKipcbiAqIEBleGFtcGxlIGhleFRvQnl0ZXMoJ2NhZmUwMTIzJykgLy8gVWludDhBcnJheS5mcm9tKFsweGNhLCAweGZlLCAweDAxLCAweDIzXSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhleFRvQnl0ZXMoaGV4OiBzdHJpbmcpOiBVaW50OEFycmF5IHtcbiAgaWYgKHR5cGVvZiBoZXggIT09ICdzdHJpbmcnKSB0aHJvdyBuZXcgRXJyb3IoJ2hleCBzdHJpbmcgZXhwZWN0ZWQsIGdvdCAnICsgdHlwZW9mIGhleCk7XG4gIGNvbnN0IGxlbiA9IGhleC5sZW5ndGg7XG4gIGlmIChsZW4gJSAyKSB0aHJvdyBuZXcgRXJyb3IoJ3BhZGRlZCBoZXggc3RyaW5nIGV4cGVjdGVkLCBnb3QgdW5wYWRkZWQgaGV4IG9mIGxlbmd0aCAnICsgbGVuKTtcbiAgY29uc3QgYXJyYXkgPSBuZXcgVWludDhBcnJheShsZW4gLyAyKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGogPSBpICogMjtcbiAgICBjb25zdCBoZXhCeXRlID0gaGV4LnNsaWNlKGosIGogKyAyKTtcbiAgICBjb25zdCBieXRlID0gTnVtYmVyLnBhcnNlSW50KGhleEJ5dGUsIDE2KTtcbiAgICBpZiAoTnVtYmVyLmlzTmFOKGJ5dGUpIHx8IGJ5dGUgPCAwKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYnl0ZSBzZXF1ZW5jZScpO1xuICAgIGFycmF5W2ldID0gYnl0ZTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbi8vIEJFOiBCaWcgRW5kaWFuLCBMRTogTGl0dGxlIEVuZGlhblxuZXhwb3J0IGZ1bmN0aW9uIGJ5dGVzVG9OdW1iZXJCRShieXRlczogVWludDhBcnJheSk6IGJpZ2ludCB7XG4gIHJldHVybiBoZXhUb051bWJlcihieXRlc1RvSGV4KGJ5dGVzKSk7XG59XG5leHBvcnQgZnVuY3Rpb24gYnl0ZXNUb051bWJlckxFKGJ5dGVzOiBVaW50OEFycmF5KTogYmlnaW50IHtcbiAgaWYgKCF1OGEoYnl0ZXMpKSB0aHJvdyBuZXcgRXJyb3IoJ1VpbnQ4QXJyYXkgZXhwZWN0ZWQnKTtcbiAgcmV0dXJuIGhleFRvTnVtYmVyKGJ5dGVzVG9IZXgoVWludDhBcnJheS5mcm9tKGJ5dGVzKS5yZXZlcnNlKCkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlclRvQnl0ZXNCRShuOiBudW1iZXIgfCBiaWdpbnQsIGxlbjogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIHJldHVybiBoZXhUb0J5dGVzKG4udG9TdHJpbmcoMTYpLnBhZFN0YXJ0KGxlbiAqIDIsICcwJykpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG51bWJlclRvQnl0ZXNMRShuOiBudW1iZXIgfCBiaWdpbnQsIGxlbjogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIHJldHVybiBudW1iZXJUb0J5dGVzQkUobiwgbGVuKS5yZXZlcnNlKCk7XG59XG4vLyBVbnBhZGRlZCwgcmFyZWx5IHVzZWRcbmV4cG9ydCBmdW5jdGlvbiBudW1iZXJUb1ZhckJ5dGVzQkUobjogbnVtYmVyIHwgYmlnaW50KTogVWludDhBcnJheSB7XG4gIHJldHVybiBoZXhUb0J5dGVzKG51bWJlclRvSGV4VW5wYWRkZWQobikpO1xufVxuXG4vKipcbiAqIFRha2VzIGhleCBzdHJpbmcgb3IgVWludDhBcnJheSwgY29udmVydHMgdG8gVWludDhBcnJheS5cbiAqIFZhbGlkYXRlcyBvdXRwdXQgbGVuZ3RoLlxuICogV2lsbCB0aHJvdyBlcnJvciBmb3Igb3RoZXIgdHlwZXMuXG4gKiBAcGFyYW0gdGl0bGUgZGVzY3JpcHRpdmUgdGl0bGUgZm9yIGFuIGVycm9yIGUuZy4gJ3ByaXZhdGUga2V5J1xuICogQHBhcmFtIGhleCBoZXggc3RyaW5nIG9yIFVpbnQ4QXJyYXlcbiAqIEBwYXJhbSBleHBlY3RlZExlbmd0aCBvcHRpb25hbCwgd2lsbCBjb21wYXJlIHRvIHJlc3VsdCBhcnJheSdzIGxlbmd0aFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZUJ5dGVzKHRpdGxlOiBzdHJpbmcsIGhleDogSGV4LCBleHBlY3RlZExlbmd0aD86IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICBsZXQgcmVzOiBVaW50OEFycmF5O1xuICBpZiAodHlwZW9mIGhleCA9PT0gJ3N0cmluZycpIHtcbiAgICB0cnkge1xuICAgICAgcmVzID0gaGV4VG9CeXRlcyhoZXgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aXRsZX0gbXVzdCBiZSB2YWxpZCBoZXggc3RyaW5nLCBnb3QgXCIke2hleH1cIi4gQ2F1c2U6ICR7ZX1gKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodThhKGhleCkpIHtcbiAgICAvLyBVaW50OEFycmF5LmZyb20oKSBpbnN0ZWFkIG9mIGhhc2guc2xpY2UoKSBiZWNhdXNlIG5vZGUuanMgQnVmZmVyXG4gICAgLy8gaXMgaW5zdGFuY2Ugb2YgVWludDhBcnJheSwgYW5kIGl0cyBzbGljZSgpIGNyZWF0ZXMgKiptdXRhYmxlKiogY29weVxuICAgIHJlcyA9IFVpbnQ4QXJyYXkuZnJvbShoZXgpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHt0aXRsZX0gbXVzdCBiZSBoZXggc3RyaW5nIG9yIFVpbnQ4QXJyYXlgKTtcbiAgfVxuICBjb25zdCBsZW4gPSByZXMubGVuZ3RoO1xuICBpZiAodHlwZW9mIGV4cGVjdGVkTGVuZ3RoID09PSAnbnVtYmVyJyAmJiBsZW4gIT09IGV4cGVjdGVkTGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcihgJHt0aXRsZX0gZXhwZWN0ZWQgJHtleHBlY3RlZExlbmd0aH0gYnl0ZXMsIGdvdCAke2xlbn1gKTtcbiAgcmV0dXJuIHJlcztcbn1cblxuLyoqXG4gKiBDb3BpZXMgc2V2ZXJhbCBVaW50OEFycmF5cyBpbnRvIG9uZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbmNhdEJ5dGVzKC4uLmFycmF5czogVWludDhBcnJheVtdKTogVWludDhBcnJheSB7XG4gIGNvbnN0IHIgPSBuZXcgVWludDhBcnJheShhcnJheXMucmVkdWNlKChzdW0sIGEpID0+IHN1bSArIGEubGVuZ3RoLCAwKSk7XG4gIGxldCBwYWQgPSAwOyAvLyB3YWxrIHRocm91Z2ggZWFjaCBpdGVtLCBlbnN1cmUgdGhleSBoYXZlIHByb3BlciB0eXBlXG4gIGFycmF5cy5mb3JFYWNoKChhKSA9PiB7XG4gICAgaWYgKCF1OGEoYSkpIHRocm93IG5ldyBFcnJvcignVWludDhBcnJheSBleHBlY3RlZCcpO1xuICAgIHIuc2V0KGEsIHBhZCk7XG4gICAgcGFkICs9IGEubGVuZ3RoO1xuICB9KTtcbiAgcmV0dXJuIHI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbEJ5dGVzKGIxOiBVaW50OEFycmF5LCBiMjogVWludDhBcnJheSkge1xuICAvLyBXZSBkb24ndCBjYXJlIGFib3V0IHRpbWluZyBhdHRhY2tzIGhlcmVcbiAgaWYgKGIxLmxlbmd0aCAhPT0gYjIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYjEubGVuZ3RoOyBpKyspIGlmIChiMVtpXSAhPT0gYjJbaV0pIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIEdsb2JhbCBzeW1ib2xzIGluIGJvdGggYnJvd3NlcnMgYW5kIE5vZGUuanMgc2luY2UgdjExXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy8zMTUzNVxuZGVjbGFyZSBjb25zdCBUZXh0RW5jb2RlcjogYW55O1xuXG4vKipcbiAqIEBleGFtcGxlIHV0ZjhUb0J5dGVzKCdhYmMnKSAvLyBuZXcgVWludDhBcnJheShbOTcsIDk4LCA5OV0pXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1dGY4VG9CeXRlcyhzdHI6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHRocm93IG5ldyBFcnJvcihgdXRmOFRvQnl0ZXMgZXhwZWN0ZWQgc3RyaW5nLCBnb3QgJHt0eXBlb2Ygc3RyfWApO1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHN0cikpOyAvLyBodHRwczovL2J1Z3ppbC5sYS8xNjgxODA5XG59XG5cbi8vIEJpdCBvcGVyYXRpb25zXG5cbi8qKlxuICogQ2FsY3VsYXRlcyBhbW91bnQgb2YgYml0cyBpbiBhIGJpZ2ludC5cbiAqIFNhbWUgYXMgYG4udG9TdHJpbmcoMikubGVuZ3RoYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYml0TGVuKG46IGJpZ2ludCkge1xuICBsZXQgbGVuO1xuICBmb3IgKGxlbiA9IDA7IG4gPiBfMG47IG4gPj49IF8xbiwgbGVuICs9IDEpO1xuICByZXR1cm4gbGVuO1xufVxuXG4vKipcbiAqIEdldHMgc2luZ2xlIGJpdCBhdCBwb3NpdGlvbi5cbiAqIE5PVEU6IGZpcnN0IGJpdCBwb3NpdGlvbiBpcyAwIChzYW1lIGFzIGFycmF5cylcbiAqIFNhbWUgYXMgYCEhK0FycmF5LmZyb20obi50b1N0cmluZygyKSkucmV2ZXJzZSgpW3Bvc11gXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaXRHZXQobjogYmlnaW50LCBwb3M6IG51bWJlcikge1xuICByZXR1cm4gKG4gPj4gQmlnSW50KHBvcykpICYgXzFuO1xufVxuXG4vKipcbiAqIFNldHMgc2luZ2xlIGJpdCBhdCBwb3NpdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGJpdFNldCA9IChuOiBiaWdpbnQsIHBvczogbnVtYmVyLCB2YWx1ZTogYm9vbGVhbikgPT4ge1xuICByZXR1cm4gbiB8ICgodmFsdWUgPyBfMW4gOiBfMG4pIDw8IEJpZ0ludChwb3MpKTtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlIG1hc2sgZm9yIE4gYml0cy4gTm90IHVzaW5nICoqIG9wZXJhdG9yIHdpdGggYmlnaW50cyBiZWNhdXNlIG9mIG9sZCBlbmdpbmVzLlxuICogU2FtZSBhcyBCaWdJbnQoYDBiJHtBcnJheShpKS5maWxsKCcxJykuam9pbignJyl9YClcbiAqL1xuZXhwb3J0IGNvbnN0IGJpdE1hc2sgPSAobjogbnVtYmVyKSA9PiAoXzJuIDw8IEJpZ0ludChuIC0gMSkpIC0gXzFuO1xuXG4vLyBEUkJHXG5cbmNvbnN0IHU4biA9IChkYXRhPzogYW55KSA9PiBuZXcgVWludDhBcnJheShkYXRhKTsgLy8gY3JlYXRlcyBVaW50OEFycmF5XG5jb25zdCB1OGZyID0gKGFycjogYW55KSA9PiBVaW50OEFycmF5LmZyb20oYXJyKTsgLy8gYW5vdGhlciBzaG9ydGN1dFxudHlwZSBQcmVkPFQ+ID0gKHY6IFVpbnQ4QXJyYXkpID0+IFQgfCB1bmRlZmluZWQ7XG4vKipcbiAqIE1pbmltYWwgSE1BQy1EUkJHIGZyb20gTklTVCA4MDAtOTAgZm9yIFJGQzY5Nzkgc2lncy5cbiAqIEByZXR1cm5zIGZ1bmN0aW9uIHRoYXQgd2lsbCBjYWxsIERSQkcgdW50aWwgMm5kIGFyZyByZXR1cm5zIHNvbWV0aGluZyBtZWFuaW5nZnVsXG4gKiBAZXhhbXBsZVxuICogICBjb25zdCBkcmJnID0gY3JlYXRlSG1hY0RSQkc8S2V5PigzMiwgMzIsIGhtYWMpO1xuICogICBkcmJnKHNlZWQsIGJ5dGVzVG9LZXkpOyAvLyBieXRlc1RvS2V5IG11c3QgcmV0dXJuIEtleSBvciB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhtYWNEcmJnPFQ+KFxuICBoYXNoTGVuOiBudW1iZXIsXG4gIHFCeXRlTGVuOiBudW1iZXIsXG4gIGhtYWNGbjogKGtleTogVWludDhBcnJheSwgLi4ubWVzc2FnZXM6IFVpbnQ4QXJyYXlbXSkgPT4gVWludDhBcnJheVxuKTogKHNlZWQ6IFVpbnQ4QXJyYXksIHByZWRpY2F0ZTogUHJlZDxUPikgPT4gVCB7XG4gIGlmICh0eXBlb2YgaGFzaExlbiAhPT0gJ251bWJlcicgfHwgaGFzaExlbiA8IDIpIHRocm93IG5ldyBFcnJvcignaGFzaExlbiBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIGlmICh0eXBlb2YgcUJ5dGVMZW4gIT09ICdudW1iZXInIHx8IHFCeXRlTGVuIDwgMikgdGhyb3cgbmV3IEVycm9yKCdxQnl0ZUxlbiBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIGlmICh0eXBlb2YgaG1hY0ZuICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ2htYWNGbiBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgLy8gU3RlcCBCLCBTdGVwIEM6IHNldCBoYXNoTGVuIHRvIDgqY2VpbChobGVuLzgpXG4gIGxldCB2ID0gdThuKGhhc2hMZW4pOyAvLyBNaW5pbWFsIG5vbi1mdWxsLXNwZWMgSE1BQy1EUkJHIGZyb20gTklTVCA4MDAtOTAgZm9yIFJGQzY5Nzkgc2lncy5cbiAgbGV0IGsgPSB1OG4oaGFzaExlbik7IC8vIFN0ZXBzIEIgYW5kIEMgb2YgUkZDNjk3OSAzLjI6IHNldCBoYXNoTGVuLCBpbiBvdXIgY2FzZSBhbHdheXMgc2FtZVxuICBsZXQgaSA9IDA7IC8vIEl0ZXJhdGlvbnMgY291bnRlciwgd2lsbCB0aHJvdyB3aGVuIG92ZXIgMTAwMFxuICBjb25zdCByZXNldCA9ICgpID0+IHtcbiAgICB2LmZpbGwoMSk7XG4gICAgay5maWxsKDApO1xuICAgIGkgPSAwO1xuICB9O1xuICBjb25zdCBoID0gKC4uLmI6IFVpbnQ4QXJyYXlbXSkgPT4gaG1hY0ZuKGssIHYsIC4uLmIpOyAvLyBobWFjKGspKHYsIC4uLnZhbHVlcylcbiAgY29uc3QgcmVzZWVkID0gKHNlZWQgPSB1OG4oKSkgPT4ge1xuICAgIC8vIEhNQUMtRFJCRyByZXNlZWQoKSBmdW5jdGlvbi4gU3RlcHMgRC1HXG4gICAgayA9IGgodThmcihbMHgwMF0pLCBzZWVkKTsgLy8gayA9IGhtYWMoayB8fCB2IHx8IDB4MDAgfHwgc2VlZClcbiAgICB2ID0gaCgpOyAvLyB2ID0gaG1hYyhrIHx8IHYpXG4gICAgaWYgKHNlZWQubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgayA9IGgodThmcihbMHgwMV0pLCBzZWVkKTsgLy8gayA9IGhtYWMoayB8fCB2IHx8IDB4MDEgfHwgc2VlZClcbiAgICB2ID0gaCgpOyAvLyB2ID0gaG1hYyhrIHx8IHYpXG4gIH07XG4gIGNvbnN0IGdlbiA9ICgpID0+IHtcbiAgICAvLyBITUFDLURSQkcgZ2VuZXJhdGUoKSBmdW5jdGlvblxuICAgIGlmIChpKysgPj0gMTAwMCkgdGhyb3cgbmV3IEVycm9yKCdkcmJnOiB0cmllZCAxMDAwIHZhbHVlcycpO1xuICAgIGxldCBsZW4gPSAwO1xuICAgIGNvbnN0IG91dDogVWludDhBcnJheVtdID0gW107XG4gICAgd2hpbGUgKGxlbiA8IHFCeXRlTGVuKSB7XG4gICAgICB2ID0gaCgpO1xuICAgICAgY29uc3Qgc2wgPSB2LnNsaWNlKCk7XG4gICAgICBvdXQucHVzaChzbCk7XG4gICAgICBsZW4gKz0gdi5sZW5ndGg7XG4gICAgfVxuICAgIHJldHVybiBjb25jYXRCeXRlcyguLi5vdXQpO1xuICB9O1xuICBjb25zdCBnZW5VbnRpbCA9IChzZWVkOiBVaW50OEFycmF5LCBwcmVkOiBQcmVkPFQ+KTogVCA9PiB7XG4gICAgcmVzZXQoKTtcbiAgICByZXNlZWQoc2VlZCk7IC8vIFN0ZXBzIEQtR1xuICAgIGxldCByZXM6IFQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7IC8vIFN0ZXAgSDogZ3JpbmQgdW50aWwgayBpcyBpbiBbMS4ubi0xXVxuICAgIHdoaWxlICghKHJlcyA9IHByZWQoZ2VuKCkpKSkgcmVzZWVkKCk7XG4gICAgcmVzZXQoKTtcbiAgICByZXR1cm4gcmVzO1xuICB9O1xuICByZXR1cm4gZ2VuVW50aWw7XG59XG5cbi8vIFZhbGlkYXRpbmcgY3VydmVzIGFuZCBmaWVsZHNcblxuY29uc3QgdmFsaWRhdG9yRm5zID0ge1xuICBiaWdpbnQ6ICh2YWw6IGFueSkgPT4gdHlwZW9mIHZhbCA9PT0gJ2JpZ2ludCcsXG4gIGZ1bmN0aW9uOiAodmFsOiBhbnkpID0+IHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbicsXG4gIGJvb2xlYW46ICh2YWw6IGFueSkgPT4gdHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nLFxuICBzdHJpbmc6ICh2YWw6IGFueSkgPT4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycsXG4gIGlzU2FmZUludGVnZXI6ICh2YWw6IGFueSkgPT4gTnVtYmVyLmlzU2FmZUludGVnZXIodmFsKSxcbiAgYXJyYXk6ICh2YWw6IGFueSkgPT4gQXJyYXkuaXNBcnJheSh2YWwpLFxuICBmaWVsZDogKHZhbDogYW55LCBvYmplY3Q6IGFueSkgPT4gKG9iamVjdCBhcyBhbnkpLkZwLmlzVmFsaWQodmFsKSxcbiAgaGFzaDogKHZhbDogYW55KSA9PiB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nICYmIE51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbC5vdXRwdXRMZW4pLFxufSBhcyBjb25zdDtcbnR5cGUgVmFsaWRhdG9yID0ga2V5b2YgdHlwZW9mIHZhbGlkYXRvckZucztcbnR5cGUgVmFsTWFwPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IHsgW0sgaW4ga2V5b2YgVF0/OiBWYWxpZGF0b3IgfTtcbi8vIHR5cGUgUmVjb3JkPEsgZXh0ZW5kcyBzdHJpbmcgfCBudW1iZXIgfCBzeW1ib2wsIFQ+ID0geyBbUCBpbiBLXTogVDsgfVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVPYmplY3Q8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+KFxuICBvYmplY3Q6IFQsXG4gIHZhbGlkYXRvcnM6IFZhbE1hcDxUPixcbiAgb3B0VmFsaWRhdG9yczogVmFsTWFwPFQ+ID0ge31cbikge1xuICBjb25zdCBjaGVja0ZpZWxkID0gKGZpZWxkTmFtZToga2V5b2YgVCwgdHlwZTogVmFsaWRhdG9yLCBpc09wdGlvbmFsOiBib29sZWFuKSA9PiB7XG4gICAgY29uc3QgY2hlY2tWYWwgPSB2YWxpZGF0b3JGbnNbdHlwZV07XG4gICAgaWYgKHR5cGVvZiBjaGVja1ZhbCAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB2YWxpZGF0b3IgXCIke3R5cGV9XCIsIGV4cGVjdGVkIGZ1bmN0aW9uYCk7XG5cbiAgICBjb25zdCB2YWwgPSBvYmplY3RbZmllbGROYW1lIGFzIGtleW9mIHR5cGVvZiBvYmplY3RdO1xuICAgIGlmIChpc09wdGlvbmFsICYmIHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgaWYgKCFjaGVja1ZhbCh2YWwsIG9iamVjdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgcGFyYW0gJHtTdHJpbmcoZmllbGROYW1lKX09JHt2YWx9ICgke3R5cGVvZiB2YWx9KSwgZXhwZWN0ZWQgJHt0eXBlfWBcbiAgICAgICk7XG4gICAgfVxuICB9O1xuICBmb3IgKGNvbnN0IFtmaWVsZE5hbWUsIHR5cGVdIG9mIE9iamVjdC5lbnRyaWVzKHZhbGlkYXRvcnMpKSBjaGVja0ZpZWxkKGZpZWxkTmFtZSwgdHlwZSEsIGZhbHNlKTtcbiAgZm9yIChjb25zdCBbZmllbGROYW1lLCB0eXBlXSBvZiBPYmplY3QuZW50cmllcyhvcHRWYWxpZGF0b3JzKSkgY2hlY2tGaWVsZChmaWVsZE5hbWUsIHR5cGUhLCB0cnVlKTtcbiAgcmV0dXJuIG9iamVjdDtcbn1cbi8vIHZhbGlkYXRlIHR5cGUgdGVzdHNcbi8vIGNvbnN0IG86IHsgYTogbnVtYmVyOyBiOiBudW1iZXI7IGM6IG51bWJlciB9ID0geyBhOiAxLCBiOiA1LCBjOiA2IH07XG4vLyBjb25zdCB6MCA9IHZhbGlkYXRlT2JqZWN0KG8sIHsgYTogJ2lzU2FmZUludGVnZXInIH0sIHsgYzogJ2JpZ2ludCcgfSk7IC8vIE9rIVxuLy8gLy8gU2hvdWxkIGZhaWwgdHlwZS1jaGVja1xuLy8gY29uc3QgejEgPSB2YWxpZGF0ZU9iamVjdChvLCB7IGE6ICd0bXAnIH0sIHsgYzogJ3p6JyB9KTtcbi8vIGNvbnN0IHoyID0gdmFsaWRhdGVPYmplY3QobywgeyBhOiAnaXNTYWZlSW50ZWdlcicgfSwgeyBjOiAnenonIH0pO1xuLy8gY29uc3QgejMgPSB2YWxpZGF0ZU9iamVjdChvLCB7IHRlc3Q6ICdib29sZWFuJywgejogJ2J1ZycgfSk7XG4vLyBjb25zdCB6NCA9IHZhbGlkYXRlT2JqZWN0KG8sIHsgYTogJ2Jvb2xlYW4nLCB6OiAnYnVnJyB9KTtcbiIsIi8qISBub2JsZS1jdXJ2ZXMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi9cbi8vIFNob3J0IFdlaWVyc3RyYXNzIGN1cnZlLiBUaGUgZm9ybXVsYSBpczogecKyID0geMKzICsgYXggKyBiXG5pbXBvcnQgKiBhcyBtb2QgZnJvbSAnLi9tb2R1bGFyLmpzJztcbmltcG9ydCAqIGFzIHV0IGZyb20gJy4vdXRpbHMuanMnO1xuaW1wb3J0IHsgQ0hhc2gsIEhleCwgUHJpdktleSwgZW5zdXJlQnl0ZXMgfSBmcm9tICcuL3V0aWxzLmpzJztcbmltcG9ydCB7IEdyb3VwLCBHcm91cENvbnN0cnVjdG9yLCB3TkFGLCBCYXNpY0N1cnZlLCB2YWxpZGF0ZUJhc2ljLCBBZmZpbmVQb2ludCB9IGZyb20gJy4vY3VydmUuanMnO1xuXG5leHBvcnQgdHlwZSB7IEFmZmluZVBvaW50IH07XG50eXBlIEhtYWNGblN5bmMgPSAoa2V5OiBVaW50OEFycmF5LCAuLi5tZXNzYWdlczogVWludDhBcnJheVtdKSA9PiBVaW50OEFycmF5O1xudHlwZSBFbmRvbW9ycGhpc21PcHRzID0ge1xuICBiZXRhOiBiaWdpbnQ7XG4gIHNwbGl0U2NhbGFyOiAoazogYmlnaW50KSA9PiB7IGsxbmVnOiBib29sZWFuOyBrMTogYmlnaW50OyBrMm5lZzogYm9vbGVhbjsgazI6IGJpZ2ludCB9O1xufTtcbmV4cG9ydCB0eXBlIEJhc2ljV0N1cnZlPFQ+ID0gQmFzaWNDdXJ2ZTxUPiAmIHtcbiAgLy8gUGFyYW1zOiBhLCBiXG4gIGE6IFQ7XG4gIGI6IFQ7XG5cbiAgLy8gT3B0aW9uYWwgcGFyYW1zXG4gIGFsbG93ZWRQcml2YXRlS2V5TGVuZ3Rocz86IHJlYWRvbmx5IG51bWJlcltdOyAvLyBmb3IgUDUyMVxuICB3cmFwUHJpdmF0ZUtleT86IGJvb2xlYW47IC8vIGJsczEyLTM4MSByZXF1aXJlcyBtb2QobikgaW5zdGVhZCBvZiByZWplY3Rpbmcga2V5cyA+PSBuXG4gIGVuZG8/OiBFbmRvbW9ycGhpc21PcHRzOyAvLyBFbmRvbW9ycGhpc20gb3B0aW9ucyBmb3IgS29ibGl0eiBjdXJ2ZXNcbiAgLy8gV2hlbiBhIGNvZmFjdG9yICE9IDEsIHRoZXJlIGNhbiBiZSBhbiBlZmZlY3RpdmUgbWV0aG9kcyB0bzpcbiAgLy8gMS4gRGV0ZXJtaW5lIHdoZXRoZXIgYSBwb2ludCBpcyB0b3JzaW9uLWZyZWVcbiAgaXNUb3JzaW9uRnJlZT86IChjOiBQcm9qQ29uc3RydWN0b3I8VD4sIHBvaW50OiBQcm9qUG9pbnRUeXBlPFQ+KSA9PiBib29sZWFuO1xuICAvLyAyLiBDbGVhciB0b3JzaW9uIGNvbXBvbmVudFxuICBjbGVhckNvZmFjdG9yPzogKGM6IFByb2pDb25zdHJ1Y3RvcjxUPiwgcG9pbnQ6IFByb2pQb2ludFR5cGU8VD4pID0+IFByb2pQb2ludFR5cGU8VD47XG59O1xuXG50eXBlIEVudHJvcHkgPSBIZXggfCB0cnVlO1xuZXhwb3J0IHR5cGUgU2lnbk9wdHMgPSB7IGxvd1M/OiBib29sZWFuOyBleHRyYUVudHJvcHk/OiBFbnRyb3B5OyBwcmVoYXNoPzogYm9vbGVhbiB9O1xuZXhwb3J0IHR5cGUgVmVyT3B0cyA9IHsgbG93Uz86IGJvb2xlYW47IHByZWhhc2g/OiBib29sZWFuIH07XG5cbi8qKlxuICogIyMjIERlc2lnbiByYXRpb25hbGUgZm9yIHR5cGVzXG4gKlxuICogKiBJbnRlcmFjdGlvbiBiZXR3ZWVuIGNsYXNzZXMgZnJvbSBkaWZmZXJlbnQgY3VydmVzIHNob3VsZCBmYWlsOlxuICogICBgazI1Ni5Qb2ludC5CQVNFLmFkZChwMjU2LlBvaW50LkJBU0UpYFxuICogKiBGb3IgdGhpcyBwdXJwb3NlIHdlIHdhbnQgdG8gdXNlIGBpbnN0YW5jZW9mYCBvcGVyYXRvciwgd2hpY2ggaXMgZmFzdCBhbmQgd29ya3MgZHVyaW5nIHJ1bnRpbWVcbiAqICogRGlmZmVyZW50IGNhbGxzIG9mIGBjdXJ2ZSgpYCB3b3VsZCByZXR1cm4gZGlmZmVyZW50IGNsYXNzZXMgLVxuICogICBgY3VydmUocGFyYW1zKSAhPT0gY3VydmUocGFyYW1zKWA6IGlmIHNvbWVib2R5IGRlY2lkZWQgdG8gbW9ua2V5LXBhdGNoIHRoZWlyIGN1cnZlLFxuICogICBpdCB3b24ndCBhZmZlY3Qgb3RoZXJzXG4gKlxuICogVHlwZVNjcmlwdCBjYW4ndCBpbmZlciB0eXBlcyBmb3IgY2xhc3NlcyBjcmVhdGVkIGluc2lkZSBhIGZ1bmN0aW9uLiBDbGFzc2VzIGlzIG9uZSBpbnN0YW5jZSBvZiBub21pbmF0aXZlIHR5cGVzIGluIFR5cGVTY3JpcHQgYW5kIGludGVyZmFjZXMgb25seSBjaGVjayBmb3Igc2hhcGUsIHNvIGl0J3MgaGFyZCB0byBjcmVhdGUgdW5pcXVlIHR5cGUgZm9yIGV2ZXJ5IGZ1bmN0aW9uIGNhbGwuXG4gKlxuICogV2UgY2FuIHVzZSBnZW5lcmljIHR5cGVzIHZpYSBzb21lIHBhcmFtLCBsaWtlIGN1cnZlIG9wdHMsIGJ1dCB0aGF0IHdvdWxkOlxuICogICAgIDEuIEVuYWJsZSBpbnRlcmFjdGlvbiBiZXR3ZWVuIGBjdXJ2ZShwYXJhbXMpYCBhbmQgYGN1cnZlKHBhcmFtcylgIChjdXJ2ZXMgb2Ygc2FtZSBwYXJhbXMpXG4gKiAgICAgd2hpY2ggaXMgaGFyZCB0byBkZWJ1Zy5cbiAqICAgICAyLiBQYXJhbXMgY2FuIGJlIGdlbmVyaWMgYW5kIHdlIGNhbid0IGVuZm9yY2UgdGhlbSB0byBiZSBjb25zdGFudCB2YWx1ZTpcbiAqICAgICBpZiBzb21lYm9keSBjcmVhdGVzIGN1cnZlIGZyb20gbm9uLWNvbnN0YW50IHBhcmFtcyxcbiAqICAgICBpdCB3b3VsZCBiZSBhbGxvd2VkIHRvIGludGVyYWN0IHdpdGggb3RoZXIgY3VydmVzIHdpdGggbm9uLWNvbnN0YW50IHBhcmFtc1xuICpcbiAqIFRPRE86IGh0dHBzOi8vd3d3LnR5cGVzY3JpcHRsYW5nLm9yZy9kb2NzL2hhbmRib29rL3JlbGVhc2Utbm90ZXMvdHlwZXNjcmlwdC0yLTcuaHRtbCN1bmlxdWUtc3ltYm9sXG4gKi9cblxuLy8gSW5zdGFuY2UgZm9yIDNkIFhZWiBwb2ludHNcbmV4cG9ydCBpbnRlcmZhY2UgUHJvalBvaW50VHlwZTxUPiBleHRlbmRzIEdyb3VwPFByb2pQb2ludFR5cGU8VD4+IHtcbiAgcmVhZG9ubHkgcHg6IFQ7XG4gIHJlYWRvbmx5IHB5OiBUO1xuICByZWFkb25seSBwejogVDtcbiAgZ2V0IHgoKTogVDtcbiAgZ2V0IHkoKTogVDtcbiAgbXVsdGlwbHkoc2NhbGFyOiBiaWdpbnQpOiBQcm9qUG9pbnRUeXBlPFQ+O1xuICB0b0FmZmluZShpej86IFQpOiBBZmZpbmVQb2ludDxUPjtcbiAgaXNUb3JzaW9uRnJlZSgpOiBib29sZWFuO1xuICBjbGVhckNvZmFjdG9yKCk6IFByb2pQb2ludFR5cGU8VD47XG4gIGFzc2VydFZhbGlkaXR5KCk6IHZvaWQ7XG4gIGhhc0V2ZW5ZKCk6IGJvb2xlYW47XG4gIHRvUmF3Qnl0ZXMoaXNDb21wcmVzc2VkPzogYm9vbGVhbik6IFVpbnQ4QXJyYXk7XG4gIHRvSGV4KGlzQ29tcHJlc3NlZD86IGJvb2xlYW4pOiBzdHJpbmc7XG5cbiAgbXVsdGlwbHlVbnNhZmUoc2NhbGFyOiBiaWdpbnQpOiBQcm9qUG9pbnRUeXBlPFQ+O1xuICBtdWx0aXBseUFuZEFkZFVuc2FmZShROiBQcm9qUG9pbnRUeXBlPFQ+LCBhOiBiaWdpbnQsIGI6IGJpZ2ludCk6IFByb2pQb2ludFR5cGU8VD4gfCB1bmRlZmluZWQ7XG4gIF9zZXRXaW5kb3dTaXplKHdpbmRvd1NpemU6IG51bWJlcik6IHZvaWQ7XG59XG4vLyBTdGF0aWMgbWV0aG9kcyBmb3IgM2QgWFlaIHBvaW50c1xuZXhwb3J0IGludGVyZmFjZSBQcm9qQ29uc3RydWN0b3I8VD4gZXh0ZW5kcyBHcm91cENvbnN0cnVjdG9yPFByb2pQb2ludFR5cGU8VD4+IHtcbiAgbmV3ICh4OiBULCB5OiBULCB6OiBUKTogUHJvalBvaW50VHlwZTxUPjtcbiAgZnJvbUFmZmluZShwOiBBZmZpbmVQb2ludDxUPik6IFByb2pQb2ludFR5cGU8VD47XG4gIGZyb21IZXgoaGV4OiBIZXgpOiBQcm9qUG9pbnRUeXBlPFQ+O1xuICBmcm9tUHJpdmF0ZUtleShwcml2YXRlS2V5OiBQcml2S2V5KTogUHJvalBvaW50VHlwZTxUPjtcbiAgbm9ybWFsaXplWihwb2ludHM6IFByb2pQb2ludFR5cGU8VD5bXSk6IFByb2pQb2ludFR5cGU8VD5bXTtcbn1cblxuZXhwb3J0IHR5cGUgQ3VydmVQb2ludHNUeXBlPFQ+ID0gQmFzaWNXQ3VydmU8VD4gJiB7XG4gIC8vIEJ5dGVzXG4gIGZyb21CeXRlcz86IChieXRlczogVWludDhBcnJheSkgPT4gQWZmaW5lUG9pbnQ8VD47XG4gIHRvQnl0ZXM/OiAoYzogUHJvakNvbnN0cnVjdG9yPFQ+LCBwb2ludDogUHJvalBvaW50VHlwZTxUPiwgaXNDb21wcmVzc2VkOiBib29sZWFuKSA9PiBVaW50OEFycmF5O1xufTtcblxuZnVuY3Rpb24gdmFsaWRhdGVQb2ludE9wdHM8VD4oY3VydmU6IEN1cnZlUG9pbnRzVHlwZTxUPikge1xuICBjb25zdCBvcHRzID0gdmFsaWRhdGVCYXNpYyhjdXJ2ZSk7XG4gIHV0LnZhbGlkYXRlT2JqZWN0KFxuICAgIG9wdHMsXG4gICAge1xuICAgICAgYTogJ2ZpZWxkJyxcbiAgICAgIGI6ICdmaWVsZCcsXG4gICAgfSxcbiAgICB7XG4gICAgICBhbGxvd2VkUHJpdmF0ZUtleUxlbmd0aHM6ICdhcnJheScsXG4gICAgICB3cmFwUHJpdmF0ZUtleTogJ2Jvb2xlYW4nLFxuICAgICAgaXNUb3JzaW9uRnJlZTogJ2Z1bmN0aW9uJyxcbiAgICAgIGNsZWFyQ29mYWN0b3I6ICdmdW5jdGlvbicsXG4gICAgICBhbGxvd0luZmluaXR5UG9pbnQ6ICdib29sZWFuJyxcbiAgICAgIGZyb21CeXRlczogJ2Z1bmN0aW9uJyxcbiAgICAgIHRvQnl0ZXM6ICdmdW5jdGlvbicsXG4gICAgfVxuICApO1xuICBjb25zdCB7IGVuZG8sIEZwLCBhIH0gPSBvcHRzO1xuICBpZiAoZW5kbykge1xuICAgIGlmICghRnAuZXFsKGEsIEZwLlpFUk8pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuZG9tb3JwaGlzbSBjYW4gb25seSBiZSBkZWZpbmVkIGZvciBLb2JsaXR6IGN1cnZlcyB0aGF0IGhhdmUgYT0wJyk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBlbmRvICE9PSAnb2JqZWN0JyB8fFxuICAgICAgdHlwZW9mIGVuZG8uYmV0YSAhPT0gJ2JpZ2ludCcgfHxcbiAgICAgIHR5cGVvZiBlbmRvLnNwbGl0U2NhbGFyICE9PSAnZnVuY3Rpb24nXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGVuZG9tb3JwaGlzbSB3aXRoIGJldGE6IGJpZ2ludCBhbmQgc3BsaXRTY2FsYXI6IGZ1bmN0aW9uJyk7XG4gICAgfVxuICB9XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHsgLi4ub3B0cyB9IGFzIGNvbnN0KTtcbn1cblxuZXhwb3J0IHR5cGUgQ3VydmVQb2ludHNSZXM8VD4gPSB7XG4gIFByb2plY3RpdmVQb2ludDogUHJvakNvbnN0cnVjdG9yPFQ+O1xuICBub3JtUHJpdmF0ZUtleVRvU2NhbGFyOiAoa2V5OiBQcml2S2V5KSA9PiBiaWdpbnQ7XG4gIHdlaWVyc3RyYXNzRXF1YXRpb246ICh4OiBUKSA9PiBUO1xuICBpc1dpdGhpbkN1cnZlT3JkZXI6IChudW06IGJpZ2ludCkgPT4gYm9vbGVhbjtcbn07XG5cbi8vIEFTTi4xIERFUiBlbmNvZGluZyB1dGlsaXRpZXNcbmNvbnN0IHsgYnl0ZXNUb051bWJlckJFOiBiMm4sIGhleFRvQnl0ZXM6IGgyYiB9ID0gdXQ7XG5leHBvcnQgY29uc3QgREVSID0ge1xuICAvLyBhc24uMSBERVIgZW5jb2RpbmcgdXRpbHNcbiAgRXJyOiBjbGFzcyBERVJFcnIgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IobSA9ICcnKSB7XG4gICAgICBzdXBlcihtKTtcbiAgICB9XG4gIH0sXG4gIF9wYXJzZUludChkYXRhOiBVaW50OEFycmF5KTogeyBkOiBiaWdpbnQ7IGw6IFVpbnQ4QXJyYXkgfSB7XG4gICAgY29uc3QgeyBFcnI6IEUgfSA9IERFUjtcbiAgICBpZiAoZGF0YS5sZW5ndGggPCAyIHx8IGRhdGFbMF0gIT09IDB4MDIpIHRocm93IG5ldyBFKCdJbnZhbGlkIHNpZ25hdHVyZSBpbnRlZ2VyIHRhZycpO1xuICAgIGNvbnN0IGxlbiA9IGRhdGFbMV07XG4gICAgY29uc3QgcmVzID0gZGF0YS5zdWJhcnJheSgyLCBsZW4gKyAyKTtcbiAgICBpZiAoIWxlbiB8fCByZXMubGVuZ3RoICE9PSBsZW4pIHRocm93IG5ldyBFKCdJbnZhbGlkIHNpZ25hdHVyZSBpbnRlZ2VyOiB3cm9uZyBsZW5ndGgnKTtcbiAgICAvLyBodHRwczovL2NyeXB0by5zdGFja2V4Y2hhbmdlLmNvbS9hLzU3NzM0IExlZnRtb3N0IGJpdCBvZiBmaXJzdCBieXRlIGlzICduZWdhdGl2ZScgZmxhZyxcbiAgICAvLyBzaW5jZSB3ZSBhbHdheXMgdXNlIHBvc2l0aXZlIGludGVnZXJzIGhlcmUuIEl0IG11c3QgYWx3YXlzIGJlIGVtcHR5OlxuICAgIC8vIC0gYWRkIHplcm8gYnl0ZSBpZiBleGlzdHNcbiAgICAvLyAtIGlmIG5leHQgYnl0ZSBkb2Vzbid0IGhhdmUgYSBmbGFnLCBsZWFkaW5nIHplcm8gaXMgbm90IGFsbG93ZWQgKG1pbmltYWwgZW5jb2RpbmcpXG4gICAgaWYgKHJlc1swXSAmIDBiMTAwMDAwMDApIHRocm93IG5ldyBFKCdJbnZhbGlkIHNpZ25hdHVyZSBpbnRlZ2VyOiBuZWdhdGl2ZScpO1xuICAgIGlmIChyZXNbMF0gPT09IDB4MDAgJiYgIShyZXNbMV0gJiAwYjEwMDAwMDAwKSlcbiAgICAgIHRocm93IG5ldyBFKCdJbnZhbGlkIHNpZ25hdHVyZSBpbnRlZ2VyOiB1bm5lY2Vzc2FyeSBsZWFkaW5nIHplcm8nKTtcbiAgICByZXR1cm4geyBkOiBiMm4ocmVzKSwgbDogZGF0YS5zdWJhcnJheShsZW4gKyAyKSB9OyAvLyBkIGlzIGRhdGEsIGwgaXMgbGVmdFxuICB9LFxuICB0b1NpZyhoZXg6IHN0cmluZyB8IFVpbnQ4QXJyYXkpOiB7IHI6IGJpZ2ludDsgczogYmlnaW50IH0ge1xuICAgIC8vIHBhcnNlIERFUiBzaWduYXR1cmVcbiAgICBjb25zdCB7IEVycjogRSB9ID0gREVSO1xuICAgIGNvbnN0IGRhdGEgPSB0eXBlb2YgaGV4ID09PSAnc3RyaW5nJyA/IGgyYihoZXgpIDogaGV4O1xuICAgIGlmICghKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkgdGhyb3cgbmV3IEVycm9yKCd1aThhIGV4cGVjdGVkJyk7XG4gICAgbGV0IGwgPSBkYXRhLmxlbmd0aDtcbiAgICBpZiAobCA8IDIgfHwgZGF0YVswXSAhPSAweDMwKSB0aHJvdyBuZXcgRSgnSW52YWxpZCBzaWduYXR1cmUgdGFnJyk7XG4gICAgaWYgKGRhdGFbMV0gIT09IGwgLSAyKSB0aHJvdyBuZXcgRSgnSW52YWxpZCBzaWduYXR1cmU6IGluY29ycmVjdCBsZW5ndGgnKTtcbiAgICBjb25zdCB7IGQ6IHIsIGw6IHNCeXRlcyB9ID0gREVSLl9wYXJzZUludChkYXRhLnN1YmFycmF5KDIpKTtcbiAgICBjb25zdCB7IGQ6IHMsIGw6IHJCeXRlc0xlZnQgfSA9IERFUi5fcGFyc2VJbnQoc0J5dGVzKTtcbiAgICBpZiAockJ5dGVzTGVmdC5sZW5ndGgpIHRocm93IG5ldyBFKCdJbnZhbGlkIHNpZ25hdHVyZTogbGVmdCBieXRlcyBhZnRlciBwYXJzaW5nJyk7XG4gICAgcmV0dXJuIHsgciwgcyB9O1xuICB9LFxuICBoZXhGcm9tU2lnKHNpZzogeyByOiBiaWdpbnQ7IHM6IGJpZ2ludCB9KTogc3RyaW5nIHtcbiAgICAvLyBBZGQgbGVhZGluZyB6ZXJvIGlmIGZpcnN0IGJ5dGUgaGFzIG5lZ2F0aXZlIGJpdCBlbmFibGVkLiBNb3JlIGRldGFpbHMgaW4gJ19wYXJzZUludCdcbiAgICBjb25zdCBzbGljZSA9IChzOiBzdHJpbmcpOiBzdHJpbmcgPT4gKE51bWJlci5wYXJzZUludChzWzBdLCAxNikgJiAwYjEwMDAgPyAnMDAnICsgcyA6IHMpO1xuICAgIGNvbnN0IGggPSAobnVtOiBudW1iZXIgfCBiaWdpbnQpID0+IHtcbiAgICAgIGNvbnN0IGhleCA9IG51bS50b1N0cmluZygxNik7XG4gICAgICByZXR1cm4gaGV4Lmxlbmd0aCAmIDEgPyBgMCR7aGV4fWAgOiBoZXg7XG4gICAgfTtcbiAgICBjb25zdCBzID0gc2xpY2UoaChzaWcucykpO1xuICAgIGNvbnN0IHIgPSBzbGljZShoKHNpZy5yKSk7XG4gICAgY29uc3Qgc2hsID0gcy5sZW5ndGggLyAyO1xuICAgIGNvbnN0IHJobCA9IHIubGVuZ3RoIC8gMjtcbiAgICBjb25zdCBzbCA9IGgoc2hsKTtcbiAgICBjb25zdCBybCA9IGgocmhsKTtcbiAgICByZXR1cm4gYDMwJHtoKHJobCArIHNobCArIDQpfTAyJHtybH0ke3J9MDIke3NsfSR7c31gO1xuICB9LFxufTtcblxuLy8gQmUgZnJpZW5kbHkgdG8gYmFkIEVDTUFTY3JpcHQgcGFyc2VycyBieSBub3QgdXNpbmcgYmlnaW50IGxpdGVyYWxzXG4vLyBwcmV0dGllci1pZ25vcmVcbmNvbnN0IF8wbiA9IEJpZ0ludCgwKSwgXzFuID0gQmlnSW50KDEpLCBfMm4gPSBCaWdJbnQoMiksIF8zbiA9IEJpZ0ludCgzKSwgXzRuID0gQmlnSW50KDQpO1xuXG5leHBvcnQgZnVuY3Rpb24gd2VpZXJzdHJhc3NQb2ludHM8VD4ob3B0czogQ3VydmVQb2ludHNUeXBlPFQ+KSB7XG4gIGNvbnN0IENVUlZFID0gdmFsaWRhdGVQb2ludE9wdHMob3B0cyk7XG4gIGNvbnN0IHsgRnAgfSA9IENVUlZFOyAvLyBBbGwgY3VydmVzIGhhcyBzYW1lIGZpZWxkIC8gZ3JvdXAgbGVuZ3RoIGFzIGZvciBub3csIGJ1dCB0aGV5IGNhbiBkaWZmZXJcblxuICBjb25zdCB0b0J5dGVzID1cbiAgICBDVVJWRS50b0J5dGVzIHx8XG4gICAgKChjOiBQcm9qQ29uc3RydWN0b3I8VD4sIHBvaW50OiBQcm9qUG9pbnRUeXBlPFQ+LCBpc0NvbXByZXNzZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgIGNvbnN0IGEgPSBwb2ludC50b0FmZmluZSgpO1xuICAgICAgcmV0dXJuIHV0LmNvbmNhdEJ5dGVzKFVpbnQ4QXJyYXkuZnJvbShbMHgwNF0pLCBGcC50b0J5dGVzKGEueCksIEZwLnRvQnl0ZXMoYS55KSk7XG4gICAgfSk7XG4gIGNvbnN0IGZyb21CeXRlcyA9XG4gICAgQ1VSVkUuZnJvbUJ5dGVzIHx8XG4gICAgKChieXRlczogVWludDhBcnJheSkgPT4ge1xuICAgICAgLy8gY29uc3QgaGVhZCA9IGJ5dGVzWzBdO1xuICAgICAgY29uc3QgdGFpbCA9IGJ5dGVzLnN1YmFycmF5KDEpO1xuICAgICAgLy8gaWYgKGhlYWQgIT09IDB4MDQpIHRocm93IG5ldyBFcnJvcignT25seSBub24tY29tcHJlc3NlZCBlbmNvZGluZyBpcyBzdXBwb3J0ZWQnKTtcbiAgICAgIGNvbnN0IHggPSBGcC5mcm9tQnl0ZXModGFpbC5zdWJhcnJheSgwLCBGcC5CWVRFUykpO1xuICAgICAgY29uc3QgeSA9IEZwLmZyb21CeXRlcyh0YWlsLnN1YmFycmF5KEZwLkJZVEVTLCAyICogRnAuQllURVMpKTtcbiAgICAgIHJldHVybiB7IHgsIHkgfTtcbiAgICB9KTtcblxuICAvKipcbiAgICogecKyID0geMKzICsgYXggKyBiOiBTaG9ydCB3ZWllcnN0cmFzcyBjdXJ2ZSBmb3JtdWxhXG4gICAqIEByZXR1cm5zIHnCslxuICAgKi9cbiAgZnVuY3Rpb24gd2VpZXJzdHJhc3NFcXVhdGlvbih4OiBUKTogVCB7XG4gICAgY29uc3QgeyBhLCBiIH0gPSBDVVJWRTtcbiAgICBjb25zdCB4MiA9IEZwLnNxcih4KTsgLy8geCAqIHhcbiAgICBjb25zdCB4MyA9IEZwLm11bCh4MiwgeCk7IC8vIHgyICogeFxuICAgIHJldHVybiBGcC5hZGQoRnAuYWRkKHgzLCBGcC5tdWwoeCwgYSkpLCBiKTsgLy8geDMgKyBhICogeCArIGJcbiAgfVxuICAvLyBWYWxpZGF0ZSB3aGV0aGVyIHRoZSBwYXNzZWQgY3VydmUgcGFyYW1zIGFyZSB2YWxpZC5cbiAgLy8gV2UgY2hlY2sgaWYgY3VydmUgZXF1YXRpb24gd29ya3MgZm9yIGdlbmVyYXRvciBwb2ludC5cbiAgLy8gYGFzc2VydFZhbGlkaXR5KClgIHdvbid0IHdvcms6IGBpc1RvcnNpb25GcmVlKClgIGlzIG5vdCBhdmFpbGFibGUgYXQgdGhpcyBwb2ludCBpbiBibHMxMi0zODEuXG4gIC8vIFByb2plY3RpdmVQb2ludCBjbGFzcyBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgeWV0LlxuICBpZiAoIUZwLmVxbChGcC5zcXIoQ1VSVkUuR3kpLCB3ZWllcnN0cmFzc0VxdWF0aW9uKENVUlZFLkd4KSkpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdiYWQgZ2VuZXJhdG9yIHBvaW50OiBlcXVhdGlvbiBsZWZ0ICE9IHJpZ2h0Jyk7XG5cbiAgLy8gVmFsaWQgZ3JvdXAgZWxlbWVudHMgcmVzaWRlIGluIHJhbmdlIDEuLm4tMVxuICBmdW5jdGlvbiBpc1dpdGhpbkN1cnZlT3JkZXIobnVtOiBiaWdpbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHlwZW9mIG51bSA9PT0gJ2JpZ2ludCcgJiYgXzBuIDwgbnVtICYmIG51bSA8IENVUlZFLm47XG4gIH1cbiAgZnVuY3Rpb24gYXNzZXJ0R0UobnVtOiBiaWdpbnQpIHtcbiAgICBpZiAoIWlzV2l0aGluQ3VydmVPcmRlcihudW0pKSB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHZhbGlkIGJpZ2ludDogMCA8IGJpZ2ludCA8IGN1cnZlLm4nKTtcbiAgfVxuICAvLyBWYWxpZGF0ZXMgaWYgcHJpdiBrZXkgaXMgdmFsaWQgYW5kIGNvbnZlcnRzIGl0IHRvIGJpZ2ludC5cbiAgLy8gU3VwcG9ydHMgb3B0aW9ucyBhbGxvd2VkUHJpdmF0ZUtleUxlbmd0aHMgYW5kIHdyYXBQcml2YXRlS2V5LlxuICBmdW5jdGlvbiBub3JtUHJpdmF0ZUtleVRvU2NhbGFyKGtleTogUHJpdktleSk6IGJpZ2ludCB7XG4gICAgY29uc3QgeyBhbGxvd2VkUHJpdmF0ZUtleUxlbmd0aHM6IGxlbmd0aHMsIG5CeXRlTGVuZ3RoLCB3cmFwUHJpdmF0ZUtleSwgbiB9ID0gQ1VSVkU7XG4gICAgaWYgKGxlbmd0aHMgJiYgdHlwZW9mIGtleSAhPT0gJ2JpZ2ludCcpIHtcbiAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBVaW50OEFycmF5KSBrZXkgPSB1dC5ieXRlc1RvSGV4KGtleSk7XG4gICAgICAvLyBOb3JtYWxpemUgdG8gaGV4IHN0cmluZywgcGFkLiBFLmcuIFA1MjEgd291bGQgbm9ybSAxMzAtMTMyIGNoYXIgaGV4IHRvIDEzMi1jaGFyIGJ5dGVzXG4gICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycgfHwgIWxlbmd0aHMuaW5jbHVkZXMoa2V5Lmxlbmd0aCkpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBrZXknKTtcbiAgICAgIGtleSA9IGtleS5wYWRTdGFydChuQnl0ZUxlbmd0aCAqIDIsICcwJyk7XG4gICAgfVxuICAgIGxldCBudW06IGJpZ2ludDtcbiAgICB0cnkge1xuICAgICAgbnVtID1cbiAgICAgICAgdHlwZW9mIGtleSA9PT0gJ2JpZ2ludCdcbiAgICAgICAgICA/IGtleVxuICAgICAgICAgIDogdXQuYnl0ZXNUb051bWJlckJFKGVuc3VyZUJ5dGVzKCdwcml2YXRlIGtleScsIGtleSwgbkJ5dGVMZW5ndGgpKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBwcml2YXRlIGtleSBtdXN0IGJlICR7bkJ5dGVMZW5ndGh9IGJ5dGVzLCBoZXggb3IgYmlnaW50LCBub3QgJHt0eXBlb2Yga2V5fWApO1xuICAgIH1cbiAgICBpZiAod3JhcFByaXZhdGVLZXkpIG51bSA9IG1vZC5tb2QobnVtLCBuKTsgLy8gZGlzYWJsZWQgYnkgZGVmYXVsdCwgZW5hYmxlZCBmb3IgQkxTXG4gICAgYXNzZXJ0R0UobnVtKTsgLy8gbnVtIGluIHJhbmdlIFsxLi5OLTFdXG4gICAgcmV0dXJuIG51bTtcbiAgfVxuXG4gIGNvbnN0IHBvaW50UHJlY29tcHV0ZXMgPSBuZXcgTWFwPFBvaW50LCBQb2ludFtdPigpO1xuICBmdW5jdGlvbiBhc3NlcnRQcmpQb2ludChvdGhlcjogdW5rbm93bikge1xuICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgUG9pbnQpKSB0aHJvdyBuZXcgRXJyb3IoJ1Byb2plY3RpdmVQb2ludCBleHBlY3RlZCcpO1xuICB9XG4gIC8qKlxuICAgKiBQcm9qZWN0aXZlIFBvaW50IHdvcmtzIGluIDNkIC8gcHJvamVjdGl2ZSAoaG9tb2dlbmVvdXMpIGNvb3JkaW5hdGVzOiAoeCwgeSwgeikg4oiLICh4PXgveiwgeT15L3opXG4gICAqIERlZmF1bHQgUG9pbnQgd29ya3MgaW4gMmQgLyBhZmZpbmUgY29vcmRpbmF0ZXM6ICh4LCB5KVxuICAgKiBXZSdyZSBkb2luZyBjYWxjdWxhdGlvbnMgaW4gcHJvamVjdGl2ZSwgYmVjYXVzZSBpdHMgb3BlcmF0aW9ucyBkb24ndCByZXF1aXJlIGNvc3RseSBpbnZlcnNpb24uXG4gICAqL1xuICBjbGFzcyBQb2ludCBpbXBsZW1lbnRzIFByb2pQb2ludFR5cGU8VD4ge1xuICAgIHN0YXRpYyByZWFkb25seSBCQVNFID0gbmV3IFBvaW50KENVUlZFLkd4LCBDVVJWRS5HeSwgRnAuT05FKTtcbiAgICBzdGF0aWMgcmVhZG9ubHkgWkVSTyA9IG5ldyBQb2ludChGcC5aRVJPLCBGcC5PTkUsIEZwLlpFUk8pO1xuXG4gICAgY29uc3RydWN0b3IocmVhZG9ubHkgcHg6IFQsIHJlYWRvbmx5IHB5OiBULCByZWFkb25seSBwejogVCkge1xuICAgICAgaWYgKHB4ID09IG51bGwgfHwgIUZwLmlzVmFsaWQocHgpKSB0aHJvdyBuZXcgRXJyb3IoJ3ggcmVxdWlyZWQnKTtcbiAgICAgIGlmIChweSA9PSBudWxsIHx8ICFGcC5pc1ZhbGlkKHB5KSkgdGhyb3cgbmV3IEVycm9yKCd5IHJlcXVpcmVkJyk7XG4gICAgICBpZiAocHogPT0gbnVsbCB8fCAhRnAuaXNWYWxpZChweikpIHRocm93IG5ldyBFcnJvcigneiByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8vIERvZXMgbm90IHZhbGlkYXRlIGlmIHRoZSBwb2ludCBpcyBvbi1jdXJ2ZS5cbiAgICAvLyBVc2UgZnJvbUhleCBpbnN0ZWFkLCBvciBjYWxsIGFzc2VydFZhbGlkaXR5KCkgbGF0ZXIuXG4gICAgc3RhdGljIGZyb21BZmZpbmUocDogQWZmaW5lUG9pbnQ8VD4pOiBQb2ludCB7XG4gICAgICBjb25zdCB7IHgsIHkgfSA9IHAgfHwge307XG4gICAgICBpZiAoIXAgfHwgIUZwLmlzVmFsaWQoeCkgfHwgIUZwLmlzVmFsaWQoeSkpIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhZmZpbmUgcG9pbnQnKTtcbiAgICAgIGlmIChwIGluc3RhbmNlb2YgUG9pbnQpIHRocm93IG5ldyBFcnJvcigncHJvamVjdGl2ZSBwb2ludCBub3QgYWxsb3dlZCcpO1xuICAgICAgY29uc3QgaXMwID0gKGk6IFQpID0+IEZwLmVxbChpLCBGcC5aRVJPKTtcbiAgICAgIC8vIGZyb21BZmZpbmUoeDowLCB5OjApIHdvdWxkIHByb2R1Y2UgKHg6MCwgeTowLCB6OjEpLCBidXQgd2UgbmVlZCAoeDowLCB5OjEsIHo6MClcbiAgICAgIGlmIChpczAoeCkgJiYgaXMwKHkpKSByZXR1cm4gUG9pbnQuWkVSTztcbiAgICAgIHJldHVybiBuZXcgUG9pbnQoeCwgeSwgRnAuT05FKTtcbiAgICB9XG5cbiAgICBnZXQgeCgpOiBUIHtcbiAgICAgIHJldHVybiB0aGlzLnRvQWZmaW5lKCkueDtcbiAgICB9XG4gICAgZ2V0IHkoKTogVCB7XG4gICAgICByZXR1cm4gdGhpcy50b0FmZmluZSgpLnk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGFrZXMgYSBidW5jaCBvZiBQcm9qZWN0aXZlIFBvaW50cyBidXQgZXhlY3V0ZXMgb25seSBvbmVcbiAgICAgKiBpbnZlcnNpb24gb24gYWxsIG9mIHRoZW0uIEludmVyc2lvbiBpcyB2ZXJ5IHNsb3cgb3BlcmF0aW9uLFxuICAgICAqIHNvIHRoaXMgaW1wcm92ZXMgcGVyZm9ybWFuY2UgbWFzc2l2ZWx5LlxuICAgICAqIE9wdGltaXphdGlvbjogY29udmVydHMgYSBsaXN0IG9mIHByb2plY3RpdmUgcG9pbnRzIHRvIGEgbGlzdCBvZiBpZGVudGljYWwgcG9pbnRzIHdpdGggWj0xLlxuICAgICAqL1xuICAgIHN0YXRpYyBub3JtYWxpemVaKHBvaW50czogUG9pbnRbXSk6IFBvaW50W10ge1xuICAgICAgY29uc3QgdG9JbnYgPSBGcC5pbnZlcnRCYXRjaChwb2ludHMubWFwKChwKSA9PiBwLnB6KSk7XG4gICAgICByZXR1cm4gcG9pbnRzLm1hcCgocCwgaSkgPT4gcC50b0FmZmluZSh0b0ludltpXSkpLm1hcChQb2ludC5mcm9tQWZmaW5lKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBoYXNoIHN0cmluZyBvciBVaW50OEFycmF5IHRvIFBvaW50LlxuICAgICAqIEBwYXJhbSBoZXggc2hvcnQvbG9uZyBFQ0RTQSBoZXhcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbUhleChoZXg6IEhleCk6IFBvaW50IHtcbiAgICAgIGNvbnN0IFAgPSBQb2ludC5mcm9tQWZmaW5lKGZyb21CeXRlcyhlbnN1cmVCeXRlcygncG9pbnRIZXgnLCBoZXgpKSk7XG4gICAgICBQLmFzc2VydFZhbGlkaXR5KCk7XG4gICAgICByZXR1cm4gUDtcbiAgICB9XG5cbiAgICAvLyBNdWx0aXBsaWVzIGdlbmVyYXRvciBwb2ludCBieSBwcml2YXRlS2V5LlxuICAgIHN0YXRpYyBmcm9tUHJpdmF0ZUtleShwcml2YXRlS2V5OiBQcml2S2V5KSB7XG4gICAgICByZXR1cm4gUG9pbnQuQkFTRS5tdWx0aXBseShub3JtUHJpdmF0ZUtleVRvU2NhbGFyKHByaXZhdGVLZXkpKTtcbiAgICB9XG5cbiAgICAvLyBXZSBjYWxjdWxhdGUgcHJlY29tcHV0ZXMgZm9yIGVsbGlwdGljIGN1cnZlIHBvaW50IG11bHRpcGxpY2F0aW9uXG4gICAgLy8gdXNpbmcgd2luZG93ZWQgbWV0aG9kLiBUaGlzIHNwZWNpZmllcyB3aW5kb3cgc2l6ZSBhbmRcbiAgICAvLyBzdG9yZXMgcHJlY29tcHV0ZWQgdmFsdWVzLiBVc3VhbGx5IG9ubHkgYmFzZSBwb2ludCB3b3VsZCBiZSBwcmVjb21wdXRlZC5cbiAgICBfV0lORE9XX1NJWkU/OiBudW1iZXI7XG5cbiAgICAvLyBcIlByaXZhdGUgbWV0aG9kXCIsIGRvbid0IHVzZSBpdCBkaXJlY3RseVxuICAgIF9zZXRXaW5kb3dTaXplKHdpbmRvd1NpemU6IG51bWJlcikge1xuICAgICAgdGhpcy5fV0lORE9XX1NJWkUgPSB3aW5kb3dTaXplO1xuICAgICAgcG9pbnRQcmVjb21wdXRlcy5kZWxldGUodGhpcyk7XG4gICAgfVxuXG4gICAgLy8gQSBwb2ludCBvbiBjdXJ2ZSBpcyB2YWxpZCBpZiBpdCBjb25mb3JtcyB0byBlcXVhdGlvbi5cbiAgICBhc3NlcnRWYWxpZGl0eSgpOiB2b2lkIHtcbiAgICAgIC8vIFplcm8gaXMgdmFsaWQgcG9pbnQgdG9vIVxuICAgICAgaWYgKHRoaXMuaXMwKCkpIHtcbiAgICAgICAgaWYgKENVUlZFLmFsbG93SW5maW5pdHlQb2ludCkgcmV0dXJuO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwb2ludDogWkVSTycpO1xuICAgICAgfVxuICAgICAgLy8gU29tZSAzcmQtcGFydHkgdGVzdCB2ZWN0b3JzIHJlcXVpcmUgZGlmZmVyZW50IHdvcmRpbmcgYmV0d2VlbiBoZXJlICYgYGZyb21Db21wcmVzc2VkSGV4YFxuICAgICAgY29uc3QgeyB4LCB5IH0gPSB0aGlzLnRvQWZmaW5lKCk7XG4gICAgICAvLyBDaGVjayBpZiB4LCB5IGFyZSB2YWxpZCBmaWVsZCBlbGVtZW50c1xuICAgICAgaWYgKCFGcC5pc1ZhbGlkKHgpIHx8ICFGcC5pc1ZhbGlkKHkpKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwb2ludDogeCBvciB5IG5vdCBGRScpO1xuICAgICAgY29uc3QgbGVmdCA9IEZwLnNxcih5KTsgLy8gecKyXG4gICAgICBjb25zdCByaWdodCA9IHdlaWVyc3RyYXNzRXF1YXRpb24oeCk7IC8vIHjCsyArIGF4ICsgYlxuICAgICAgaWYgKCFGcC5lcWwobGVmdCwgcmlnaHQpKSB0aHJvdyBuZXcgRXJyb3IoJ2JhZCBwb2ludDogZXF1YXRpb24gbGVmdCAhPSByaWdodCcpO1xuICAgICAgaWYgKCF0aGlzLmlzVG9yc2lvbkZyZWUoKSkgdGhyb3cgbmV3IEVycm9yKCdiYWQgcG9pbnQ6IG5vdCBpbiBwcmltZS1vcmRlciBzdWJncm91cCcpO1xuICAgIH1cbiAgICBoYXNFdmVuWSgpOiBib29sZWFuIHtcbiAgICAgIGNvbnN0IHsgeSB9ID0gdGhpcy50b0FmZmluZSgpO1xuICAgICAgaWYgKEZwLmlzT2RkKSByZXR1cm4gIUZwLmlzT2RkKHkpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRmllbGQgZG9lc24ndCBzdXBwb3J0IGlzT2RkXCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBhcmUgb25lIHBvaW50IHRvIGFub3RoZXIuXG4gICAgICovXG4gICAgZXF1YWxzKG90aGVyOiBQb2ludCk6IGJvb2xlYW4ge1xuICAgICAgYXNzZXJ0UHJqUG9pbnQob3RoZXIpO1xuICAgICAgY29uc3QgeyBweDogWDEsIHB5OiBZMSwgcHo6IFoxIH0gPSB0aGlzO1xuICAgICAgY29uc3QgeyBweDogWDIsIHB5OiBZMiwgcHo6IFoyIH0gPSBvdGhlcjtcbiAgICAgIGNvbnN0IFUxID0gRnAuZXFsKEZwLm11bChYMSwgWjIpLCBGcC5tdWwoWDIsIFoxKSk7XG4gICAgICBjb25zdCBVMiA9IEZwLmVxbChGcC5tdWwoWTEsIFoyKSwgRnAubXVsKFkyLCBaMSkpO1xuICAgICAgcmV0dXJuIFUxICYmIFUyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZsaXBzIHBvaW50IHRvIG9uZSBjb3JyZXNwb25kaW5nIHRvICh4LCAteSkgaW4gQWZmaW5lIGNvb3JkaW5hdGVzLlxuICAgICAqL1xuICAgIG5lZ2F0ZSgpOiBQb2ludCB7XG4gICAgICByZXR1cm4gbmV3IFBvaW50KHRoaXMucHgsIEZwLm5lZyh0aGlzLnB5KSwgdGhpcy5weik7XG4gICAgfVxuXG4gICAgLy8gUmVuZXMtQ29zdGVsbG8tQmF0aW5hIGV4Y2VwdGlvbi1mcmVlIGRvdWJsaW5nIGZvcm11bGEuXG4gICAgLy8gVGhlcmUgaXMgMzAlIGZhc3RlciBKYWNvYmlhbiBmb3JtdWxhLCBidXQgaXQgaXMgbm90IGNvbXBsZXRlLlxuICAgIC8vIGh0dHBzOi8vZXByaW50LmlhY3Iub3JnLzIwMTUvMTA2MCwgYWxnb3JpdGhtIDNcbiAgICAvLyBDb3N0OiA4TSArIDNTICsgMyphICsgMipiMyArIDE1YWRkLlxuICAgIGRvdWJsZSgpIHtcbiAgICAgIGNvbnN0IHsgYSwgYiB9ID0gQ1VSVkU7XG4gICAgICBjb25zdCBiMyA9IEZwLm11bChiLCBfM24pO1xuICAgICAgY29uc3QgeyBweDogWDEsIHB5OiBZMSwgcHo6IFoxIH0gPSB0aGlzO1xuICAgICAgbGV0IFgzID0gRnAuWkVSTywgWTMgPSBGcC5aRVJPLCBaMyA9IEZwLlpFUk87IC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgbGV0IHQwID0gRnAubXVsKFgxLCBYMSk7IC8vIHN0ZXAgMVxuICAgICAgbGV0IHQxID0gRnAubXVsKFkxLCBZMSk7XG4gICAgICBsZXQgdDIgPSBGcC5tdWwoWjEsIFoxKTtcbiAgICAgIGxldCB0MyA9IEZwLm11bChYMSwgWTEpO1xuICAgICAgdDMgPSBGcC5hZGQodDMsIHQzKTsgLy8gc3RlcCA1XG4gICAgICBaMyA9IEZwLm11bChYMSwgWjEpO1xuICAgICAgWjMgPSBGcC5hZGQoWjMsIFozKTtcbiAgICAgIFgzID0gRnAubXVsKGEsIFozKTtcbiAgICAgIFkzID0gRnAubXVsKGIzLCB0Mik7XG4gICAgICBZMyA9IEZwLmFkZChYMywgWTMpOyAvLyBzdGVwIDEwXG4gICAgICBYMyA9IEZwLnN1Yih0MSwgWTMpO1xuICAgICAgWTMgPSBGcC5hZGQodDEsIFkzKTtcbiAgICAgIFkzID0gRnAubXVsKFgzLCBZMyk7XG4gICAgICBYMyA9IEZwLm11bCh0MywgWDMpO1xuICAgICAgWjMgPSBGcC5tdWwoYjMsIFozKTsgLy8gc3RlcCAxNVxuICAgICAgdDIgPSBGcC5tdWwoYSwgdDIpO1xuICAgICAgdDMgPSBGcC5zdWIodDAsIHQyKTtcbiAgICAgIHQzID0gRnAubXVsKGEsIHQzKTtcbiAgICAgIHQzID0gRnAuYWRkKHQzLCBaMyk7XG4gICAgICBaMyA9IEZwLmFkZCh0MCwgdDApOyAvLyBzdGVwIDIwXG4gICAgICB0MCA9IEZwLmFkZChaMywgdDApO1xuICAgICAgdDAgPSBGcC5hZGQodDAsIHQyKTtcbiAgICAgIHQwID0gRnAubXVsKHQwLCB0Myk7XG4gICAgICBZMyA9IEZwLmFkZChZMywgdDApO1xuICAgICAgdDIgPSBGcC5tdWwoWTEsIFoxKTsgLy8gc3RlcCAyNVxuICAgICAgdDIgPSBGcC5hZGQodDIsIHQyKTtcbiAgICAgIHQwID0gRnAubXVsKHQyLCB0Myk7XG4gICAgICBYMyA9IEZwLnN1YihYMywgdDApO1xuICAgICAgWjMgPSBGcC5tdWwodDIsIHQxKTtcbiAgICAgIFozID0gRnAuYWRkKFozLCBaMyk7IC8vIHN0ZXAgMzBcbiAgICAgIFozID0gRnAuYWRkKFozLCBaMyk7XG4gICAgICByZXR1cm4gbmV3IFBvaW50KFgzLCBZMywgWjMpO1xuICAgIH1cblxuICAgIC8vIFJlbmVzLUNvc3RlbGxvLUJhdGluYSBleGNlcHRpb24tZnJlZSBhZGRpdGlvbiBmb3JtdWxhLlxuICAgIC8vIFRoZXJlIGlzIDMwJSBmYXN0ZXIgSmFjb2JpYW4gZm9ybXVsYSwgYnV0IGl0IGlzIG5vdCBjb21wbGV0ZS5cbiAgICAvLyBodHRwczovL2VwcmludC5pYWNyLm9yZy8yMDE1LzEwNjAsIGFsZ29yaXRobSAxXG4gICAgLy8gQ29zdDogMTJNICsgMFMgKyAzKmEgKyAzKmIzICsgMjNhZGQuXG4gICAgYWRkKG90aGVyOiBQb2ludCk6IFBvaW50IHtcbiAgICAgIGFzc2VydFByalBvaW50KG90aGVyKTtcbiAgICAgIGNvbnN0IHsgcHg6IFgxLCBweTogWTEsIHB6OiBaMSB9ID0gdGhpcztcbiAgICAgIGNvbnN0IHsgcHg6IFgyLCBweTogWTIsIHB6OiBaMiB9ID0gb3RoZXI7XG4gICAgICBsZXQgWDMgPSBGcC5aRVJPLCBZMyA9IEZwLlpFUk8sIFozID0gRnAuWkVSTzsgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICBjb25zdCBhID0gQ1VSVkUuYTtcbiAgICAgIGNvbnN0IGIzID0gRnAubXVsKENVUlZFLmIsIF8zbik7XG4gICAgICBsZXQgdDAgPSBGcC5tdWwoWDEsIFgyKTsgLy8gc3RlcCAxXG4gICAgICBsZXQgdDEgPSBGcC5tdWwoWTEsIFkyKTtcbiAgICAgIGxldCB0MiA9IEZwLm11bChaMSwgWjIpO1xuICAgICAgbGV0IHQzID0gRnAuYWRkKFgxLCBZMSk7XG4gICAgICBsZXQgdDQgPSBGcC5hZGQoWDIsIFkyKTsgLy8gc3RlcCA1XG4gICAgICB0MyA9IEZwLm11bCh0MywgdDQpO1xuICAgICAgdDQgPSBGcC5hZGQodDAsIHQxKTtcbiAgICAgIHQzID0gRnAuc3ViKHQzLCB0NCk7XG4gICAgICB0NCA9IEZwLmFkZChYMSwgWjEpO1xuICAgICAgbGV0IHQ1ID0gRnAuYWRkKFgyLCBaMik7IC8vIHN0ZXAgMTBcbiAgICAgIHQ0ID0gRnAubXVsKHQ0LCB0NSk7XG4gICAgICB0NSA9IEZwLmFkZCh0MCwgdDIpO1xuICAgICAgdDQgPSBGcC5zdWIodDQsIHQ1KTtcbiAgICAgIHQ1ID0gRnAuYWRkKFkxLCBaMSk7XG4gICAgICBYMyA9IEZwLmFkZChZMiwgWjIpOyAvLyBzdGVwIDE1XG4gICAgICB0NSA9IEZwLm11bCh0NSwgWDMpO1xuICAgICAgWDMgPSBGcC5hZGQodDEsIHQyKTtcbiAgICAgIHQ1ID0gRnAuc3ViKHQ1LCBYMyk7XG4gICAgICBaMyA9IEZwLm11bChhLCB0NCk7XG4gICAgICBYMyA9IEZwLm11bChiMywgdDIpOyAvLyBzdGVwIDIwXG4gICAgICBaMyA9IEZwLmFkZChYMywgWjMpO1xuICAgICAgWDMgPSBGcC5zdWIodDEsIFozKTtcbiAgICAgIFozID0gRnAuYWRkKHQxLCBaMyk7XG4gICAgICBZMyA9IEZwLm11bChYMywgWjMpO1xuICAgICAgdDEgPSBGcC5hZGQodDAsIHQwKTsgLy8gc3RlcCAyNVxuICAgICAgdDEgPSBGcC5hZGQodDEsIHQwKTtcbiAgICAgIHQyID0gRnAubXVsKGEsIHQyKTtcbiAgICAgIHQ0ID0gRnAubXVsKGIzLCB0NCk7XG4gICAgICB0MSA9IEZwLmFkZCh0MSwgdDIpO1xuICAgICAgdDIgPSBGcC5zdWIodDAsIHQyKTsgLy8gc3RlcCAzMFxuICAgICAgdDIgPSBGcC5tdWwoYSwgdDIpO1xuICAgICAgdDQgPSBGcC5hZGQodDQsIHQyKTtcbiAgICAgIHQwID0gRnAubXVsKHQxLCB0NCk7XG4gICAgICBZMyA9IEZwLmFkZChZMywgdDApO1xuICAgICAgdDAgPSBGcC5tdWwodDUsIHQ0KTsgLy8gc3RlcCAzNVxuICAgICAgWDMgPSBGcC5tdWwodDMsIFgzKTtcbiAgICAgIFgzID0gRnAuc3ViKFgzLCB0MCk7XG4gICAgICB0MCA9IEZwLm11bCh0MywgdDEpO1xuICAgICAgWjMgPSBGcC5tdWwodDUsIFozKTtcbiAgICAgIFozID0gRnAuYWRkKFozLCB0MCk7IC8vIHN0ZXAgNDBcbiAgICAgIHJldHVybiBuZXcgUG9pbnQoWDMsIFkzLCBaMyk7XG4gICAgfVxuXG4gICAgc3VidHJhY3Qob3RoZXI6IFBvaW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5hZGQob3RoZXIubmVnYXRlKCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXMwKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXF1YWxzKFBvaW50LlpFUk8pO1xuICAgIH1cbiAgICBwcml2YXRlIHdOQUYobjogYmlnaW50KTogeyBwOiBQb2ludDsgZjogUG9pbnQgfSB7XG4gICAgICByZXR1cm4gd25hZi53TkFGQ2FjaGVkKHRoaXMsIHBvaW50UHJlY29tcHV0ZXMsIG4sIChjb21wOiBQb2ludFtdKSA9PiB7XG4gICAgICAgIGNvbnN0IHRvSW52ID0gRnAuaW52ZXJ0QmF0Y2goY29tcC5tYXAoKHApID0+IHAucHopKTtcbiAgICAgICAgcmV0dXJuIGNvbXAubWFwKChwLCBpKSA9PiBwLnRvQWZmaW5lKHRvSW52W2ldKSkubWFwKFBvaW50LmZyb21BZmZpbmUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTm9uLWNvbnN0YW50LXRpbWUgbXVsdGlwbGljYXRpb24uIFVzZXMgZG91YmxlLWFuZC1hZGQgYWxnb3JpdGhtLlxuICAgICAqIEl0J3MgZmFzdGVyLCBidXQgc2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIHlvdSBkb24ndCBjYXJlIGFib3V0XG4gICAgICogYW4gZXhwb3NlZCBwcml2YXRlIGtleSBlLmcuIHNpZyB2ZXJpZmljYXRpb24sIHdoaWNoIHdvcmtzIG92ZXIgKnB1YmxpYyoga2V5cy5cbiAgICAgKi9cbiAgICBtdWx0aXBseVVuc2FmZShuOiBiaWdpbnQpOiBQb2ludCB7XG4gICAgICBjb25zdCBJID0gUG9pbnQuWkVSTztcbiAgICAgIGlmIChuID09PSBfMG4pIHJldHVybiBJO1xuICAgICAgYXNzZXJ0R0Uobik7IC8vIFdpbGwgdGhyb3cgb24gMFxuICAgICAgaWYgKG4gPT09IF8xbikgcmV0dXJuIHRoaXM7XG4gICAgICBjb25zdCB7IGVuZG8gfSA9IENVUlZFO1xuICAgICAgaWYgKCFlbmRvKSByZXR1cm4gd25hZi51bnNhZmVMYWRkZXIodGhpcywgbik7XG5cbiAgICAgIC8vIEFwcGx5IGVuZG9tb3JwaGlzbVxuICAgICAgbGV0IHsgazFuZWcsIGsxLCBrMm5lZywgazIgfSA9IGVuZG8uc3BsaXRTY2FsYXIobik7XG4gICAgICBsZXQgazFwID0gSTtcbiAgICAgIGxldCBrMnAgPSBJO1xuICAgICAgbGV0IGQ6IFBvaW50ID0gdGhpcztcbiAgICAgIHdoaWxlIChrMSA+IF8wbiB8fCBrMiA+IF8wbikge1xuICAgICAgICBpZiAoazEgJiBfMW4pIGsxcCA9IGsxcC5hZGQoZCk7XG4gICAgICAgIGlmIChrMiAmIF8xbikgazJwID0gazJwLmFkZChkKTtcbiAgICAgICAgZCA9IGQuZG91YmxlKCk7XG4gICAgICAgIGsxID4+PSBfMW47XG4gICAgICAgIGsyID4+PSBfMW47XG4gICAgICB9XG4gICAgICBpZiAoazFuZWcpIGsxcCA9IGsxcC5uZWdhdGUoKTtcbiAgICAgIGlmIChrMm5lZykgazJwID0gazJwLm5lZ2F0ZSgpO1xuICAgICAgazJwID0gbmV3IFBvaW50KEZwLm11bChrMnAucHgsIGVuZG8uYmV0YSksIGsycC5weSwgazJwLnB6KTtcbiAgICAgIHJldHVybiBrMXAuYWRkKGsycCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgdGltZSBtdWx0aXBsaWNhdGlvbi5cbiAgICAgKiBVc2VzIHdOQUYgbWV0aG9kLiBXaW5kb3dlZCBtZXRob2QgbWF5IGJlIDEwJSBmYXN0ZXIsXG4gICAgICogYnV0IHRha2VzIDJ4IGxvbmdlciB0byBnZW5lcmF0ZSBhbmQgY29uc3VtZXMgMnggbWVtb3J5LlxuICAgICAqIFVzZXMgcHJlY29tcHV0ZXMgd2hlbiBhdmFpbGFibGUuXG4gICAgICogVXNlcyBlbmRvbW9ycGhpc20gZm9yIEtvYmxpdHogY3VydmVzLlxuICAgICAqIEBwYXJhbSBzY2FsYXIgYnkgd2hpY2ggdGhlIHBvaW50IHdvdWxkIGJlIG11bHRpcGxpZWRcbiAgICAgKiBAcmV0dXJucyBOZXcgcG9pbnRcbiAgICAgKi9cbiAgICBtdWx0aXBseShzY2FsYXI6IGJpZ2ludCk6IFBvaW50IHtcbiAgICAgIGFzc2VydEdFKHNjYWxhcik7XG4gICAgICBsZXQgbiA9IHNjYWxhcjtcbiAgICAgIGxldCBwb2ludDogUG9pbnQsIGZha2U6IFBvaW50OyAvLyBGYWtlIHBvaW50IGlzIHVzZWQgdG8gY29uc3QtdGltZSBtdWx0XG4gICAgICBjb25zdCB7IGVuZG8gfSA9IENVUlZFO1xuICAgICAgaWYgKGVuZG8pIHtcbiAgICAgICAgY29uc3QgeyBrMW5lZywgazEsIGsybmVnLCBrMiB9ID0gZW5kby5zcGxpdFNjYWxhcihuKTtcbiAgICAgICAgbGV0IHsgcDogazFwLCBmOiBmMXAgfSA9IHRoaXMud05BRihrMSk7XG4gICAgICAgIGxldCB7IHA6IGsycCwgZjogZjJwIH0gPSB0aGlzLndOQUYoazIpO1xuICAgICAgICBrMXAgPSB3bmFmLmNvbnN0VGltZU5lZ2F0ZShrMW5lZywgazFwKTtcbiAgICAgICAgazJwID0gd25hZi5jb25zdFRpbWVOZWdhdGUoazJuZWcsIGsycCk7XG4gICAgICAgIGsycCA9IG5ldyBQb2ludChGcC5tdWwoazJwLnB4LCBlbmRvLmJldGEpLCBrMnAucHksIGsycC5weik7XG4gICAgICAgIHBvaW50ID0gazFwLmFkZChrMnApO1xuICAgICAgICBmYWtlID0gZjFwLmFkZChmMnApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgeyBwLCBmIH0gPSB0aGlzLndOQUYobik7XG4gICAgICAgIHBvaW50ID0gcDtcbiAgICAgICAgZmFrZSA9IGY7XG4gICAgICB9XG4gICAgICAvLyBOb3JtYWxpemUgYHpgIGZvciBib3RoIHBvaW50cywgYnV0IHJldHVybiBvbmx5IHJlYWwgb25lXG4gICAgICByZXR1cm4gUG9pbnQubm9ybWFsaXplWihbcG9pbnQsIGZha2VdKVswXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFZmZpY2llbnRseSBjYWxjdWxhdGUgYGFQICsgYlFgLiBVbnNhZmUsIGNhbiBleHBvc2UgcHJpdmF0ZSBrZXksIGlmIHVzZWQgaW5jb3JyZWN0bHkuXG4gICAgICogTm90IHVzaW5nIFN0cmF1c3MtU2hhbWlyIHRyaWNrOiBwcmVjb21wdXRhdGlvbiB0YWJsZXMgYXJlIGZhc3Rlci5cbiAgICAgKiBUaGUgdHJpY2sgY291bGQgYmUgdXNlZnVsIGlmIGJvdGggUCBhbmQgUSBhcmUgbm90IEcgKG5vdCBpbiBvdXIgY2FzZSkuXG4gICAgICogQHJldHVybnMgbm9uLXplcm8gYWZmaW5lIHBvaW50XG4gICAgICovXG4gICAgbXVsdGlwbHlBbmRBZGRVbnNhZmUoUTogUG9pbnQsIGE6IGJpZ2ludCwgYjogYmlnaW50KTogUG9pbnQgfCB1bmRlZmluZWQge1xuICAgICAgY29uc3QgRyA9IFBvaW50LkJBU0U7IC8vIE5vIFN0cmF1c3MtU2hhbWlyIHRyaWNrOiB3ZSBoYXZlIDEwJSBmYXN0ZXIgRyBwcmVjb21wdXRlc1xuICAgICAgY29uc3QgbXVsID0gKFxuICAgICAgICBQOiBQb2ludCxcbiAgICAgICAgYTogYmlnaW50IC8vIFNlbGVjdCBmYXN0ZXIgbXVsdGlwbHkoKSBtZXRob2RcbiAgICAgICkgPT4gKGEgPT09IF8wbiB8fCBhID09PSBfMW4gfHwgIVAuZXF1YWxzKEcpID8gUC5tdWx0aXBseVVuc2FmZShhKSA6IFAubXVsdGlwbHkoYSkpO1xuICAgICAgY29uc3Qgc3VtID0gbXVsKHRoaXMsIGEpLmFkZChtdWwoUSwgYikpO1xuICAgICAgcmV0dXJuIHN1bS5pczAoKSA/IHVuZGVmaW5lZCA6IHN1bTtcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0cyBQcm9qZWN0aXZlIHBvaW50IHRvIGFmZmluZSAoeCwgeSkgY29vcmRpbmF0ZXMuXG4gICAgLy8gQ2FuIGFjY2VwdCBwcmVjb21wdXRlZCBaXi0xIC0gZm9yIGV4YW1wbGUsIGZyb20gaW52ZXJ0QmF0Y2guXG4gICAgLy8gKHgsIHksIHopIOKIiyAoeD14L3osIHk9eS96KVxuICAgIHRvQWZmaW5lKGl6PzogVCk6IEFmZmluZVBvaW50PFQ+IHtcbiAgICAgIGNvbnN0IHsgcHg6IHgsIHB5OiB5LCBwejogeiB9ID0gdGhpcztcbiAgICAgIGNvbnN0IGlzMCA9IHRoaXMuaXMwKCk7XG4gICAgICAvLyBJZiBpbnZaIHdhcyAwLCB3ZSByZXR1cm4gemVybyBwb2ludC4gSG93ZXZlciB3ZSBzdGlsbCB3YW50IHRvIGV4ZWN1dGVcbiAgICAgIC8vIGFsbCBvcGVyYXRpb25zLCBzbyB3ZSByZXBsYWNlIGludlogd2l0aCBhIHJhbmRvbSBudW1iZXIsIDEuXG4gICAgICBpZiAoaXogPT0gbnVsbCkgaXogPSBpczAgPyBGcC5PTkUgOiBGcC5pbnYoeik7XG4gICAgICBjb25zdCBheCA9IEZwLm11bCh4LCBpeik7XG4gICAgICBjb25zdCBheSA9IEZwLm11bCh5LCBpeik7XG4gICAgICBjb25zdCB6eiA9IEZwLm11bCh6LCBpeik7XG4gICAgICBpZiAoaXMwKSByZXR1cm4geyB4OiBGcC5aRVJPLCB5OiBGcC5aRVJPIH07XG4gICAgICBpZiAoIUZwLmVxbCh6eiwgRnAuT05FKSkgdGhyb3cgbmV3IEVycm9yKCdpbnZaIHdhcyBpbnZhbGlkJyk7XG4gICAgICByZXR1cm4geyB4OiBheCwgeTogYXkgfTtcbiAgICB9XG4gICAgaXNUb3JzaW9uRnJlZSgpOiBib29sZWFuIHtcbiAgICAgIGNvbnN0IHsgaDogY29mYWN0b3IsIGlzVG9yc2lvbkZyZWUgfSA9IENVUlZFO1xuICAgICAgaWYgKGNvZmFjdG9yID09PSBfMW4pIHJldHVybiB0cnVlOyAvLyBObyBzdWJncm91cHMsIGFsd2F5cyB0b3JzaW9uLWZyZWVcbiAgICAgIGlmIChpc1RvcnNpb25GcmVlKSByZXR1cm4gaXNUb3JzaW9uRnJlZShQb2ludCwgdGhpcyk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lzVG9yc2lvbkZyZWUoKSBoYXMgbm90IGJlZW4gZGVjbGFyZWQgZm9yIHRoZSBlbGxpcHRpYyBjdXJ2ZScpO1xuICAgIH1cbiAgICBjbGVhckNvZmFjdG9yKCk6IFBvaW50IHtcbiAgICAgIGNvbnN0IHsgaDogY29mYWN0b3IsIGNsZWFyQ29mYWN0b3IgfSA9IENVUlZFO1xuICAgICAgaWYgKGNvZmFjdG9yID09PSBfMW4pIHJldHVybiB0aGlzOyAvLyBGYXN0LXBhdGhcbiAgICAgIGlmIChjbGVhckNvZmFjdG9yKSByZXR1cm4gY2xlYXJDb2ZhY3RvcihQb2ludCwgdGhpcykgYXMgUG9pbnQ7XG4gICAgICByZXR1cm4gdGhpcy5tdWx0aXBseVVuc2FmZShDVVJWRS5oKTtcbiAgICB9XG5cbiAgICB0b1Jhd0J5dGVzKGlzQ29tcHJlc3NlZCA9IHRydWUpOiBVaW50OEFycmF5IHtcbiAgICAgIHRoaXMuYXNzZXJ0VmFsaWRpdHkoKTtcbiAgICAgIHJldHVybiB0b0J5dGVzKFBvaW50LCB0aGlzLCBpc0NvbXByZXNzZWQpO1xuICAgIH1cblxuICAgIHRvSGV4KGlzQ29tcHJlc3NlZCA9IHRydWUpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuIHV0LmJ5dGVzVG9IZXgodGhpcy50b1Jhd0J5dGVzKGlzQ29tcHJlc3NlZCkpO1xuICAgIH1cbiAgfVxuICBjb25zdCBfYml0cyA9IENVUlZFLm5CaXRMZW5ndGg7XG4gIGNvbnN0IHduYWYgPSB3TkFGKFBvaW50LCBDVVJWRS5lbmRvID8gTWF0aC5jZWlsKF9iaXRzIC8gMikgOiBfYml0cyk7XG4gIC8vIFZhbGlkYXRlIGlmIGdlbmVyYXRvciBwb2ludCBpcyBvbiBjdXJ2ZVxuICByZXR1cm4ge1xuICAgIENVUlZFLFxuICAgIFByb2plY3RpdmVQb2ludDogUG9pbnQgYXMgUHJvakNvbnN0cnVjdG9yPFQ+LFxuICAgIG5vcm1Qcml2YXRlS2V5VG9TY2FsYXIsXG4gICAgd2VpZXJzdHJhc3NFcXVhdGlvbixcbiAgICBpc1dpdGhpbkN1cnZlT3JkZXIsXG4gIH07XG59XG5cbi8vIEluc3RhbmNlXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25hdHVyZVR5cGUge1xuICByZWFkb25seSByOiBiaWdpbnQ7XG4gIHJlYWRvbmx5IHM6IGJpZ2ludDtcbiAgcmVhZG9ubHkgcmVjb3Zlcnk/OiBudW1iZXI7XG4gIGFzc2VydFZhbGlkaXR5KCk6IHZvaWQ7XG4gIGFkZFJlY292ZXJ5Qml0KHJlY292ZXJ5OiBudW1iZXIpOiBSZWNvdmVyZWRTaWduYXR1cmVUeXBlO1xuICBoYXNIaWdoUygpOiBib29sZWFuO1xuICBub3JtYWxpemVTKCk6IFNpZ25hdHVyZVR5cGU7XG4gIHJlY292ZXJQdWJsaWNLZXkobXNnSGFzaDogSGV4KTogUHJvalBvaW50VHlwZTxiaWdpbnQ+O1xuICB0b0NvbXBhY3RSYXdCeXRlcygpOiBVaW50OEFycmF5O1xuICB0b0NvbXBhY3RIZXgoKTogc3RyaW5nO1xuICAvLyBERVItZW5jb2RlZFxuICB0b0RFUlJhd0J5dGVzKGlzQ29tcHJlc3NlZD86IGJvb2xlYW4pOiBVaW50OEFycmF5O1xuICB0b0RFUkhleChpc0NvbXByZXNzZWQ/OiBib29sZWFuKTogc3RyaW5nO1xufVxuZXhwb3J0IHR5cGUgUmVjb3ZlcmVkU2lnbmF0dXJlVHlwZSA9IFNpZ25hdHVyZVR5cGUgJiB7XG4gIHJlYWRvbmx5IHJlY292ZXJ5OiBudW1iZXI7XG59O1xuLy8gU3RhdGljIG1ldGhvZHNcbmV4cG9ydCB0eXBlIFNpZ25hdHVyZUNvbnN0cnVjdG9yID0ge1xuICBuZXcgKHI6IGJpZ2ludCwgczogYmlnaW50KTogU2lnbmF0dXJlVHlwZTtcbiAgZnJvbUNvbXBhY3QoaGV4OiBIZXgpOiBTaWduYXR1cmVUeXBlO1xuICBmcm9tREVSKGhleDogSGV4KTogU2lnbmF0dXJlVHlwZTtcbn07XG50eXBlIFNpZ25hdHVyZUxpa2UgPSB7IHI6IGJpZ2ludDsgczogYmlnaW50IH07XG5cbmV4cG9ydCB0eXBlIFB1YktleSA9IEhleCB8IFByb2pQb2ludFR5cGU8YmlnaW50PjtcblxuZXhwb3J0IHR5cGUgQ3VydmVUeXBlID0gQmFzaWNXQ3VydmU8YmlnaW50PiAmIHtcbiAgaGFzaDogQ0hhc2g7IC8vIENIYXNoIG5vdCBGSGFzaCBiZWNhdXNlIHdlIG5lZWQgb3V0cHV0TGVuIGZvciBEUkJHXG4gIGhtYWM6IEhtYWNGblN5bmM7XG4gIHJhbmRvbUJ5dGVzOiAoYnl0ZXNMZW5ndGg/OiBudW1iZXIpID0+IFVpbnQ4QXJyYXk7XG4gIGxvd1M/OiBib29sZWFuO1xuICBiaXRzMmludD86IChieXRlczogVWludDhBcnJheSkgPT4gYmlnaW50O1xuICBiaXRzMmludF9tb2ROPzogKGJ5dGVzOiBVaW50OEFycmF5KSA9PiBiaWdpbnQ7XG59O1xuXG5mdW5jdGlvbiB2YWxpZGF0ZU9wdHMoY3VydmU6IEN1cnZlVHlwZSkge1xuICBjb25zdCBvcHRzID0gdmFsaWRhdGVCYXNpYyhjdXJ2ZSk7XG4gIHV0LnZhbGlkYXRlT2JqZWN0KFxuICAgIG9wdHMsXG4gICAge1xuICAgICAgaGFzaDogJ2hhc2gnLFxuICAgICAgaG1hYzogJ2Z1bmN0aW9uJyxcbiAgICAgIHJhbmRvbUJ5dGVzOiAnZnVuY3Rpb24nLFxuICAgIH0sXG4gICAge1xuICAgICAgYml0czJpbnQ6ICdmdW5jdGlvbicsXG4gICAgICBiaXRzMmludF9tb2ROOiAnZnVuY3Rpb24nLFxuICAgICAgbG93UzogJ2Jvb2xlYW4nLFxuICAgIH1cbiAgKTtcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoeyBsb3dTOiB0cnVlLCAuLi5vcHRzIH0gYXMgY29uc3QpO1xufVxuXG5leHBvcnQgdHlwZSBDdXJ2ZUZuID0ge1xuICBDVVJWRTogUmV0dXJuVHlwZTx0eXBlb2YgdmFsaWRhdGVPcHRzPjtcbiAgZ2V0UHVibGljS2V5OiAocHJpdmF0ZUtleTogUHJpdktleSwgaXNDb21wcmVzc2VkPzogYm9vbGVhbikgPT4gVWludDhBcnJheTtcbiAgZ2V0U2hhcmVkU2VjcmV0OiAocHJpdmF0ZUE6IFByaXZLZXksIHB1YmxpY0I6IEhleCwgaXNDb21wcmVzc2VkPzogYm9vbGVhbikgPT4gVWludDhBcnJheTtcbiAgc2lnbjogKG1zZ0hhc2g6IEhleCwgcHJpdktleTogUHJpdktleSwgb3B0cz86IFNpZ25PcHRzKSA9PiBSZWNvdmVyZWRTaWduYXR1cmVUeXBlO1xuICB2ZXJpZnk6IChzaWduYXR1cmU6IEhleCB8IFNpZ25hdHVyZUxpa2UsIG1zZ0hhc2g6IEhleCwgcHVibGljS2V5OiBIZXgsIG9wdHM/OiBWZXJPcHRzKSA9PiBib29sZWFuO1xuICBQcm9qZWN0aXZlUG9pbnQ6IFByb2pDb25zdHJ1Y3RvcjxiaWdpbnQ+O1xuICBTaWduYXR1cmU6IFNpZ25hdHVyZUNvbnN0cnVjdG9yO1xuICB1dGlsczoge1xuICAgIG5vcm1Qcml2YXRlS2V5VG9TY2FsYXI6IChrZXk6IFByaXZLZXkpID0+IGJpZ2ludDtcbiAgICBpc1ZhbGlkUHJpdmF0ZUtleShwcml2YXRlS2V5OiBQcml2S2V5KTogYm9vbGVhbjtcbiAgICByYW5kb21Qcml2YXRlS2V5OiAoKSA9PiBVaW50OEFycmF5O1xuICAgIHByZWNvbXB1dGU6ICh3aW5kb3dTaXplPzogbnVtYmVyLCBwb2ludD86IFByb2pQb2ludFR5cGU8YmlnaW50PikgPT4gUHJvalBvaW50VHlwZTxiaWdpbnQ+O1xuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHdlaWVyc3RyYXNzKGN1cnZlRGVmOiBDdXJ2ZVR5cGUpOiBDdXJ2ZUZuIHtcbiAgY29uc3QgQ1VSVkUgPSB2YWxpZGF0ZU9wdHMoY3VydmVEZWYpIGFzIFJldHVyblR5cGU8dHlwZW9mIHZhbGlkYXRlT3B0cz47XG4gIGNvbnN0IHsgRnAsIG46IENVUlZFX09SREVSIH0gPSBDVVJWRTtcbiAgY29uc3QgY29tcHJlc3NlZExlbiA9IEZwLkJZVEVTICsgMTsgLy8gZS5nLiAzMyBmb3IgMzJcbiAgY29uc3QgdW5jb21wcmVzc2VkTGVuID0gMiAqIEZwLkJZVEVTICsgMTsgLy8gZS5nLiA2NSBmb3IgMzJcblxuICBmdW5jdGlvbiBpc1ZhbGlkRmllbGRFbGVtZW50KG51bTogYmlnaW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIF8wbiA8IG51bSAmJiBudW0gPCBGcC5PUkRFUjsgLy8gMCBpcyBiYW5uZWQgc2luY2UgaXQncyBub3QgaW52ZXJ0aWJsZSBGRVxuICB9XG4gIGZ1bmN0aW9uIG1vZE4oYTogYmlnaW50KSB7XG4gICAgcmV0dXJuIG1vZC5tb2QoYSwgQ1VSVkVfT1JERVIpO1xuICB9XG4gIGZ1bmN0aW9uIGludk4oYTogYmlnaW50KSB7XG4gICAgcmV0dXJuIG1vZC5pbnZlcnQoYSwgQ1VSVkVfT1JERVIpO1xuICB9XG5cbiAgY29uc3Qge1xuICAgIFByb2plY3RpdmVQb2ludDogUG9pbnQsXG4gICAgbm9ybVByaXZhdGVLZXlUb1NjYWxhcixcbiAgICB3ZWllcnN0cmFzc0VxdWF0aW9uLFxuICAgIGlzV2l0aGluQ3VydmVPcmRlcixcbiAgfSA9IHdlaWVyc3RyYXNzUG9pbnRzKHtcbiAgICAuLi5DVVJWRSxcbiAgICB0b0J5dGVzKGMsIHBvaW50LCBpc0NvbXByZXNzZWQ6IGJvb2xlYW4pOiBVaW50OEFycmF5IHtcbiAgICAgIGNvbnN0IGEgPSBwb2ludC50b0FmZmluZSgpO1xuICAgICAgY29uc3QgeCA9IEZwLnRvQnl0ZXMoYS54KTtcbiAgICAgIGNvbnN0IGNhdCA9IHV0LmNvbmNhdEJ5dGVzO1xuICAgICAgaWYgKGlzQ29tcHJlc3NlZCkge1xuICAgICAgICByZXR1cm4gY2F0KFVpbnQ4QXJyYXkuZnJvbShbcG9pbnQuaGFzRXZlblkoKSA/IDB4MDIgOiAweDAzXSksIHgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNhdChVaW50OEFycmF5LmZyb20oWzB4MDRdKSwgeCwgRnAudG9CeXRlcyhhLnkpKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGZyb21CeXRlcyhieXRlczogVWludDhBcnJheSkge1xuICAgICAgY29uc3QgbGVuID0gYnl0ZXMubGVuZ3RoO1xuICAgICAgY29uc3QgaGVhZCA9IGJ5dGVzWzBdO1xuICAgICAgY29uc3QgdGFpbCA9IGJ5dGVzLnN1YmFycmF5KDEpO1xuICAgICAgLy8gdGhpcy5hc3NlcnRWYWxpZGl0eSgpIGlzIGRvbmUgaW5zaWRlIG9mIGZyb21IZXhcbiAgICAgIGlmIChsZW4gPT09IGNvbXByZXNzZWRMZW4gJiYgKGhlYWQgPT09IDB4MDIgfHwgaGVhZCA9PT0gMHgwMykpIHtcbiAgICAgICAgY29uc3QgeCA9IHV0LmJ5dGVzVG9OdW1iZXJCRSh0YWlsKTtcbiAgICAgICAgaWYgKCFpc1ZhbGlkRmllbGRFbGVtZW50KHgpKSB0aHJvdyBuZXcgRXJyb3IoJ1BvaW50IGlzIG5vdCBvbiBjdXJ2ZScpO1xuICAgICAgICBjb25zdCB5MiA9IHdlaWVyc3RyYXNzRXF1YXRpb24oeCk7IC8vIHnCsiA9IHjCsyArIGF4ICsgYlxuICAgICAgICBsZXQgeSA9IEZwLnNxcnQoeTIpOyAvLyB5ID0gecKyIF4gKHArMSkvNFxuICAgICAgICBjb25zdCBpc1lPZGQgPSAoeSAmIF8xbikgPT09IF8xbjtcbiAgICAgICAgLy8gRUNEU0FcbiAgICAgICAgY29uc3QgaXNIZWFkT2RkID0gKGhlYWQgJiAxKSA9PT0gMTtcbiAgICAgICAgaWYgKGlzSGVhZE9kZCAhPT0gaXNZT2RkKSB5ID0gRnAubmVnKHkpO1xuICAgICAgICByZXR1cm4geyB4LCB5IH07XG4gICAgICB9IGVsc2UgaWYgKGxlbiA9PT0gdW5jb21wcmVzc2VkTGVuICYmIGhlYWQgPT09IDB4MDQpIHtcbiAgICAgICAgY29uc3QgeCA9IEZwLmZyb21CeXRlcyh0YWlsLnN1YmFycmF5KDAsIEZwLkJZVEVTKSk7XG4gICAgICAgIGNvbnN0IHkgPSBGcC5mcm9tQnl0ZXModGFpbC5zdWJhcnJheShGcC5CWVRFUywgMiAqIEZwLkJZVEVTKSk7XG4gICAgICAgIHJldHVybiB7IHgsIHkgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgUG9pbnQgb2YgbGVuZ3RoICR7bGVufSB3YXMgaW52YWxpZC4gRXhwZWN0ZWQgJHtjb21wcmVzc2VkTGVufSBjb21wcmVzc2VkIGJ5dGVzIG9yICR7dW5jb21wcmVzc2VkTGVufSB1bmNvbXByZXNzZWQgYnl0ZXNgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG4gIGNvbnN0IG51bVRvTkJ5dGVTdHIgPSAobnVtOiBiaWdpbnQpOiBzdHJpbmcgPT5cbiAgICB1dC5ieXRlc1RvSGV4KHV0Lm51bWJlclRvQnl0ZXNCRShudW0sIENVUlZFLm5CeXRlTGVuZ3RoKSk7XG5cbiAgZnVuY3Rpb24gaXNCaWdnZXJUaGFuSGFsZk9yZGVyKG51bWJlcjogYmlnaW50KSB7XG4gICAgY29uc3QgSEFMRiA9IENVUlZFX09SREVSID4+IF8xbjtcbiAgICByZXR1cm4gbnVtYmVyID4gSEFMRjtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZVMoczogYmlnaW50KSB7XG4gICAgcmV0dXJuIGlzQmlnZ2VyVGhhbkhhbGZPcmRlcihzKSA/IG1vZE4oLXMpIDogcztcbiAgfVxuICAvLyBzbGljZSBieXRlcyBudW1cbiAgY29uc3Qgc2xjTnVtID0gKGI6IFVpbnQ4QXJyYXksIGZyb206IG51bWJlciwgdG86IG51bWJlcikgPT4gdXQuYnl0ZXNUb051bWJlckJFKGIuc2xpY2UoZnJvbSwgdG8pKTtcblxuICAvKipcbiAgICogRUNEU0Egc2lnbmF0dXJlIHdpdGggaXRzIChyLCBzKSBwcm9wZXJ0aWVzLiBTdXBwb3J0cyBERVIgJiBjb21wYWN0IHJlcHJlc2VudGF0aW9ucy5cbiAgICovXG4gIGNsYXNzIFNpZ25hdHVyZSBpbXBsZW1lbnRzIFNpZ25hdHVyZVR5cGUge1xuICAgIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHI6IGJpZ2ludCwgcmVhZG9ubHkgczogYmlnaW50LCByZWFkb25seSByZWNvdmVyeT86IG51bWJlcikge1xuICAgICAgdGhpcy5hc3NlcnRWYWxpZGl0eSgpO1xuICAgIH1cblxuICAgIC8vIHBhaXIgKGJ5dGVzIG9mIHIsIGJ5dGVzIG9mIHMpXG4gICAgc3RhdGljIGZyb21Db21wYWN0KGhleDogSGV4KSB7XG4gICAgICBjb25zdCBsID0gQ1VSVkUubkJ5dGVMZW5ndGg7XG4gICAgICBoZXggPSBlbnN1cmVCeXRlcygnY29tcGFjdFNpZ25hdHVyZScsIGhleCwgbCAqIDIpO1xuICAgICAgcmV0dXJuIG5ldyBTaWduYXR1cmUoc2xjTnVtKGhleCwgMCwgbCksIHNsY051bShoZXgsIGwsIDIgKiBsKSk7XG4gICAgfVxuXG4gICAgLy8gREVSIGVuY29kZWQgRUNEU0Egc2lnbmF0dXJlXG4gICAgLy8gaHR0cHM6Ly9iaXRjb2luLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy81NzY0NC93aGF0LWFyZS10aGUtcGFydHMtb2YtYS1iaXRjb2luLXRyYW5zYWN0aW9uLWlucHV0LXNjcmlwdFxuICAgIHN0YXRpYyBmcm9tREVSKGhleDogSGV4KSB7XG4gICAgICBjb25zdCB7IHIsIHMgfSA9IERFUi50b1NpZyhlbnN1cmVCeXRlcygnREVSJywgaGV4KSk7XG4gICAgICByZXR1cm4gbmV3IFNpZ25hdHVyZShyLCBzKTtcbiAgICB9XG5cbiAgICBhc3NlcnRWYWxpZGl0eSgpOiB2b2lkIHtcbiAgICAgIC8vIGNhbiB1c2UgYXNzZXJ0R0UgaGVyZVxuICAgICAgaWYgKCFpc1dpdGhpbkN1cnZlT3JkZXIodGhpcy5yKSkgdGhyb3cgbmV3IEVycm9yKCdyIG11c3QgYmUgMCA8IHIgPCBDVVJWRS5uJyk7XG4gICAgICBpZiAoIWlzV2l0aGluQ3VydmVPcmRlcih0aGlzLnMpKSB0aHJvdyBuZXcgRXJyb3IoJ3MgbXVzdCBiZSAwIDwgcyA8IENVUlZFLm4nKTtcbiAgICB9XG5cbiAgICBhZGRSZWNvdmVyeUJpdChyZWNvdmVyeTogbnVtYmVyKTogUmVjb3ZlcmVkU2lnbmF0dXJlIHtcbiAgICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHRoaXMuciwgdGhpcy5zLCByZWNvdmVyeSkgYXMgUmVjb3ZlcmVkU2lnbmF0dXJlO1xuICAgIH1cblxuICAgIHJlY292ZXJQdWJsaWNLZXkobXNnSGFzaDogSGV4KTogdHlwZW9mIFBvaW50LkJBU0Uge1xuICAgICAgY29uc3QgeyByLCBzLCByZWNvdmVyeTogcmVjIH0gPSB0aGlzO1xuICAgICAgY29uc3QgaCA9IGJpdHMyaW50X21vZE4oZW5zdXJlQnl0ZXMoJ21zZ0hhc2gnLCBtc2dIYXNoKSk7IC8vIFRydW5jYXRlIGhhc2hcbiAgICAgIGlmIChyZWMgPT0gbnVsbCB8fCAhWzAsIDEsIDIsIDNdLmluY2x1ZGVzKHJlYykpIHRocm93IG5ldyBFcnJvcigncmVjb3ZlcnkgaWQgaW52YWxpZCcpO1xuICAgICAgY29uc3QgcmFkaiA9IHJlYyA9PT0gMiB8fCByZWMgPT09IDMgPyByICsgQ1VSVkUubiA6IHI7XG4gICAgICBpZiAocmFkaiA+PSBGcC5PUkRFUikgdGhyb3cgbmV3IEVycm9yKCdyZWNvdmVyeSBpZCAyIG9yIDMgaW52YWxpZCcpO1xuICAgICAgY29uc3QgcHJlZml4ID0gKHJlYyAmIDEpID09PSAwID8gJzAyJyA6ICcwMyc7XG4gICAgICBjb25zdCBSID0gUG9pbnQuZnJvbUhleChwcmVmaXggKyBudW1Ub05CeXRlU3RyKHJhZGopKTtcbiAgICAgIGNvbnN0IGlyID0gaW52TihyYWRqKTsgLy8gcl4tMVxuICAgICAgY29uc3QgdTEgPSBtb2ROKC1oICogaXIpOyAvLyAtaHJeLTFcbiAgICAgIGNvbnN0IHUyID0gbW9kTihzICogaXIpOyAvLyBzcl4tMVxuICAgICAgY29uc3QgUSA9IFBvaW50LkJBU0UubXVsdGlwbHlBbmRBZGRVbnNhZmUoUiwgdTEsIHUyKTsgLy8gKHNyXi0xKVItKGhyXi0xKUcgPSAtKGhyXi0xKUcgKyAoc3JeLTEpXG4gICAgICBpZiAoIVEpIHRocm93IG5ldyBFcnJvcigncG9pbnQgYXQgaW5maW5pZnknKTsgLy8gdW5zYWZlIGlzIGZpbmU6IG5vIHByaXYgZGF0YSBsZWFrZWRcbiAgICAgIFEuYXNzZXJ0VmFsaWRpdHkoKTtcbiAgICAgIHJldHVybiBRO1xuICAgIH1cblxuICAgIC8vIFNpZ25hdHVyZXMgc2hvdWxkIGJlIGxvdy1zLCB0byBwcmV2ZW50IG1hbGxlYWJpbGl0eS5cbiAgICBoYXNIaWdoUygpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiBpc0JpZ2dlclRoYW5IYWxmT3JkZXIodGhpcy5zKTtcbiAgICB9XG5cbiAgICBub3JtYWxpemVTKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzSGlnaFMoKSA/IG5ldyBTaWduYXR1cmUodGhpcy5yLCBtb2ROKC10aGlzLnMpLCB0aGlzLnJlY292ZXJ5KSA6IHRoaXM7XG4gICAgfVxuXG4gICAgLy8gREVSLWVuY29kZWRcbiAgICB0b0RFUlJhd0J5dGVzKCkge1xuICAgICAgcmV0dXJuIHV0LmhleFRvQnl0ZXModGhpcy50b0RFUkhleCgpKTtcbiAgICB9XG4gICAgdG9ERVJIZXgoKSB7XG4gICAgICByZXR1cm4gREVSLmhleEZyb21TaWcoeyByOiB0aGlzLnIsIHM6IHRoaXMucyB9KTtcbiAgICB9XG5cbiAgICAvLyBwYWRkZWQgYnl0ZXMgb2YgciwgdGhlbiBwYWRkZWQgYnl0ZXMgb2Ygc1xuICAgIHRvQ29tcGFjdFJhd0J5dGVzKCkge1xuICAgICAgcmV0dXJuIHV0LmhleFRvQnl0ZXModGhpcy50b0NvbXBhY3RIZXgoKSk7XG4gICAgfVxuICAgIHRvQ29tcGFjdEhleCgpIHtcbiAgICAgIHJldHVybiBudW1Ub05CeXRlU3RyKHRoaXMucikgKyBudW1Ub05CeXRlU3RyKHRoaXMucyk7XG4gICAgfVxuICB9XG4gIHR5cGUgUmVjb3ZlcmVkU2lnbmF0dXJlID0gU2lnbmF0dXJlICYgeyByZWNvdmVyeTogbnVtYmVyIH07XG5cbiAgY29uc3QgdXRpbHMgPSB7XG4gICAgaXNWYWxpZFByaXZhdGVLZXkocHJpdmF0ZUtleTogUHJpdktleSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbm9ybVByaXZhdGVLZXlUb1NjYWxhcihwcml2YXRlS2V5KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSxcbiAgICBub3JtUHJpdmF0ZUtleVRvU2NhbGFyOiBub3JtUHJpdmF0ZUtleVRvU2NhbGFyLFxuXG4gICAgLyoqXG4gICAgICogUHJvZHVjZXMgY3J5cHRvZ3JhcGhpY2FsbHkgc2VjdXJlIHByaXZhdGUga2V5IGZyb20gcmFuZG9tIG9mIHNpemUgKG5CaXRMZW5ndGgrNjQpXG4gICAgICogYXMgcGVyIEZJUFMgMTg2IEIuNC4xIHdpdGggbW9kdWxvIGJpYXMgYmVpbmcgbmVnbGlibGUuXG4gICAgICovXG4gICAgcmFuZG9tUHJpdmF0ZUtleTogKCk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgY29uc3QgcmFuZCA9IENVUlZFLnJhbmRvbUJ5dGVzKEZwLkJZVEVTICsgOCk7XG4gICAgICBjb25zdCBudW0gPSBtb2QuaGFzaFRvUHJpdmF0ZVNjYWxhcihyYW5kLCBDVVJWRV9PUkRFUik7XG4gICAgICByZXR1cm4gdXQubnVtYmVyVG9CeXRlc0JFKG51bSwgQ1VSVkUubkJ5dGVMZW5ndGgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHByZWNvbXB1dGUgdGFibGUgZm9yIGFuIGFyYml0cmFyeSBFQyBwb2ludC4gTWFrZXMgcG9pbnQgXCJjYWNoZWRcIi5cbiAgICAgKiBBbGxvd3MgdG8gbWFzc2l2ZWx5IHNwZWVkLXVwIGBwb2ludC5tdWx0aXBseShzY2FsYXIpYC5cbiAgICAgKiBAcmV0dXJucyBjYWNoZWQgcG9pbnRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZhc3QgPSB1dGlscy5wcmVjb21wdXRlKDgsIFByb2plY3RpdmVQb2ludC5mcm9tSGV4KHNvbWVvbmVzUHViS2V5KSk7XG4gICAgICogZmFzdC5tdWx0aXBseShwcml2S2V5KTsgLy8gbXVjaCBmYXN0ZXIgRUNESCBub3dcbiAgICAgKi9cbiAgICBwcmVjb21wdXRlKHdpbmRvd1NpemUgPSA4LCBwb2ludCA9IFBvaW50LkJBU0UpOiB0eXBlb2YgUG9pbnQuQkFTRSB7XG4gICAgICBwb2ludC5fc2V0V2luZG93U2l6ZSh3aW5kb3dTaXplKTtcbiAgICAgIHBvaW50Lm11bHRpcGx5KEJpZ0ludCgzKSk7IC8vIDMgaXMgYXJiaXRyYXJ5LCBqdXN0IG5lZWQgYW55IG51bWJlciBoZXJlXG4gICAgICByZXR1cm4gcG9pbnQ7XG4gICAgfSxcbiAgfTtcblxuICAvKipcbiAgICogQ29tcHV0ZXMgcHVibGljIGtleSBmb3IgYSBwcml2YXRlIGtleS4gQ2hlY2tzIGZvciB2YWxpZGl0eSBvZiB0aGUgcHJpdmF0ZSBrZXkuXG4gICAqIEBwYXJhbSBwcml2YXRlS2V5IHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSBpc0NvbXByZXNzZWQgd2hldGhlciB0byByZXR1cm4gY29tcGFjdCAoZGVmYXVsdCksIG9yIGZ1bGwga2V5XG4gICAqIEByZXR1cm5zIFB1YmxpYyBrZXksIGZ1bGwgd2hlbiBpc0NvbXByZXNzZWQ9ZmFsc2U7IHNob3J0IHdoZW4gaXNDb21wcmVzc2VkPXRydWVcbiAgICovXG4gIGZ1bmN0aW9uIGdldFB1YmxpY0tleShwcml2YXRlS2V5OiBQcml2S2V5LCBpc0NvbXByZXNzZWQgPSB0cnVlKTogVWludDhBcnJheSB7XG4gICAgcmV0dXJuIFBvaW50LmZyb21Qcml2YXRlS2V5KHByaXZhdGVLZXkpLnRvUmF3Qnl0ZXMoaXNDb21wcmVzc2VkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWljayBhbmQgZGlydHkgY2hlY2sgZm9yIGl0ZW0gYmVpbmcgcHVibGljIGtleS4gRG9lcyBub3QgdmFsaWRhdGUgaGV4LCBvciBiZWluZyBvbi1jdXJ2ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGlzUHJvYlB1YihpdGVtOiBQcml2S2V5IHwgUHViS2V5KTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gaXRlbSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk7XG4gICAgY29uc3Qgc3RyID0gdHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnO1xuICAgIGNvbnN0IGxlbiA9IChhcnIgfHwgc3RyKSAmJiAoaXRlbSBhcyBIZXgpLmxlbmd0aDtcbiAgICBpZiAoYXJyKSByZXR1cm4gbGVuID09PSBjb21wcmVzc2VkTGVuIHx8IGxlbiA9PT0gdW5jb21wcmVzc2VkTGVuO1xuICAgIGlmIChzdHIpIHJldHVybiBsZW4gPT09IDIgKiBjb21wcmVzc2VkTGVuIHx8IGxlbiA9PT0gMiAqIHVuY29tcHJlc3NlZExlbjtcbiAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFBvaW50KSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogRUNESCAoRWxsaXB0aWMgQ3VydmUgRGlmZmllIEhlbGxtYW4pLlxuICAgKiBDb21wdXRlcyBzaGFyZWQgcHVibGljIGtleSBmcm9tIHByaXZhdGUga2V5IGFuZCBwdWJsaWMga2V5LlxuICAgKiBDaGVja3M6IDEpIHByaXZhdGUga2V5IHZhbGlkaXR5IDIpIHNoYXJlZCBrZXkgaXMgb24tY3VydmUuXG4gICAqIERvZXMgTk9UIGhhc2ggdGhlIHJlc3VsdC5cbiAgICogQHBhcmFtIHByaXZhdGVBIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSBwdWJsaWNCIGRpZmZlcmVudCBwdWJsaWMga2V5XG4gICAqIEBwYXJhbSBpc0NvbXByZXNzZWQgd2hldGhlciB0byByZXR1cm4gY29tcGFjdCAoZGVmYXVsdCksIG9yIGZ1bGwga2V5XG4gICAqIEByZXR1cm5zIHNoYXJlZCBwdWJsaWMga2V5XG4gICAqL1xuICBmdW5jdGlvbiBnZXRTaGFyZWRTZWNyZXQocHJpdmF0ZUE6IFByaXZLZXksIHB1YmxpY0I6IEhleCwgaXNDb21wcmVzc2VkID0gdHJ1ZSk6IFVpbnQ4QXJyYXkge1xuICAgIGlmIChpc1Byb2JQdWIocHJpdmF0ZUEpKSB0aHJvdyBuZXcgRXJyb3IoJ2ZpcnN0IGFyZyBtdXN0IGJlIHByaXZhdGUga2V5Jyk7XG4gICAgaWYgKCFpc1Byb2JQdWIocHVibGljQikpIHRocm93IG5ldyBFcnJvcignc2Vjb25kIGFyZyBtdXN0IGJlIHB1YmxpYyBrZXknKTtcbiAgICBjb25zdCBiID0gUG9pbnQuZnJvbUhleChwdWJsaWNCKTsgLy8gY2hlY2sgZm9yIGJlaW5nIG9uLWN1cnZlXG4gICAgcmV0dXJuIGIubXVsdGlwbHkobm9ybVByaXZhdGVLZXlUb1NjYWxhcihwcml2YXRlQSkpLnRvUmF3Qnl0ZXMoaXNDb21wcmVzc2VkKTtcbiAgfVxuXG4gIC8vIFJGQzY5Nzk6IGVuc3VyZSBFQ0RTQSBtc2cgaXMgWCBieXRlcyBhbmQgPCBOLiBSRkMgc3VnZ2VzdHMgb3B0aW9uYWwgdHJ1bmNhdGluZyB2aWEgYml0czJvY3RldHMuXG4gIC8vIEZJUFMgMTg2LTQgNC42IHN1Z2dlc3RzIHRoZSBsZWZ0bW9zdCBtaW4obkJpdExlbiwgb3V0TGVuKSBiaXRzLCB3aGljaCBtYXRjaGVzIGJpdHMyaW50LlxuICAvLyBiaXRzMmludCBjYW4gcHJvZHVjZSByZXM+Tiwgd2UgY2FuIGRvIG1vZChyZXMsIE4pIHNpbmNlIHRoZSBiaXRMZW4gaXMgdGhlIHNhbWUuXG4gIC8vIGludDJvY3RldHMgY2FuJ3QgYmUgdXNlZDsgcGFkcyBzbWFsbCBtc2dzIHdpdGggMDogdW5hY2NlcHRhdGJsZSBmb3IgdHJ1bmMgYXMgcGVyIFJGQyB2ZWN0b3JzXG4gIGNvbnN0IGJpdHMyaW50ID1cbiAgICBDVVJWRS5iaXRzMmludCB8fFxuICAgIGZ1bmN0aW9uIChieXRlczogVWludDhBcnJheSk6IGJpZ2ludCB7XG4gICAgICAvLyBGb3IgY3VydmVzIHdpdGggbkJpdExlbmd0aCAlIDggIT09IDA6IGJpdHMyb2N0ZXRzKGJpdHMyb2N0ZXRzKG0pKSAhPT0gYml0czJvY3RldHMobSlcbiAgICAgIC8vIGZvciBzb21lIGNhc2VzLCBzaW5jZSBieXRlcy5sZW5ndGggKiA4IGlzIG5vdCBhY3R1YWwgYml0TGVuZ3RoLlxuICAgICAgY29uc3QgbnVtID0gdXQuYnl0ZXNUb051bWJlckJFKGJ5dGVzKTsgLy8gY2hlY2sgZm9yID09IHU4IGRvbmUgaGVyZVxuICAgICAgY29uc3QgZGVsdGEgPSBieXRlcy5sZW5ndGggKiA4IC0gQ1VSVkUubkJpdExlbmd0aDsgLy8gdHJ1bmNhdGUgdG8gbkJpdExlbmd0aCBsZWZ0bW9zdCBiaXRzXG4gICAgICByZXR1cm4gZGVsdGEgPiAwID8gbnVtID4+IEJpZ0ludChkZWx0YSkgOiBudW07XG4gICAgfTtcbiAgY29uc3QgYml0czJpbnRfbW9kTiA9XG4gICAgQ1VSVkUuYml0czJpbnRfbW9kTiB8fFxuICAgIGZ1bmN0aW9uIChieXRlczogVWludDhBcnJheSk6IGJpZ2ludCB7XG4gICAgICByZXR1cm4gbW9kTihiaXRzMmludChieXRlcykpOyAvLyBjYW4ndCB1c2UgYnl0ZXNUb051bWJlckJFIGhlcmVcbiAgICB9O1xuICAvLyBOT1RFOiBwYWRzIG91dHB1dCB3aXRoIHplcm8gYXMgcGVyIHNwZWNcbiAgY29uc3QgT1JERVJfTUFTSyA9IHV0LmJpdE1hc2soQ1VSVkUubkJpdExlbmd0aCk7XG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0byBieXRlcy4gQ2hlY2tzIGlmIG51bSBpbiBgWzAuLk9SREVSX01BU0stMV1gIGUuZy46IGBbMC4uMl4yNTYtMV1gLlxuICAgKi9cbiAgZnVuY3Rpb24gaW50Mm9jdGV0cyhudW06IGJpZ2ludCk6IFVpbnQ4QXJyYXkge1xuICAgIGlmICh0eXBlb2YgbnVtICE9PSAnYmlnaW50JykgdGhyb3cgbmV3IEVycm9yKCdiaWdpbnQgZXhwZWN0ZWQnKTtcbiAgICBpZiAoIShfMG4gPD0gbnVtICYmIG51bSA8IE9SREVSX01BU0spKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBiaWdpbnQgZXhwZWN0ZWQgPCAyXiR7Q1VSVkUubkJpdExlbmd0aH1gKTtcbiAgICAvLyB3b3JrcyB3aXRoIG9yZGVyLCBjYW4gaGF2ZSBkaWZmZXJlbnQgc2l6ZSB0aGFuIG51bVRvRmllbGQhXG4gICAgcmV0dXJuIHV0Lm51bWJlclRvQnl0ZXNCRShudW0sIENVUlZFLm5CeXRlTGVuZ3RoKTtcbiAgfVxuXG4gIC8vIFN0ZXBzIEEsIEQgb2YgUkZDNjk3OSAzLjJcbiAgLy8gQ3JlYXRlcyBSRkM2OTc5IHNlZWQ7IGNvbnZlcnRzIG1zZy9wcml2S2V5IHRvIG51bWJlcnMuXG4gIC8vIFVzZWQgb25seSBpbiBzaWduLCBub3QgaW4gdmVyaWZ5LlxuICAvLyBOT1RFOiB3ZSBjYW5ub3QgYXNzdW1lIGhlcmUgdGhhdCBtc2dIYXNoIGhhcyBzYW1lIGFtb3VudCBvZiBieXRlcyBhcyBjdXJ2ZSBvcmRlciwgdGhpcyB3aWxsIGJlIHdyb25nIGF0IGxlYXN0IGZvciBQNTIxLlxuICAvLyBBbHNvIGl0IGNhbiBiZSBiaWdnZXIgZm9yIFAyMjQgKyBTSEEyNTZcbiAgZnVuY3Rpb24gcHJlcFNpZyhtc2dIYXNoOiBIZXgsIHByaXZhdGVLZXk6IFByaXZLZXksIG9wdHMgPSBkZWZhdWx0U2lnT3B0cykge1xuICAgIGlmIChbJ3JlY292ZXJlZCcsICdjYW5vbmljYWwnXS5zb21lKChrKSA9PiBrIGluIG9wdHMpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaWduKCkgbGVnYWN5IG9wdGlvbnMgbm90IHN1cHBvcnRlZCcpO1xuICAgIGNvbnN0IHsgaGFzaCwgcmFuZG9tQnl0ZXMgfSA9IENVUlZFO1xuICAgIGxldCB7IGxvd1MsIHByZWhhc2gsIGV4dHJhRW50cm9weTogZW50IH0gPSBvcHRzOyAvLyBnZW5lcmF0ZXMgbG93LXMgc2lncyBieSBkZWZhdWx0XG4gICAgaWYgKGxvd1MgPT0gbnVsbCkgbG93UyA9IHRydWU7IC8vIFJGQzY5NzkgMy4yOiB3ZSBza2lwIHN0ZXAgQSwgYmVjYXVzZSB3ZSBhbHJlYWR5IHByb3ZpZGUgaGFzaFxuICAgIG1zZ0hhc2ggPSBlbnN1cmVCeXRlcygnbXNnSGFzaCcsIG1zZ0hhc2gpO1xuICAgIGlmIChwcmVoYXNoKSBtc2dIYXNoID0gZW5zdXJlQnl0ZXMoJ3ByZWhhc2hlZCBtc2dIYXNoJywgaGFzaChtc2dIYXNoKSk7XG5cbiAgICAvLyBXZSBjYW4ndCBsYXRlciBjYWxsIGJpdHMyb2N0ZXRzLCBzaW5jZSBuZXN0ZWQgYml0czJpbnQgaXMgYnJva2VuIGZvciBjdXJ2ZXNcbiAgICAvLyB3aXRoIG5CaXRMZW5ndGggJSA4ICE9PSAwLiBCZWNhdXNlIG9mIHRoYXQsIHdlIHVud3JhcCBpdCBoZXJlIGFzIGludDJvY3RldHMgY2FsbC5cbiAgICAvLyBjb25zdCBiaXRzMm9jdGV0cyA9IChiaXRzKSA9PiBpbnQyb2N0ZXRzKGJpdHMyaW50X21vZE4oYml0cykpXG4gICAgY29uc3QgaDFpbnQgPSBiaXRzMmludF9tb2ROKG1zZ0hhc2gpO1xuICAgIGNvbnN0IGQgPSBub3JtUHJpdmF0ZUtleVRvU2NhbGFyKHByaXZhdGVLZXkpOyAvLyB2YWxpZGF0ZSBwcml2YXRlIGtleSwgY29udmVydCB0byBiaWdpbnRcbiAgICBjb25zdCBzZWVkQXJncyA9IFtpbnQyb2N0ZXRzKGQpLCBpbnQyb2N0ZXRzKGgxaW50KV07XG4gICAgLy8gZXh0cmFFbnRyb3B5LiBSRkM2OTc5IDMuNjogYWRkaXRpb25hbCBrJyAob3B0aW9uYWwpLlxuICAgIGlmIChlbnQgIT0gbnVsbCkge1xuICAgICAgLy8gSyA9IEhNQUNfSyhWIHx8IDB4MDAgfHwgaW50Mm9jdGV0cyh4KSB8fCBiaXRzMm9jdGV0cyhoMSkgfHwgaycpXG4gICAgICBjb25zdCBlID0gZW50ID09PSB0cnVlID8gcmFuZG9tQnl0ZXMoRnAuQllURVMpIDogZW50OyAvLyBnZW5lcmF0ZSByYW5kb20gYnl0ZXMgT1IgcGFzcyBhcy1pc1xuICAgICAgc2VlZEFyZ3MucHVzaChlbnN1cmVCeXRlcygnZXh0cmFFbnRyb3B5JywgZSwgRnAuQllURVMpKTsgLy8gY2hlY2sgZm9yIGJlaW5nIG9mIHNpemUgQllURVNcbiAgICB9XG4gICAgY29uc3Qgc2VlZCA9IHV0LmNvbmNhdEJ5dGVzKC4uLnNlZWRBcmdzKTsgLy8gU3RlcCBEIG9mIFJGQzY5NzkgMy4yXG4gICAgY29uc3QgbSA9IGgxaW50OyAvLyBOT1RFOiBubyBuZWVkIHRvIGNhbGwgYml0czJpbnQgc2Vjb25kIHRpbWUgaGVyZSwgaXQgaXMgaW5zaWRlIHRydW5jYXRlSGFzaCFcbiAgICAvLyBDb252ZXJ0cyBzaWduYXR1cmUgcGFyYW1zIGludG8gcG9pbnQgdyByL3MsIGNoZWNrcyByZXN1bHQgZm9yIHZhbGlkaXR5LlxuICAgIGZ1bmN0aW9uIGsyc2lnKGtCeXRlczogVWludDhBcnJheSk6IFJlY292ZXJlZFNpZ25hdHVyZSB8IHVuZGVmaW5lZCB7XG4gICAgICAvLyBSRkMgNjk3OSBTZWN0aW9uIDMuMiwgc3RlcCAzOiBrID0gYml0czJpbnQoVClcbiAgICAgIGNvbnN0IGsgPSBiaXRzMmludChrQnl0ZXMpOyAvLyBDYW5ub3QgdXNlIGZpZWxkcyBtZXRob2RzLCBzaW5jZSBpdCBpcyBncm91cCBlbGVtZW50XG4gICAgICBpZiAoIWlzV2l0aGluQ3VydmVPcmRlcihrKSkgcmV0dXJuOyAvLyBJbXBvcnRhbnQ6IGFsbCBtb2QoKSBjYWxscyBoZXJlIG11c3QgYmUgZG9uZSBvdmVyIE5cbiAgICAgIGNvbnN0IGlrID0gaW52TihrKTsgLy8ga14tMSBtb2QgblxuICAgICAgY29uc3QgcSA9IFBvaW50LkJBU0UubXVsdGlwbHkoaykudG9BZmZpbmUoKTsgLy8gcSA9IEdrXG4gICAgICBjb25zdCByID0gbW9kTihxLngpOyAvLyByID0gcS54IG1vZCBuXG4gICAgICBpZiAociA9PT0gXzBuKSByZXR1cm47XG4gICAgICAvLyBDYW4gdXNlIHNjYWxhciBibGluZGluZyBiXi0xKGJtICsgYmRyKSB3aGVyZSBiIOKIiCBbMSxx4oiSMV0gYWNjb3JkaW5nIHRvXG4gICAgICAvLyBodHRwczovL3RjaGVzLmlhY3Iub3JnL2luZGV4LnBocC9UQ0hFUy9hcnRpY2xlL3ZpZXcvNzMzNy82NTA5LiBXZSd2ZSBkZWNpZGVkIGFnYWluc3QgaXQ6XG4gICAgICAvLyBhKSBkZXBlbmRlbmN5IG9uIENTUFJORyBiKSAxNSUgc2xvd2Rvd24gYykgZG9lc24ndCByZWFsbHkgaGVscCBzaW5jZSBiaWdpbnRzIGFyZSBub3QgQ1RcbiAgICAgIGNvbnN0IHMgPSBtb2ROKGlrICogbW9kTihtICsgciAqIGQpKTsgLy8gTm90IHVzaW5nIGJsaW5kaW5nIGhlcmVcbiAgICAgIGlmIChzID09PSBfMG4pIHJldHVybjtcbiAgICAgIGxldCByZWNvdmVyeSA9IChxLnggPT09IHIgPyAwIDogMikgfCBOdW1iZXIocS55ICYgXzFuKTsgLy8gcmVjb3ZlcnkgYml0ICgyIG9yIDMsIHdoZW4gcS54ID4gbilcbiAgICAgIGxldCBub3JtUyA9IHM7XG4gICAgICBpZiAobG93UyAmJiBpc0JpZ2dlclRoYW5IYWxmT3JkZXIocykpIHtcbiAgICAgICAgbm9ybVMgPSBub3JtYWxpemVTKHMpOyAvLyBpZiBsb3dTIHdhcyBwYXNzZWQsIGVuc3VyZSBzIGlzIGFsd2F5c1xuICAgICAgICByZWNvdmVyeSBePSAxOyAvLyAvLyBpbiB0aGUgYm90dG9tIGhhbGYgb2YgTlxuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBTaWduYXR1cmUociwgbm9ybVMsIHJlY292ZXJ5KSBhcyBSZWNvdmVyZWRTaWduYXR1cmU7IC8vIHVzZSBub3JtUywgbm90IHNcbiAgICB9XG4gICAgcmV0dXJuIHsgc2VlZCwgazJzaWcgfTtcbiAgfVxuICBjb25zdCBkZWZhdWx0U2lnT3B0czogU2lnbk9wdHMgPSB7IGxvd1M6IENVUlZFLmxvd1MsIHByZWhhc2g6IGZhbHNlIH07XG4gIGNvbnN0IGRlZmF1bHRWZXJPcHRzOiBWZXJPcHRzID0geyBsb3dTOiBDVVJWRS5sb3dTLCBwcmVoYXNoOiBmYWxzZSB9O1xuXG4gIC8qKlxuICAgKiBTaWducyBtZXNzYWdlIGhhc2ggd2l0aCBhIHByaXZhdGUga2V5LlxuICAgKiBgYGBcbiAgICogc2lnbihtLCBkLCBrKSB3aGVyZVxuICAgKiAgICh4LCB5KSA9IEcgw5cga1xuICAgKiAgIHIgPSB4IG1vZCBuXG4gICAqICAgcyA9IChtICsgZHIpL2sgbW9kIG5cbiAgICogYGBgXG4gICAqIEBwYXJhbSBtc2dIYXNoIE5PVCBtZXNzYWdlLiBtc2cgbmVlZHMgdG8gYmUgaGFzaGVkIHRvIGBtc2dIYXNoYCwgb3IgdXNlIGBwcmVoYXNoYC5cbiAgICogQHBhcmFtIHByaXZLZXkgcHJpdmF0ZSBrZXlcbiAgICogQHBhcmFtIG9wdHMgbG93UyBmb3Igbm9uLW1hbGxlYWJsZSBzaWdzLiBleHRyYUVudHJvcHkgZm9yIG1peGluZyByYW5kb21uZXNzIGludG8gay4gcHJlaGFzaCB3aWxsIGhhc2ggZmlyc3QgYXJnLlxuICAgKiBAcmV0dXJucyBzaWduYXR1cmUgd2l0aCByZWNvdmVyeSBwYXJhbVxuICAgKi9cbiAgZnVuY3Rpb24gc2lnbihtc2dIYXNoOiBIZXgsIHByaXZLZXk6IFByaXZLZXksIG9wdHMgPSBkZWZhdWx0U2lnT3B0cyk6IFJlY292ZXJlZFNpZ25hdHVyZSB7XG4gICAgY29uc3QgeyBzZWVkLCBrMnNpZyB9ID0gcHJlcFNpZyhtc2dIYXNoLCBwcml2S2V5LCBvcHRzKTsgLy8gU3RlcHMgQSwgRCBvZiBSRkM2OTc5IDMuMi5cbiAgICBjb25zdCBDID0gQ1VSVkU7XG4gICAgY29uc3QgZHJiZyA9IHV0LmNyZWF0ZUhtYWNEcmJnPFJlY292ZXJlZFNpZ25hdHVyZT4oQy5oYXNoLm91dHB1dExlbiwgQy5uQnl0ZUxlbmd0aCwgQy5obWFjKTtcbiAgICByZXR1cm4gZHJiZyhzZWVkLCBrMnNpZyk7IC8vIFN0ZXBzIEIsIEMsIEQsIEUsIEYsIEdcbiAgfVxuXG4gIC8vIEVuYWJsZSBwcmVjb21wdXRlcy4gU2xvd3MgZG93biBmaXJzdCBwdWJsaWNLZXkgY29tcHV0YXRpb24gYnkgMjBtcy5cbiAgUG9pbnQuQkFTRS5fc2V0V2luZG93U2l6ZSg4KTtcbiAgLy8gdXRpbHMucHJlY29tcHV0ZSg4LCBQcm9qZWN0aXZlUG9pbnQuQkFTRSlcblxuICAvKipcbiAgICogVmVyaWZpZXMgYSBzaWduYXR1cmUgYWdhaW5zdCBtZXNzYWdlIGhhc2ggYW5kIHB1YmxpYyBrZXkuXG4gICAqIFJlamVjdHMgbG93UyBzaWduYXR1cmVzIGJ5IGRlZmF1bHQ6IHRvIG92ZXJyaWRlLFxuICAgKiBzcGVjaWZ5IG9wdGlvbiBge2xvd1M6IGZhbHNlfWAuIEltcGxlbWVudHMgc2VjdGlvbiA0LjEuNCBmcm9tIGh0dHBzOi8vd3d3LnNlY2cub3JnL3NlYzEtdjIucGRmOlxuICAgKlxuICAgKiBgYGBcbiAgICogdmVyaWZ5KHIsIHMsIGgsIFApIHdoZXJlXG4gICAqICAgVTEgPSBoc14tMSBtb2QgblxuICAgKiAgIFUyID0gcnNeLTEgbW9kIG5cbiAgICogICBSID0gVTHii4VHIC0gVTLii4VQXG4gICAqICAgbW9kKFIueCwgbikgPT0gclxuICAgKiBgYGBcbiAgICovXG4gIGZ1bmN0aW9uIHZlcmlmeShcbiAgICBzaWduYXR1cmU6IEhleCB8IFNpZ25hdHVyZUxpa2UsXG4gICAgbXNnSGFzaDogSGV4LFxuICAgIHB1YmxpY0tleTogSGV4LFxuICAgIG9wdHMgPSBkZWZhdWx0VmVyT3B0c1xuICApOiBib29sZWFuIHtcbiAgICBjb25zdCBzZyA9IHNpZ25hdHVyZTtcbiAgICBtc2dIYXNoID0gZW5zdXJlQnl0ZXMoJ21zZ0hhc2gnLCBtc2dIYXNoKTtcbiAgICBwdWJsaWNLZXkgPSBlbnN1cmVCeXRlcygncHVibGljS2V5JywgcHVibGljS2V5KTtcbiAgICBpZiAoJ3N0cmljdCcgaW4gb3B0cykgdGhyb3cgbmV3IEVycm9yKCdvcHRpb25zLnN0cmljdCB3YXMgcmVuYW1lZCB0byBsb3dTJyk7XG4gICAgY29uc3QgeyBsb3dTLCBwcmVoYXNoIH0gPSBvcHRzO1xuXG4gICAgbGV0IF9zaWc6IFNpZ25hdHVyZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgUDogUHJvalBvaW50VHlwZTxiaWdpbnQ+O1xuICAgIHRyeSB7XG4gICAgICBpZiAodHlwZW9mIHNnID09PSAnc3RyaW5nJyB8fCBzZyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgLy8gU2lnbmF0dXJlIGNhbiBiZSByZXByZXNlbnRlZCBpbiAyIHdheXM6IGNvbXBhY3QgKDIqbkJ5dGVMZW5ndGgpICYgREVSICh2YXJpYWJsZS1sZW5ndGgpLlxuICAgICAgICAvLyBTaW5jZSBERVIgY2FuIGFsc28gYmUgMipuQnl0ZUxlbmd0aCBieXRlcywgd2UgY2hlY2sgZm9yIGl0IGZpcnN0LlxuICAgICAgICB0cnkge1xuICAgICAgICAgIF9zaWcgPSBTaWduYXR1cmUuZnJvbURFUihzZyk7XG4gICAgICAgIH0gY2F0Y2ggKGRlckVycm9yKSB7XG4gICAgICAgICAgaWYgKCEoZGVyRXJyb3IgaW5zdGFuY2VvZiBERVIuRXJyKSkgdGhyb3cgZGVyRXJyb3I7XG4gICAgICAgICAgX3NpZyA9IFNpZ25hdHVyZS5mcm9tQ29tcGFjdChzZyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHNnID09PSAnb2JqZWN0JyAmJiB0eXBlb2Ygc2cuciA9PT0gJ2JpZ2ludCcgJiYgdHlwZW9mIHNnLnMgPT09ICdiaWdpbnQnKSB7XG4gICAgICAgIGNvbnN0IHsgciwgcyB9ID0gc2c7XG4gICAgICAgIF9zaWcgPSBuZXcgU2lnbmF0dXJlKHIsIHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQQVJTRScpO1xuICAgICAgfVxuICAgICAgUCA9IFBvaW50LmZyb21IZXgocHVibGljS2V5KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKChlcnJvciBhcyBFcnJvcikubWVzc2FnZSA9PT0gJ1BBUlNFJylcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBzaWduYXR1cmUgbXVzdCBiZSBTaWduYXR1cmUgaW5zdGFuY2UsIFVpbnQ4QXJyYXkgb3IgaGV4IHN0cmluZ2ApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAobG93UyAmJiBfc2lnLmhhc0hpZ2hTKCkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAocHJlaGFzaCkgbXNnSGFzaCA9IENVUlZFLmhhc2gobXNnSGFzaCk7XG4gICAgY29uc3QgeyByLCBzIH0gPSBfc2lnO1xuICAgIGNvbnN0IGggPSBiaXRzMmludF9tb2ROKG1zZ0hhc2gpOyAvLyBDYW5ub3QgdXNlIGZpZWxkcyBtZXRob2RzLCBzaW5jZSBpdCBpcyBncm91cCBlbGVtZW50XG4gICAgY29uc3QgaXMgPSBpbnZOKHMpOyAvLyBzXi0xXG4gICAgY29uc3QgdTEgPSBtb2ROKGggKiBpcyk7IC8vIHUxID0gaHNeLTEgbW9kIG5cbiAgICBjb25zdCB1MiA9IG1vZE4ociAqIGlzKTsgLy8gdTIgPSByc14tMSBtb2QgblxuICAgIGNvbnN0IFIgPSBQb2ludC5CQVNFLm11bHRpcGx5QW5kQWRkVW5zYWZlKFAsIHUxLCB1Mik/LnRvQWZmaW5lKCk7IC8vIFIgPSB1MeKLhUcgKyB1MuKLhVBcbiAgICBpZiAoIVIpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCB2ID0gbW9kTihSLngpO1xuICAgIHJldHVybiB2ID09PSByO1xuICB9XG4gIHJldHVybiB7XG4gICAgQ1VSVkUsXG4gICAgZ2V0UHVibGljS2V5LFxuICAgIGdldFNoYXJlZFNlY3JldCxcbiAgICBzaWduLFxuICAgIHZlcmlmeSxcbiAgICBQcm9qZWN0aXZlUG9pbnQ6IFBvaW50LFxuICAgIFNpZ25hdHVyZSxcbiAgICB1dGlscyxcbiAgfTtcbn1cblxuLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2hhbGx1ZSBhbmQgdmFuIGRlIFdvZXN0aWpuZSBtZXRob2QgZm9yIGFueSB3ZWllcnN0cmFzcyBjdXJ2ZS5cbiAqIFRPRE86IGNoZWNrIGlmIHRoZXJlIGlzIGEgd2F5IHRvIG1lcmdlIHRoaXMgd2l0aCB1dlJhdGlvIGluIEVkd2FyZHM7IG1vdmUgdG8gbW9kdWxhci5cbiAqIGIgPSBUcnVlIGFuZCB5ID0gc3FydCh1IC8gdikgaWYgKHUgLyB2KSBpcyBzcXVhcmUgaW4gRiwgYW5kXG4gKiBiID0gRmFsc2UgYW5kIHkgPSBzcXJ0KFogKiAodSAvIHYpKSBvdGhlcndpc2UuXG4gKiBAcGFyYW0gRnBcbiAqIEBwYXJhbSBaXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gU1dVRnBTcXJ0UmF0aW88VD4oRnA6IG1vZC5JRmllbGQ8VD4sIFo6IFQpIHtcbiAgLy8gR2VuZXJpYyBpbXBsZW1lbnRhdGlvblxuICBjb25zdCBxID0gRnAuT1JERVI7XG4gIGxldCBsID0gXzBuO1xuICBmb3IgKGxldCBvID0gcSAtIF8xbjsgbyAlIF8ybiA9PT0gXzBuOyBvIC89IF8ybikgbCArPSBfMW47XG4gIGNvbnN0IGMxID0gbDsgLy8gMS4gYzEsIHRoZSBsYXJnZXN0IGludGVnZXIgc3VjaCB0aGF0IDJeYzEgZGl2aWRlcyBxIC0gMS5cbiAgLy8gV2UgbmVlZCAybiAqKiBjMSBhbmQgMm4gKiogKGMxLTEpLiBXZSBjYW4ndCB1c2UgKio7IGJ1dCB3ZSBjYW4gdXNlIDw8LlxuICAvLyAybiAqKiBjMSA9PSAybiA8PCAoYzEtMSlcbiAgY29uc3QgXzJuX3Bvd19jMV8xID0gXzJuIDw8IChjMSAtIF8xbiAtIF8xbik7XG4gIGNvbnN0IF8ybl9wb3dfYzEgPSBfMm5fcG93X2MxXzEgKiBfMm47XG4gIGNvbnN0IGMyID0gKHEgLSBfMW4pIC8gXzJuX3Bvd19jMTsgLy8gMi4gYzIgPSAocSAtIDEpIC8gKDJeYzEpICAjIEludGVnZXIgYXJpdGhtZXRpY1xuICBjb25zdCBjMyA9IChjMiAtIF8xbikgLyBfMm47IC8vIDMuIGMzID0gKGMyIC0gMSkgLyAyICAgICAgICAgICAgIyBJbnRlZ2VyIGFyaXRobWV0aWNcbiAgY29uc3QgYzQgPSBfMm5fcG93X2MxIC0gXzFuOyAvLyA0LiBjNCA9IDJeYzEgLSAxICAgICAgICAgICAgICAgICMgSW50ZWdlciBhcml0aG1ldGljXG4gIGNvbnN0IGM1ID0gXzJuX3Bvd19jMV8xOyAvLyA1LiBjNSA9IDJeKGMxIC0gMSkgICAgICAgICAgICAgICAgICAjIEludGVnZXIgYXJpdGhtZXRpY1xuICBjb25zdCBjNiA9IEZwLnBvdyhaLCBjMik7IC8vIDYuIGM2ID0gWl5jMlxuICBjb25zdCBjNyA9IEZwLnBvdyhaLCAoYzIgKyBfMW4pIC8gXzJuKTsgLy8gNy4gYzcgPSBaXigoYzIgKyAxKSAvIDIpXG4gIGxldCBzcXJ0UmF0aW8gPSAodTogVCwgdjogVCk6IHsgaXNWYWxpZDogYm9vbGVhbjsgdmFsdWU6IFQgfSA9PiB7XG4gICAgbGV0IHR2MSA9IGM2OyAvLyAxLiB0djEgPSBjNlxuICAgIGxldCB0djIgPSBGcC5wb3codiwgYzQpOyAvLyAyLiB0djIgPSB2XmM0XG4gICAgbGV0IHR2MyA9IEZwLnNxcih0djIpOyAvLyAzLiB0djMgPSB0djJeMlxuICAgIHR2MyA9IEZwLm11bCh0djMsIHYpOyAvLyA0LiB0djMgPSB0djMgKiB2XG4gICAgbGV0IHR2NSA9IEZwLm11bCh1LCB0djMpOyAvLyA1LiB0djUgPSB1ICogdHYzXG4gICAgdHY1ID0gRnAucG93KHR2NSwgYzMpOyAvLyA2LiB0djUgPSB0djVeYzNcbiAgICB0djUgPSBGcC5tdWwodHY1LCB0djIpOyAvLyA3LiB0djUgPSB0djUgKiB0djJcbiAgICB0djIgPSBGcC5tdWwodHY1LCB2KTsgLy8gOC4gdHYyID0gdHY1ICogdlxuICAgIHR2MyA9IEZwLm11bCh0djUsIHUpOyAvLyA5LiB0djMgPSB0djUgKiB1XG4gICAgbGV0IHR2NCA9IEZwLm11bCh0djMsIHR2Mik7IC8vIDEwLiB0djQgPSB0djMgKiB0djJcbiAgICB0djUgPSBGcC5wb3codHY0LCBjNSk7IC8vIDExLiB0djUgPSB0djReYzVcbiAgICBsZXQgaXNRUiA9IEZwLmVxbCh0djUsIEZwLk9ORSk7IC8vIDEyLiBpc1FSID0gdHY1ID09IDFcbiAgICB0djIgPSBGcC5tdWwodHYzLCBjNyk7IC8vIDEzLiB0djIgPSB0djMgKiBjN1xuICAgIHR2NSA9IEZwLm11bCh0djQsIHR2MSk7IC8vIDE0LiB0djUgPSB0djQgKiB0djFcbiAgICB0djMgPSBGcC5jbW92KHR2MiwgdHYzLCBpc1FSKTsgLy8gMTUuIHR2MyA9IENNT1YodHYyLCB0djMsIGlzUVIpXG4gICAgdHY0ID0gRnAuY21vdih0djUsIHR2NCwgaXNRUik7IC8vIDE2LiB0djQgPSBDTU9WKHR2NSwgdHY0LCBpc1FSKVxuICAgIC8vIDE3LiBmb3IgaSBpbiAoYzEsIGMxIC0gMSwgLi4uLCAyKTpcbiAgICBmb3IgKGxldCBpID0gYzE7IGkgPiBfMW47IGktLSkge1xuICAgICAgbGV0IHR2NSA9IGkgLSBfMm47IC8vIDE4LiAgICB0djUgPSBpIC0gMlxuICAgICAgdHY1ID0gXzJuIDw8ICh0djUgLSBfMW4pOyAvLyAxOS4gICAgdHY1ID0gMl50djVcbiAgICAgIGxldCB0dnY1ID0gRnAucG93KHR2NCwgdHY1KTsgLy8gMjAuICAgIHR2NSA9IHR2NF50djVcbiAgICAgIGNvbnN0IGUxID0gRnAuZXFsKHR2djUsIEZwLk9ORSk7IC8vIDIxLiAgICBlMSA9IHR2NSA9PSAxXG4gICAgICB0djIgPSBGcC5tdWwodHYzLCB0djEpOyAvLyAyMi4gICAgdHYyID0gdHYzICogdHYxXG4gICAgICB0djEgPSBGcC5tdWwodHYxLCB0djEpOyAvLyAyMy4gICAgdHYxID0gdHYxICogdHYxXG4gICAgICB0dnY1ID0gRnAubXVsKHR2NCwgdHYxKTsgLy8gMjQuICAgIHR2NSA9IHR2NCAqIHR2MVxuICAgICAgdHYzID0gRnAuY21vdih0djIsIHR2MywgZTEpOyAvLyAyNS4gICAgdHYzID0gQ01PVih0djIsIHR2MywgZTEpXG4gICAgICB0djQgPSBGcC5jbW92KHR2djUsIHR2NCwgZTEpOyAvLyAyNi4gICAgdHY0ID0gQ01PVih0djUsIHR2NCwgZTEpXG4gICAgfVxuICAgIHJldHVybiB7IGlzVmFsaWQ6IGlzUVIsIHZhbHVlOiB0djMgfTtcbiAgfTtcbiAgaWYgKEZwLk9SREVSICUgXzRuID09PSBfM24pIHtcbiAgICAvLyBzcXJ0X3JhdGlvXzNtb2Q0KHUsIHYpXG4gICAgY29uc3QgYzEgPSAoRnAuT1JERVIgLSBfM24pIC8gXzRuOyAvLyAxLiBjMSA9IChxIC0gMykgLyA0ICAgICAjIEludGVnZXIgYXJpdGhtZXRpY1xuICAgIGNvbnN0IGMyID0gRnAuc3FydChGcC5uZWcoWikpOyAvLyAyLiBjMiA9IHNxcnQoLVopXG4gICAgc3FydFJhdGlvID0gKHU6IFQsIHY6IFQpID0+IHtcbiAgICAgIGxldCB0djEgPSBGcC5zcXIodik7IC8vIDEuIHR2MSA9IHZeMlxuICAgICAgY29uc3QgdHYyID0gRnAubXVsKHUsIHYpOyAvLyAyLiB0djIgPSB1ICogdlxuICAgICAgdHYxID0gRnAubXVsKHR2MSwgdHYyKTsgLy8gMy4gdHYxID0gdHYxICogdHYyXG4gICAgICBsZXQgeTEgPSBGcC5wb3codHYxLCBjMSk7IC8vIDQuIHkxID0gdHYxXmMxXG4gICAgICB5MSA9IEZwLm11bCh5MSwgdHYyKTsgLy8gNS4geTEgPSB5MSAqIHR2MlxuICAgICAgY29uc3QgeTIgPSBGcC5tdWwoeTEsIGMyKTsgLy8gNi4geTIgPSB5MSAqIGMyXG4gICAgICBjb25zdCB0djMgPSBGcC5tdWwoRnAuc3FyKHkxKSwgdik7IC8vIDcuIHR2MyA9IHkxXjI7IDguIHR2MyA9IHR2MyAqIHZcbiAgICAgIGNvbnN0IGlzUVIgPSBGcC5lcWwodHYzLCB1KTsgLy8gOS4gaXNRUiA9IHR2MyA9PSB1XG4gICAgICBsZXQgeSA9IEZwLmNtb3YoeTIsIHkxLCBpc1FSKTsgLy8gMTAuIHkgPSBDTU9WKHkyLCB5MSwgaXNRUilcbiAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGlzUVIsIHZhbHVlOiB5IH07IC8vIDExLiByZXR1cm4gKGlzUVIsIHkpIGlzUVIgPyB5IDogeSpjMlxuICAgIH07XG4gIH1cbiAgLy8gTm8gY3VydmVzIHVzZXMgdGhhdFxuICAvLyBpZiAoRnAuT1JERVIgJSBfOG4gPT09IF81bikgLy8gc3FydF9yYXRpb181bW9kOFxuICByZXR1cm4gc3FydFJhdGlvO1xufVxuLyoqXG4gKiBGcm9tIGRyYWZ0LWlydGYtY2ZyZy1oYXNoLXRvLWN1cnZlLTE2XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBUb0N1cnZlU2ltcGxlU1dVPFQ+KFxuICBGcDogbW9kLklGaWVsZDxUPixcbiAgb3B0czoge1xuICAgIEE6IFQ7XG4gICAgQjogVDtcbiAgICBaOiBUO1xuICB9XG4pIHtcbiAgbW9kLnZhbGlkYXRlRmllbGQoRnApO1xuICBpZiAoIUZwLmlzVmFsaWQob3B0cy5BKSB8fCAhRnAuaXNWYWxpZChvcHRzLkIpIHx8ICFGcC5pc1ZhbGlkKG9wdHMuWikpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdtYXBUb0N1cnZlU2ltcGxlU1dVOiBpbnZhbGlkIG9wdHMnKTtcbiAgY29uc3Qgc3FydFJhdGlvID0gU1dVRnBTcXJ0UmF0aW8oRnAsIG9wdHMuWik7XG4gIGlmICghRnAuaXNPZGQpIHRocm93IG5ldyBFcnJvcignRnAuaXNPZGQgaXMgbm90IGltcGxlbWVudGVkIScpO1xuICAvLyBJbnB1dDogdSwgYW4gZWxlbWVudCBvZiBGLlxuICAvLyBPdXRwdXQ6ICh4LCB5KSwgYSBwb2ludCBvbiBFLlxuICByZXR1cm4gKHU6IFQpOiB7IHg6IFQ7IHk6IFQgfSA9PiB7XG4gICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgbGV0IHR2MSwgdHYyLCB0djMsIHR2NCwgdHY1LCB0djYsIHgsIHk7XG4gICAgdHYxID0gRnAuc3FyKHUpOyAvLyAxLiAgdHYxID0gdV4yXG4gICAgdHYxID0gRnAubXVsKHR2MSwgb3B0cy5aKTsgLy8gMi4gIHR2MSA9IFogKiB0djFcbiAgICB0djIgPSBGcC5zcXIodHYxKTsgLy8gMy4gIHR2MiA9IHR2MV4yXG4gICAgdHYyID0gRnAuYWRkKHR2MiwgdHYxKTsgLy8gNC4gIHR2MiA9IHR2MiArIHR2MVxuICAgIHR2MyA9IEZwLmFkZCh0djIsIEZwLk9ORSk7IC8vIDUuICB0djMgPSB0djIgKyAxXG4gICAgdHYzID0gRnAubXVsKHR2Mywgb3B0cy5CKTsgLy8gNi4gIHR2MyA9IEIgKiB0djNcbiAgICB0djQgPSBGcC5jbW92KG9wdHMuWiwgRnAubmVnKHR2MiksICFGcC5lcWwodHYyLCBGcC5aRVJPKSk7IC8vIDcuICB0djQgPSBDTU9WKFosIC10djIsIHR2MiAhPSAwKVxuICAgIHR2NCA9IEZwLm11bCh0djQsIG9wdHMuQSk7IC8vIDguICB0djQgPSBBICogdHY0XG4gICAgdHYyID0gRnAuc3FyKHR2Myk7IC8vIDkuICB0djIgPSB0djNeMlxuICAgIHR2NiA9IEZwLnNxcih0djQpOyAvLyAxMC4gdHY2ID0gdHY0XjJcbiAgICB0djUgPSBGcC5tdWwodHY2LCBvcHRzLkEpOyAvLyAxMS4gdHY1ID0gQSAqIHR2NlxuICAgIHR2MiA9IEZwLmFkZCh0djIsIHR2NSk7IC8vIDEyLiB0djIgPSB0djIgKyB0djVcbiAgICB0djIgPSBGcC5tdWwodHYyLCB0djMpOyAvLyAxMy4gdHYyID0gdHYyICogdHYzXG4gICAgdHY2ID0gRnAubXVsKHR2NiwgdHY0KTsgLy8gMTQuIHR2NiA9IHR2NiAqIHR2NFxuICAgIHR2NSA9IEZwLm11bCh0djYsIG9wdHMuQik7IC8vIDE1LiB0djUgPSBCICogdHY2XG4gICAgdHYyID0gRnAuYWRkKHR2MiwgdHY1KTsgLy8gMTYuIHR2MiA9IHR2MiArIHR2NVxuICAgIHggPSBGcC5tdWwodHYxLCB0djMpOyAvLyAxNy4gICB4ID0gdHYxICogdHYzXG4gICAgY29uc3QgeyBpc1ZhbGlkLCB2YWx1ZSB9ID0gc3FydFJhdGlvKHR2MiwgdHY2KTsgLy8gMTguIChpc19neDFfc3F1YXJlLCB5MSkgPSBzcXJ0X3JhdGlvKHR2MiwgdHY2KVxuICAgIHkgPSBGcC5tdWwodHYxLCB1KTsgLy8gMTkuICAgeSA9IHR2MSAqIHUgIC0+IFogKiB1XjMgKiB5MVxuICAgIHkgPSBGcC5tdWwoeSwgdmFsdWUpOyAvLyAyMC4gICB5ID0geSAqIHkxXG4gICAgeCA9IEZwLmNtb3YoeCwgdHYzLCBpc1ZhbGlkKTsgLy8gMjEuICAgeCA9IENNT1YoeCwgdHYzLCBpc19neDFfc3F1YXJlKVxuICAgIHkgPSBGcC5jbW92KHksIHZhbHVlLCBpc1ZhbGlkKTsgLy8gMjIuICAgeSA9IENNT1YoeSwgeTEsIGlzX2d4MV9zcXVhcmUpXG4gICAgY29uc3QgZTEgPSBGcC5pc09kZCEodSkgPT09IEZwLmlzT2RkISh5KTsgLy8gMjMuICBlMSA9IHNnbjAodSkgPT0gc2duMCh5KVxuICAgIHkgPSBGcC5jbW92KEZwLm5lZyh5KSwgeSwgZTEpOyAvLyAyNC4gICB5ID0gQ01PVigteSwgeSwgZTEpXG4gICAgeCA9IEZwLmRpdih4LCB0djQpOyAvLyAyNS4gICB4ID0geCAvIHR2NFxuICAgIHJldHVybiB7IHgsIHkgfTtcbiAgfTtcbn1cbiIsIi8qISBub2JsZS1jdXJ2ZXMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi9cbi8vIFV0aWxpdGllcyBmb3IgbW9kdWxhciBhcml0aG1ldGljcyBhbmQgZmluaXRlIGZpZWxkc1xuaW1wb3J0IHtcbiAgYml0TWFzayxcbiAgbnVtYmVyVG9CeXRlc0JFLFxuICBudW1iZXJUb0J5dGVzTEUsXG4gIGJ5dGVzVG9OdW1iZXJCRSxcbiAgYnl0ZXNUb051bWJlckxFLFxuICBlbnN1cmVCeXRlcyxcbiAgdmFsaWRhdGVPYmplY3QsXG59IGZyb20gJy4vdXRpbHMuanMnO1xuLy8gcHJldHRpZXItaWdub3JlXG5jb25zdCBfMG4gPSBCaWdJbnQoMCksIF8xbiA9IEJpZ0ludCgxKSwgXzJuID0gQmlnSW50KDIpLCBfM24gPSBCaWdJbnQoMyk7XG4vLyBwcmV0dGllci1pZ25vcmVcbmNvbnN0IF80biA9IEJpZ0ludCg0KSwgXzVuID0gQmlnSW50KDUpLCBfOG4gPSBCaWdJbnQoOCk7XG4vLyBwcmV0dGllci1pZ25vcmVcbmNvbnN0IF85biA9IEJpZ0ludCg5KSwgXzE2biA9IEJpZ0ludCgxNik7XG5cbi8vIENhbGN1bGF0ZXMgYSBtb2R1bG8gYlxuZXhwb3J0IGZ1bmN0aW9uIG1vZChhOiBiaWdpbnQsIGI6IGJpZ2ludCk6IGJpZ2ludCB7XG4gIGNvbnN0IHJlc3VsdCA9IGEgJSBiO1xuICByZXR1cm4gcmVzdWx0ID49IF8wbiA/IHJlc3VsdCA6IGIgKyByZXN1bHQ7XG59XG4vKipcbiAqIEVmZmljaWVudGx5IHJhaXNlIG51bSB0byBwb3dlciBhbmQgZG8gbW9kdWxhciBkaXZpc2lvbi5cbiAqIFVuc2FmZSBpbiBzb21lIGNvbnRleHRzOiB1c2VzIGxhZGRlciwgc28gY2FuIGV4cG9zZSBiaWdpbnQgYml0cy5cbiAqIEBleGFtcGxlXG4gKiBwb3coMm4sIDZuLCAxMW4pIC8vIDY0biAlIDExbiA9PSA5blxuICovXG4vLyBUT0RPOiB1c2UgZmllbGQgdmVyc2lvbiAmJiByZW1vdmVcbmV4cG9ydCBmdW5jdGlvbiBwb3cobnVtOiBiaWdpbnQsIHBvd2VyOiBiaWdpbnQsIG1vZHVsbzogYmlnaW50KTogYmlnaW50IHtcbiAgaWYgKG1vZHVsbyA8PSBfMG4gfHwgcG93ZXIgPCBfMG4pIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgcG93ZXIvbW9kdWxvID4gMCcpO1xuICBpZiAobW9kdWxvID09PSBfMW4pIHJldHVybiBfMG47XG4gIGxldCByZXMgPSBfMW47XG4gIHdoaWxlIChwb3dlciA+IF8wbikge1xuICAgIGlmIChwb3dlciAmIF8xbikgcmVzID0gKHJlcyAqIG51bSkgJSBtb2R1bG87XG4gICAgbnVtID0gKG51bSAqIG51bSkgJSBtb2R1bG87XG4gICAgcG93ZXIgPj49IF8xbjtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuXG4vLyBEb2VzIHggXiAoMiBeIHBvd2VyKSBtb2QgcC4gcG93MigzMCwgNCkgPT0gMzAgXiAoMiBeIDQpXG5leHBvcnQgZnVuY3Rpb24gcG93Mih4OiBiaWdpbnQsIHBvd2VyOiBiaWdpbnQsIG1vZHVsbzogYmlnaW50KTogYmlnaW50IHtcbiAgbGV0IHJlcyA9IHg7XG4gIHdoaWxlIChwb3dlci0tID4gXzBuKSB7XG4gICAgcmVzICo9IHJlcztcbiAgICByZXMgJT0gbW9kdWxvO1xuICB9XG4gIHJldHVybiByZXM7XG59XG5cbi8vIEludmVyc2VzIG51bWJlciBvdmVyIG1vZHVsb1xuZXhwb3J0IGZ1bmN0aW9uIGludmVydChudW1iZXI6IGJpZ2ludCwgbW9kdWxvOiBiaWdpbnQpOiBiaWdpbnQge1xuICBpZiAobnVtYmVyID09PSBfMG4gfHwgbW9kdWxvIDw9IF8wbikge1xuICAgIHRocm93IG5ldyBFcnJvcihgaW52ZXJ0OiBleHBlY3RlZCBwb3NpdGl2ZSBpbnRlZ2VycywgZ290IG49JHtudW1iZXJ9IG1vZD0ke21vZHVsb31gKTtcbiAgfVxuICAvLyBFdWNsaWRlYW4gR0NEIGh0dHBzOi8vYnJpbGxpYW50Lm9yZy93aWtpL2V4dGVuZGVkLWV1Y2xpZGVhbi1hbGdvcml0aG0vXG4gIC8vIEZlcm1hdCdzIGxpdHRsZSB0aGVvcmVtIFwiQ1QtbGlrZVwiIHZlcnNpb24gaW52KG4pID0gbl4obS0yKSBtb2QgbSBpcyAzMHggc2xvd2VyLlxuICBsZXQgYSA9IG1vZChudW1iZXIsIG1vZHVsbyk7XG4gIGxldCBiID0gbW9kdWxvO1xuICAvLyBwcmV0dGllci1pZ25vcmVcbiAgbGV0IHggPSBfMG4sIHkgPSBfMW4sIHUgPSBfMW4sIHYgPSBfMG47XG4gIHdoaWxlIChhICE9PSBfMG4pIHtcbiAgICAvLyBKSVQgYXBwbGllcyBvcHRpbWl6YXRpb24gaWYgdGhvc2UgdHdvIGxpbmVzIGZvbGxvdyBlYWNoIG90aGVyXG4gICAgY29uc3QgcSA9IGIgLyBhO1xuICAgIGNvbnN0IHIgPSBiICUgYTtcbiAgICBjb25zdCBtID0geCAtIHUgKiBxO1xuICAgIGNvbnN0IG4gPSB5IC0gdiAqIHE7XG4gICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgYiA9IGEsIGEgPSByLCB4ID0gdSwgeSA9IHYsIHUgPSBtLCB2ID0gbjtcbiAgfVxuICBjb25zdCBnY2QgPSBiO1xuICBpZiAoZ2NkICE9PSBfMW4pIHRocm93IG5ldyBFcnJvcignaW52ZXJ0OiBkb2VzIG5vdCBleGlzdCcpO1xuICByZXR1cm4gbW9kKHgsIG1vZHVsbyk7XG59XG5cbi8vIFRvbmVsbGktU2hhbmtzIGFsZ29yaXRobVxuLy8gUGFwZXIgMTogaHR0cHM6Ly9lcHJpbnQuaWFjci5vcmcvMjAxMi82ODUucGRmIChwYWdlIDEyKVxuLy8gUGFwZXIgMjogU3F1YXJlIFJvb3RzIGZyb20gMTsgMjQsIDUxLCAxMCB0byBEYW4gU2hhbmtzXG5leHBvcnQgZnVuY3Rpb24gdG9uZWxsaVNoYW5rcyhQOiBiaWdpbnQpIHtcbiAgLy8gTGVnZW5kcmUgY29uc3RhbnQ6IHVzZWQgdG8gY2FsY3VsYXRlIExlZ2VuZHJlIHN5bWJvbCAoYSB8IHApLFxuICAvLyB3aGljaCBkZW5vdGVzIHRoZSB2YWx1ZSBvZiBhXigocC0xKS8yKSAobW9kIHApLlxuICAvLyAoYSB8IHApIOKJoSAxICAgIGlmIGEgaXMgYSBzcXVhcmUgKG1vZCBwKVxuICAvLyAoYSB8IHApIOKJoSAtMSAgIGlmIGEgaXMgbm90IGEgc3F1YXJlIChtb2QgcClcbiAgLy8gKGEgfCBwKSDiiaEgMCAgICBpZiBhIOKJoSAwIChtb2QgcClcbiAgY29uc3QgbGVnZW5kcmVDID0gKFAgLSBfMW4pIC8gXzJuO1xuXG4gIGxldCBROiBiaWdpbnQsIFM6IG51bWJlciwgWjogYmlnaW50O1xuICAvLyBTdGVwIDE6IEJ5IGZhY3RvcmluZyBvdXQgcG93ZXJzIG9mIDIgZnJvbSBwIC0gMSxcbiAgLy8gZmluZCBxIGFuZCBzIHN1Y2ggdGhhdCBwIC0gMSA9IHEqKDJecykgd2l0aCBxIG9kZFxuICBmb3IgKFEgPSBQIC0gXzFuLCBTID0gMDsgUSAlIF8ybiA9PT0gXzBuOyBRIC89IF8ybiwgUysrKTtcblxuICAvLyBTdGVwIDI6IFNlbGVjdCBhIG5vbi1zcXVhcmUgeiBzdWNoIHRoYXQgKHogfCBwKSDiiaEgLTEgYW5kIHNldCBjIOKJoSB6cVxuICBmb3IgKFogPSBfMm47IFogPCBQICYmIHBvdyhaLCBsZWdlbmRyZUMsIFApICE9PSBQIC0gXzFuOyBaKyspO1xuXG4gIC8vIEZhc3QtcGF0aFxuICBpZiAoUyA9PT0gMSkge1xuICAgIGNvbnN0IHAxZGl2NCA9IChQICsgXzFuKSAvIF80bjtcbiAgICByZXR1cm4gZnVuY3Rpb24gdG9uZWxsaUZhc3Q8VD4oRnA6IElGaWVsZDxUPiwgbjogVCkge1xuICAgICAgY29uc3Qgcm9vdCA9IEZwLnBvdyhuLCBwMWRpdjQpO1xuICAgICAgaWYgKCFGcC5lcWwoRnAuc3FyKHJvb3QpLCBuKSkgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCBzcXVhcmUgcm9vdCcpO1xuICAgICAgcmV0dXJuIHJvb3Q7XG4gICAgfTtcbiAgfVxuXG4gIC8vIFNsb3ctcGF0aFxuICBjb25zdCBRMWRpdjIgPSAoUSArIF8xbikgLyBfMm47XG4gIHJldHVybiBmdW5jdGlvbiB0b25lbGxpU2xvdzxUPihGcDogSUZpZWxkPFQ+LCBuOiBUKTogVCB7XG4gICAgLy8gU3RlcCAwOiBDaGVjayB0aGF0IG4gaXMgaW5kZWVkIGEgc3F1YXJlOiAobiB8IHApIHNob3VsZCBub3QgYmUg4omhIC0xXG4gICAgaWYgKEZwLnBvdyhuLCBsZWdlbmRyZUMpID09PSBGcC5uZWcoRnAuT05FKSkgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCBzcXVhcmUgcm9vdCcpO1xuICAgIGxldCByID0gUztcbiAgICAvLyBUT0RPOiB3aWxsIGZhaWwgYXQgRnAyL2V0Y1xuICAgIGxldCBnID0gRnAucG93KEZwLm11bChGcC5PTkUsIFopLCBRKTsgLy8gd2lsbCB1cGRhdGUgYm90aCB4IGFuZCBiXG4gICAgbGV0IHggPSBGcC5wb3cobiwgUTFkaXYyKTsgLy8gZmlyc3QgZ3Vlc3MgYXQgdGhlIHNxdWFyZSByb290XG4gICAgbGV0IGIgPSBGcC5wb3cobiwgUSk7IC8vIGZpcnN0IGd1ZXNzIGF0IHRoZSBmdWRnZSBmYWN0b3JcblxuICAgIHdoaWxlICghRnAuZXFsKGIsIEZwLk9ORSkpIHtcbiAgICAgIGlmIChGcC5lcWwoYiwgRnAuWkVSTykpIHJldHVybiBGcC5aRVJPOyAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Ub25lbGxpJUUyJTgwJTkzU2hhbmtzX2FsZ29yaXRobSAoNC4gSWYgdCA9IDAsIHJldHVybiByID0gMClcbiAgICAgIC8vIEZpbmQgbSBzdWNoIGJeKDJebSk9PTFcbiAgICAgIGxldCBtID0gMTtcbiAgICAgIGZvciAobGV0IHQyID0gRnAuc3FyKGIpOyBtIDwgcjsgbSsrKSB7XG4gICAgICAgIGlmIChGcC5lcWwodDIsIEZwLk9ORSkpIGJyZWFrO1xuICAgICAgICB0MiA9IEZwLnNxcih0Mik7IC8vIHQyICo9IHQyXG4gICAgICB9XG4gICAgICAvLyBOT1RFOiByLW0tMSBjYW4gYmUgYmlnZ2VyIHRoYW4gMzIsIG5lZWQgdG8gY29udmVydCB0byBiaWdpbnQgYmVmb3JlIHNoaWZ0LCBvdGhlcndpc2UgdGhlcmUgd2lsbCBiZSBvdmVyZmxvd1xuICAgICAgY29uc3QgZ2UgPSBGcC5wb3coZywgXzFuIDw8IEJpZ0ludChyIC0gbSAtIDEpKTsgLy8gZ2UgPSAyXihyLW0tMSlcbiAgICAgIGcgPSBGcC5zcXIoZ2UpOyAvLyBnID0gZ2UgKiBnZVxuICAgICAgeCA9IEZwLm11bCh4LCBnZSk7IC8vIHggKj0gZ2VcbiAgICAgIGIgPSBGcC5tdWwoYiwgZyk7IC8vIGIgKj0gZ1xuICAgICAgciA9IG07XG4gICAgfVxuICAgIHJldHVybiB4O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gRnBTcXJ0KFA6IGJpZ2ludCkge1xuICAvLyBOT1RFOiBkaWZmZXJlbnQgYWxnb3JpdGhtcyBjYW4gZ2l2ZSBkaWZmZXJlbnQgcm9vdHMsIGl0IGlzIHVwIHRvIHVzZXIgdG8gZGVjaWRlIHdoaWNoIG9uZSB0aGV5IHdhbnQuXG4gIC8vIEZvciBleGFtcGxlIHRoZXJlIGlzIEZwU3FydE9kZC9GcFNxcnRFdmVuIHRvIGNob2ljZSByb290IGJhc2VkIG9uIG9kZG5lc3MgKHVzZWQgZm9yIGhhc2gtdG8tY3VydmUpLlxuXG4gIC8vIFAg4omhIDMgKG1vZCA0KVxuICAvLyDiiJpuID0gbl4oKFArMSkvNClcbiAgaWYgKFAgJSBfNG4gPT09IF8zbikge1xuICAgIC8vIE5vdCBhbGwgcm9vdHMgcG9zc2libGUhXG4gICAgLy8gY29uc3QgT1JERVIgPVxuICAgIC8vICAgMHgxYTAxMTFlYTM5N2ZlNjlhNGIxYmE3YjY0MzRiYWNkNzY0Nzc0Yjg0ZjM4NTEyYmY2NzMwZDJhMGY2YjBmNjI0MWVhYmZmZmViMTUzZmZmZmI5ZmVmZmZmZmZmZmFhYWJuO1xuICAgIC8vIGNvbnN0IE5VTSA9IDcyMDU3NTk0MDM3OTI3ODE2bjtcbiAgICBjb25zdCBwMWRpdjQgPSAoUCArIF8xbikgLyBfNG47XG4gICAgcmV0dXJuIGZ1bmN0aW9uIHNxcnQzbW9kNDxUPihGcDogSUZpZWxkPFQ+LCBuOiBUKSB7XG4gICAgICBjb25zdCByb290ID0gRnAucG93KG4sIHAxZGl2NCk7XG4gICAgICAvLyBUaHJvdyBpZiByb290KioyICE9IG5cbiAgICAgIGlmICghRnAuZXFsKEZwLnNxcihyb290KSwgbikpIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgc3F1YXJlIHJvb3QnKTtcbiAgICAgIHJldHVybiByb290O1xuICAgIH07XG4gIH1cblxuICAvLyBBdGtpbiBhbGdvcml0aG0gZm9yIHEg4omhIDUgKG1vZCA4KSwgaHR0cHM6Ly9lcHJpbnQuaWFjci5vcmcvMjAxMi82ODUucGRmIChwYWdlIDEwKVxuICBpZiAoUCAlIF84biA9PT0gXzVuKSB7XG4gICAgY29uc3QgYzEgPSAoUCAtIF81bikgLyBfOG47XG4gICAgcmV0dXJuIGZ1bmN0aW9uIHNxcnQ1bW9kODxUPihGcDogSUZpZWxkPFQ+LCBuOiBUKSB7XG4gICAgICBjb25zdCBuMiA9IEZwLm11bChuLCBfMm4pO1xuICAgICAgY29uc3QgdiA9IEZwLnBvdyhuMiwgYzEpO1xuICAgICAgY29uc3QgbnYgPSBGcC5tdWwobiwgdik7XG4gICAgICBjb25zdCBpID0gRnAubXVsKEZwLm11bChudiwgXzJuKSwgdik7XG4gICAgICBjb25zdCByb290ID0gRnAubXVsKG52LCBGcC5zdWIoaSwgRnAuT05FKSk7XG4gICAgICBpZiAoIUZwLmVxbChGcC5zcXIocm9vdCksIG4pKSB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIHNxdWFyZSByb290Jyk7XG4gICAgICByZXR1cm4gcm9vdDtcbiAgICB9O1xuICB9XG5cbiAgLy8gUCDiiaEgOSAobW9kIDE2KVxuICBpZiAoUCAlIF8xNm4gPT09IF85bikge1xuICAgIC8vIE5PVEU6IHRvbmVsbGkgaXMgdG9vIHNsb3cgZm9yIGJscy1GcDIgY2FsY3VsYXRpb25zIGV2ZW4gb24gc3RhcnRcbiAgICAvLyBNZWFucyB3ZSBjYW5ub3QgdXNlIHNxcnQgZm9yIGNvbnN0YW50cyBhdCBhbGwhXG4gICAgLy9cbiAgICAvLyBjb25zdCBjMSA9IEZwLnNxcnQoRnAubmVnYXRlKEZwLk9ORSkpOyAvLyAgMS4gYzEgPSBzcXJ0KC0xKSBpbiBGLCBpLmUuLCAoYzFeMikgPT0gLTEgaW4gRlxuICAgIC8vIGNvbnN0IGMyID0gRnAuc3FydChjMSk7ICAgICAgICAgICAgICAgIC8vICAyLiBjMiA9IHNxcnQoYzEpIGluIEYsIGkuZS4sIChjMl4yKSA9PSBjMSBpbiBGXG4gICAgLy8gY29uc3QgYzMgPSBGcC5zcXJ0KEZwLm5lZ2F0ZShjMSkpOyAgICAgLy8gIDMuIGMzID0gc3FydCgtYzEpIGluIEYsIGkuZS4sIChjM14yKSA9PSAtYzEgaW4gRlxuICAgIC8vIGNvbnN0IGM0ID0gKFAgKyBfN24pIC8gXzE2bjsgICAgICAgICAgIC8vICA0LiBjNCA9IChxICsgNykgLyAxNiAgICAgICAgIyBJbnRlZ2VyIGFyaXRobWV0aWNcbiAgICAvLyBzcXJ0ID0gKHgpID0+IHtcbiAgICAvLyAgIGxldCB0djEgPSBGcC5wb3coeCwgYzQpOyAgICAgICAgICAgICAvLyAgMS4gdHYxID0geF5jNFxuICAgIC8vICAgbGV0IHR2MiA9IEZwLm11bChjMSwgdHYxKTsgICAgICAgICAgIC8vICAyLiB0djIgPSBjMSAqIHR2MVxuICAgIC8vICAgY29uc3QgdHYzID0gRnAubXVsKGMyLCB0djEpOyAgICAgICAgIC8vICAzLiB0djMgPSBjMiAqIHR2MVxuICAgIC8vICAgbGV0IHR2NCA9IEZwLm11bChjMywgdHYxKTsgICAgICAgICAgIC8vICA0LiB0djQgPSBjMyAqIHR2MVxuICAgIC8vICAgY29uc3QgZTEgPSBGcC5lcXVhbHMoRnAuc3F1YXJlKHR2MiksIHgpOyAvLyAgNS4gIGUxID0gKHR2Ml4yKSA9PSB4XG4gICAgLy8gICBjb25zdCBlMiA9IEZwLmVxdWFscyhGcC5zcXVhcmUodHYzKSwgeCk7IC8vICA2LiAgZTIgPSAodHYzXjIpID09IHhcbiAgICAvLyAgIHR2MSA9IEZwLmNtb3YodHYxLCB0djIsIGUxKTsgLy8gIDcuIHR2MSA9IENNT1YodHYxLCB0djIsIGUxKSAgIyBTZWxlY3QgdHYyIGlmICh0djJeMikgPT0geFxuICAgIC8vICAgdHYyID0gRnAuY21vdih0djQsIHR2MywgZTIpOyAvLyAgOC4gdHYyID0gQ01PVih0djQsIHR2MywgZTIpICAjIFNlbGVjdCB0djMgaWYgKHR2M14yKSA9PSB4XG4gICAgLy8gICBjb25zdCBlMyA9IEZwLmVxdWFscyhGcC5zcXVhcmUodHYyKSwgeCk7IC8vICA5LiAgZTMgPSAodHYyXjIpID09IHhcbiAgICAvLyAgIHJldHVybiBGcC5jbW92KHR2MSwgdHYyLCBlMyk7IC8vICAxMC4gIHogPSBDTU9WKHR2MSwgdHYyLCBlMykgICMgU2VsZWN0IHRoZSBzcXJ0IGZyb20gdHYxIGFuZCB0djJcbiAgICAvLyB9XG4gIH1cblxuICAvLyBPdGhlciBjYXNlczogVG9uZWxsaS1TaGFua3MgYWxnb3JpdGhtXG4gIHJldHVybiB0b25lbGxpU2hhbmtzKFApO1xufVxuXG4vLyBMaXR0bGUtZW5kaWFuIGNoZWNrIGZvciBmaXJzdCBMRSBiaXQgKGxhc3QgQkUgYml0KTtcbmV4cG9ydCBjb25zdCBpc05lZ2F0aXZlTEUgPSAobnVtOiBiaWdpbnQsIG1vZHVsbzogYmlnaW50KSA9PiAobW9kKG51bSwgbW9kdWxvKSAmIF8xbikgPT09IF8xbjtcblxuLy8gRmllbGQgaXMgbm90IGFsd2F5cyBvdmVyIHByaW1lLCBGcDIgZm9yIGV4YW1wbGUgaGFzIE9SREVSKHEpPXBebVxuZXhwb3J0IGludGVyZmFjZSBJRmllbGQ8VD4ge1xuICBPUkRFUjogYmlnaW50O1xuICBCWVRFUzogbnVtYmVyO1xuICBCSVRTOiBudW1iZXI7XG4gIE1BU0s6IGJpZ2ludDtcbiAgWkVSTzogVDtcbiAgT05FOiBUO1xuICAvLyAxLWFyZ1xuICBjcmVhdGU6IChudW06IFQpID0+IFQ7XG4gIGlzVmFsaWQ6IChudW06IFQpID0+IGJvb2xlYW47XG4gIGlzMDogKG51bTogVCkgPT4gYm9vbGVhbjtcbiAgbmVnKG51bTogVCk6IFQ7XG4gIGludihudW06IFQpOiBUO1xuICBzcXJ0KG51bTogVCk6IFQ7XG4gIHNxcihudW06IFQpOiBUO1xuICAvLyAyLWFyZ3NcbiAgZXFsKGxoczogVCwgcmhzOiBUKTogYm9vbGVhbjtcbiAgYWRkKGxoczogVCwgcmhzOiBUKTogVDtcbiAgc3ViKGxoczogVCwgcmhzOiBUKTogVDtcbiAgbXVsKGxoczogVCwgcmhzOiBUIHwgYmlnaW50KTogVDtcbiAgcG93KGxoczogVCwgcG93ZXI6IGJpZ2ludCk6IFQ7XG4gIGRpdihsaHM6IFQsIHJoczogVCB8IGJpZ2ludCk6IFQ7XG4gIC8vIE4gZm9yIE5vbk5vcm1hbGl6ZWQgKGZvciBub3cpXG4gIGFkZE4obGhzOiBULCByaHM6IFQpOiBUO1xuICBzdWJOKGxoczogVCwgcmhzOiBUKTogVDtcbiAgbXVsTihsaHM6IFQsIHJoczogVCB8IGJpZ2ludCk6IFQ7XG4gIHNxck4obnVtOiBUKTogVDtcblxuICAvLyBPcHRpb25hbFxuICAvLyBTaG91bGQgYmUgc2FtZSBhcyBzZ24wIGZ1bmN0aW9uIGluIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2RyYWZ0LWlydGYtY2ZyZy1oYXNoLXRvLWN1cnZlL1xuICAvLyBOT1RFOiBzZ24wIGlzICduZWdhdGl2ZSBpbiBMRScsIHdoaWNoIGlzIHNhbWUgYXMgb2RkLiBBbmQgbmVnYXRpdmUgaW4gTEUgaXMga2luZGEgc3RyYW5nZSBkZWZpbml0aW9uIGFueXdheS5cbiAgaXNPZGQ/KG51bTogVCk6IGJvb2xlYW47IC8vIE9kZCBpbnN0ZWFkIG9mIGV2ZW4gc2luY2Ugd2UgaGF2ZSBpdCBmb3IgRnAyXG4gIC8vIGxlZ2VuZHJlPyhudW06IFQpOiBUO1xuICBwb3cobGhzOiBULCBwb3dlcjogYmlnaW50KTogVDtcbiAgaW52ZXJ0QmF0Y2g6IChsc3Q6IFRbXSkgPT4gVFtdO1xuICB0b0J5dGVzKG51bTogVCk6IFVpbnQ4QXJyYXk7XG4gIGZyb21CeXRlcyhieXRlczogVWludDhBcnJheSk6IFQ7XG4gIC8vIElmIGMgaXMgRmFsc2UsIENNT1YgcmV0dXJucyBhLCBvdGhlcndpc2UgaXQgcmV0dXJucyBiLlxuICBjbW92KGE6IFQsIGI6IFQsIGM6IGJvb2xlYW4pOiBUO1xufVxuLy8gcHJldHRpZXItaWdub3JlXG5jb25zdCBGSUVMRF9GSUVMRFMgPSBbXG4gICdjcmVhdGUnLCAnaXNWYWxpZCcsICdpczAnLCAnbmVnJywgJ2ludicsICdzcXJ0JywgJ3NxcicsXG4gICdlcWwnLCAnYWRkJywgJ3N1YicsICdtdWwnLCAncG93JywgJ2RpdicsXG4gICdhZGROJywgJ3N1Yk4nLCAnbXVsTicsICdzcXJOJ1xuXSBhcyBjb25zdDtcbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUZpZWxkPFQ+KGZpZWxkOiBJRmllbGQ8VD4pIHtcbiAgY29uc3QgaW5pdGlhbCA9IHtcbiAgICBPUkRFUjogJ2JpZ2ludCcsXG4gICAgTUFTSzogJ2JpZ2ludCcsXG4gICAgQllURVM6ICdpc1NhZmVJbnRlZ2VyJyxcbiAgICBCSVRTOiAnaXNTYWZlSW50ZWdlcicsXG4gIH0gYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgY29uc3Qgb3B0cyA9IEZJRUxEX0ZJRUxEUy5yZWR1Y2UoKG1hcCwgdmFsOiBzdHJpbmcpID0+IHtcbiAgICBtYXBbdmFsXSA9ICdmdW5jdGlvbic7XG4gICAgcmV0dXJuIG1hcDtcbiAgfSwgaW5pdGlhbCk7XG4gIHJldHVybiB2YWxpZGF0ZU9iamVjdChmaWVsZCwgb3B0cyk7XG59XG5cbi8vIEdlbmVyaWMgZmllbGQgZnVuY3Rpb25zXG5leHBvcnQgZnVuY3Rpb24gRnBQb3c8VD4oZjogSUZpZWxkPFQ+LCBudW06IFQsIHBvd2VyOiBiaWdpbnQpOiBUIHtcbiAgLy8gU2hvdWxkIGhhdmUgc2FtZSBzcGVlZCBhcyBwb3cgZm9yIGJpZ2ludHNcbiAgLy8gVE9ETzogYmVuY2htYXJrIVxuICBpZiAocG93ZXIgPCBfMG4pIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgcG93ZXIgPiAwJyk7XG4gIGlmIChwb3dlciA9PT0gXzBuKSByZXR1cm4gZi5PTkU7XG4gIGlmIChwb3dlciA9PT0gXzFuKSByZXR1cm4gbnVtO1xuICBsZXQgcCA9IGYuT05FO1xuICBsZXQgZCA9IG51bTtcbiAgd2hpbGUgKHBvd2VyID4gXzBuKSB7XG4gICAgaWYgKHBvd2VyICYgXzFuKSBwID0gZi5tdWwocCwgZCk7XG4gICAgZCA9IGYuc3FyKGQpO1xuICAgIHBvd2VyID4+PSBfMW47XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbi8vIDAgaXMgbm9uLWludmVydGlibGU6IG5vbi1iYXRjaGVkIHZlcnNpb24gd2lsbCB0aHJvdyBvbiAwXG5leHBvcnQgZnVuY3Rpb24gRnBJbnZlcnRCYXRjaDxUPihmOiBJRmllbGQ8VD4sIG51bXM6IFRbXSk6IFRbXSB7XG4gIGNvbnN0IHRtcCA9IG5ldyBBcnJheShudW1zLmxlbmd0aCk7XG4gIC8vIFdhbGsgZnJvbSBmaXJzdCB0byBsYXN0LCBtdWx0aXBseSB0aGVtIGJ5IGVhY2ggb3RoZXIgTU9EIHBcbiAgY29uc3QgbGFzdE11bHRpcGxpZWQgPSBudW1zLnJlZHVjZSgoYWNjLCBudW0sIGkpID0+IHtcbiAgICBpZiAoZi5pczAobnVtKSkgcmV0dXJuIGFjYztcbiAgICB0bXBbaV0gPSBhY2M7XG4gICAgcmV0dXJuIGYubXVsKGFjYywgbnVtKTtcbiAgfSwgZi5PTkUpO1xuICAvLyBJbnZlcnQgbGFzdCBlbGVtZW50XG4gIGNvbnN0IGludmVydGVkID0gZi5pbnYobGFzdE11bHRpcGxpZWQpO1xuICAvLyBXYWxrIGZyb20gbGFzdCB0byBmaXJzdCwgbXVsdGlwbHkgdGhlbSBieSBpbnZlcnRlZCBlYWNoIG90aGVyIE1PRCBwXG4gIG51bXMucmVkdWNlUmlnaHQoKGFjYywgbnVtLCBpKSA9PiB7XG4gICAgaWYgKGYuaXMwKG51bSkpIHJldHVybiBhY2M7XG4gICAgdG1wW2ldID0gZi5tdWwoYWNjLCB0bXBbaV0pO1xuICAgIHJldHVybiBmLm11bChhY2MsIG51bSk7XG4gIH0sIGludmVydGVkKTtcbiAgcmV0dXJuIHRtcDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEZwRGl2PFQ+KGY6IElGaWVsZDxUPiwgbGhzOiBULCByaHM6IFQgfCBiaWdpbnQpOiBUIHtcbiAgcmV0dXJuIGYubXVsKGxocywgdHlwZW9mIHJocyA9PT0gJ2JpZ2ludCcgPyBpbnZlcnQocmhzLCBmLk9SREVSKSA6IGYuaW52KHJocykpO1xufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgVHJ1ZSB3aGVuZXZlciB0aGUgdmFsdWUgeCBpcyBhIHNxdWFyZSBpbiB0aGUgZmllbGQgRi5cbmV4cG9ydCBmdW5jdGlvbiBGcElzU3F1YXJlPFQ+KGY6IElGaWVsZDxUPikge1xuICBjb25zdCBsZWdlbmRyZUNvbnN0ID0gKGYuT1JERVIgLSBfMW4pIC8gXzJuOyAvLyBJbnRlZ2VyIGFyaXRobWV0aWNcbiAgcmV0dXJuICh4OiBUKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgcCA9IGYucG93KHgsIGxlZ2VuZHJlQ29uc3QpO1xuICAgIHJldHVybiBmLmVxbChwLCBmLlpFUk8pIHx8IGYuZXFsKHAsIGYuT05FKTtcbiAgfTtcbn1cblxuLy8gQ1VSVkUubiBsZW5ndGhzXG5leHBvcnQgZnVuY3Rpb24gbkxlbmd0aChuOiBiaWdpbnQsIG5CaXRMZW5ndGg/OiBudW1iZXIpIHtcbiAgLy8gQml0IHNpemUsIGJ5dGUgc2l6ZSBvZiBDVVJWRS5uXG4gIGNvbnN0IF9uQml0TGVuZ3RoID0gbkJpdExlbmd0aCAhPT0gdW5kZWZpbmVkID8gbkJpdExlbmd0aCA6IG4udG9TdHJpbmcoMikubGVuZ3RoO1xuICBjb25zdCBuQnl0ZUxlbmd0aCA9IE1hdGguY2VpbChfbkJpdExlbmd0aCAvIDgpO1xuICByZXR1cm4geyBuQml0TGVuZ3RoOiBfbkJpdExlbmd0aCwgbkJ5dGVMZW5ndGggfTtcbn1cblxudHlwZSBGcEZpZWxkID0gSUZpZWxkPGJpZ2ludD4gJiBSZXF1aXJlZDxQaWNrPElGaWVsZDxiaWdpbnQ+LCAnaXNPZGQnPj47XG4vKipcbiAqIEluaXRpYWxpemVzIGEgZ2Fsb2lzIGZpZWxkIG92ZXIgcHJpbWUuIE5vbi1wcmltZXMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIG5vdy5cbiAqIERvIG5vdCBpbml0IGluIGxvb3A6IHNsb3cuIFZlcnkgZnJhZ2lsZTogYWx3YXlzIHJ1biBhIGJlbmNobWFyayBvbiBjaGFuZ2UuXG4gKiBNYWpvciBwZXJmb3JtYW5jZSBnYWluczpcbiAqIGEpIG5vbi1ub3JtYWxpemVkIG9wZXJhdGlvbnMgbGlrZSBtdWxOIGluc3RlYWQgb2YgbXVsXG4gKiBiKSBgT2JqZWN0LmZyZWV6ZWBcbiAqIGMpIFNhbWUgb2JqZWN0IHNoYXBlOiBuZXZlciBhZGQgb3IgcmVtb3ZlIGtleXNcbiAqIEBwYXJhbSBPUkRFUiBwcmltZSBwb3NpdGl2ZSBiaWdpbnRcbiAqIEBwYXJhbSBiaXRMZW4gaG93IG1hbnkgYml0cyB0aGUgZmllbGQgY29uc3VtZXNcbiAqIEBwYXJhbSBpc0xFIChkZWY6IGZhbHNlKSBpZiBlbmNvZGluZyAvIGRlY29kaW5nIHNob3VsZCBiZSBpbiBsaXR0bGUtZW5kaWFuXG4gKiBAcGFyYW0gcmVkZWYgb3B0aW9uYWwgZmFzdGVyIHJlZGVmaW5pdGlvbnMgb2Ygc3FydCBhbmQgb3RoZXIgbWV0aG9kc1xuICovXG5leHBvcnQgZnVuY3Rpb24gRmllbGQoXG4gIE9SREVSOiBiaWdpbnQsXG4gIGJpdExlbj86IG51bWJlcixcbiAgaXNMRSA9IGZhbHNlLFxuICByZWRlZjogUGFydGlhbDxJRmllbGQ8YmlnaW50Pj4gPSB7fVxuKTogUmVhZG9ubHk8RnBGaWVsZD4ge1xuICBpZiAoT1JERVIgPD0gXzBuKSB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIEZwIE9SREVSID4gMCwgZ290ICR7T1JERVJ9YCk7XG4gIGNvbnN0IHsgbkJpdExlbmd0aDogQklUUywgbkJ5dGVMZW5ndGg6IEJZVEVTIH0gPSBuTGVuZ3RoKE9SREVSLCBiaXRMZW4pO1xuICBpZiAoQllURVMgPiAyMDQ4KSB0aHJvdyBuZXcgRXJyb3IoJ0ZpZWxkIGxlbmd0aHMgb3ZlciAyMDQ4IGJ5dGVzIGFyZSBub3Qgc3VwcG9ydGVkJyk7XG4gIGNvbnN0IHNxcnRQID0gRnBTcXJ0KE9SREVSKTtcbiAgY29uc3QgZjogUmVhZG9ubHk8RnBGaWVsZD4gPSBPYmplY3QuZnJlZXplKHtcbiAgICBPUkRFUixcbiAgICBCSVRTLFxuICAgIEJZVEVTLFxuICAgIE1BU0s6IGJpdE1hc2soQklUUyksXG4gICAgWkVSTzogXzBuLFxuICAgIE9ORTogXzFuLFxuICAgIGNyZWF0ZTogKG51bSkgPT4gbW9kKG51bSwgT1JERVIpLFxuICAgIGlzVmFsaWQ6IChudW0pID0+IHtcbiAgICAgIGlmICh0eXBlb2YgbnVtICE9PSAnYmlnaW50JylcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGZpZWxkIGVsZW1lbnQ6IGV4cGVjdGVkIGJpZ2ludCwgZ290ICR7dHlwZW9mIG51bX1gKTtcbiAgICAgIHJldHVybiBfMG4gPD0gbnVtICYmIG51bSA8IE9SREVSOyAvLyAwIGlzIHZhbGlkIGVsZW1lbnQsIGJ1dCBpdCdzIG5vdCBpbnZlcnRpYmxlXG4gICAgfSxcbiAgICBpczA6IChudW0pID0+IG51bSA9PT0gXzBuLFxuICAgIGlzT2RkOiAobnVtKSA9PiAobnVtICYgXzFuKSA9PT0gXzFuLFxuICAgIG5lZzogKG51bSkgPT4gbW9kKC1udW0sIE9SREVSKSxcbiAgICBlcWw6IChsaHMsIHJocykgPT4gbGhzID09PSByaHMsXG5cbiAgICBzcXI6IChudW0pID0+IG1vZChudW0gKiBudW0sIE9SREVSKSxcbiAgICBhZGQ6IChsaHMsIHJocykgPT4gbW9kKGxocyArIHJocywgT1JERVIpLFxuICAgIHN1YjogKGxocywgcmhzKSA9PiBtb2QobGhzIC0gcmhzLCBPUkRFUiksXG4gICAgbXVsOiAobGhzLCByaHMpID0+IG1vZChsaHMgKiByaHMsIE9SREVSKSxcbiAgICBwb3c6IChudW0sIHBvd2VyKSA9PiBGcFBvdyhmLCBudW0sIHBvd2VyKSxcbiAgICBkaXY6IChsaHMsIHJocykgPT4gbW9kKGxocyAqIGludmVydChyaHMsIE9SREVSKSwgT1JERVIpLFxuXG4gICAgLy8gU2FtZSBhcyBhYm92ZSwgYnV0IGRvZXNuJ3Qgbm9ybWFsaXplXG4gICAgc3FyTjogKG51bSkgPT4gbnVtICogbnVtLFxuICAgIGFkZE46IChsaHMsIHJocykgPT4gbGhzICsgcmhzLFxuICAgIHN1Yk46IChsaHMsIHJocykgPT4gbGhzIC0gcmhzLFxuICAgIG11bE46IChsaHMsIHJocykgPT4gbGhzICogcmhzLFxuXG4gICAgaW52OiAobnVtKSA9PiBpbnZlcnQobnVtLCBPUkRFUiksXG4gICAgc3FydDogcmVkZWYuc3FydCB8fCAoKG4pID0+IHNxcnRQKGYsIG4pKSxcbiAgICBpbnZlcnRCYXRjaDogKGxzdCkgPT4gRnBJbnZlcnRCYXRjaChmLCBsc3QpLFxuICAgIC8vIFRPRE86IGRvIHdlIHJlYWxseSBuZWVkIGNvbnN0YW50IGNtb3Y/XG4gICAgLy8gV2UgZG9uJ3QgaGF2ZSBjb25zdC10aW1lIGJpZ2ludHMgYW55d2F5LCBzbyBwcm9iYWJseSB3aWxsIGJlIG5vdCB2ZXJ5IHVzZWZ1bFxuICAgIGNtb3Y6IChhLCBiLCBjKSA9PiAoYyA/IGIgOiBhKSxcbiAgICB0b0J5dGVzOiAobnVtKSA9PiAoaXNMRSA/IG51bWJlclRvQnl0ZXNMRShudW0sIEJZVEVTKSA6IG51bWJlclRvQnl0ZXNCRShudW0sIEJZVEVTKSksXG4gICAgZnJvbUJ5dGVzOiAoYnl0ZXMpID0+IHtcbiAgICAgIGlmIChieXRlcy5sZW5ndGggIT09IEJZVEVTKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZwLmZyb21CeXRlczogZXhwZWN0ZWQgJHtCWVRFU30sIGdvdCAke2J5dGVzLmxlbmd0aH1gKTtcbiAgICAgIHJldHVybiBpc0xFID8gYnl0ZXNUb051bWJlckxFKGJ5dGVzKSA6IGJ5dGVzVG9OdW1iZXJCRShieXRlcyk7XG4gICAgfSxcbiAgfSBhcyBGcEZpZWxkKTtcbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoZik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBGcFNxcnRPZGQ8VD4oRnA6IElGaWVsZDxUPiwgZWxtOiBUKSB7XG4gIGlmICghRnAuaXNPZGQpIHRocm93IG5ldyBFcnJvcihgRmllbGQgZG9lc24ndCBoYXZlIGlzT2RkYCk7XG4gIGNvbnN0IHJvb3QgPSBGcC5zcXJ0KGVsbSk7XG4gIHJldHVybiBGcC5pc09kZChyb290KSA/IHJvb3QgOiBGcC5uZWcocm9vdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBGcFNxcnRFdmVuPFQ+KEZwOiBJRmllbGQ8VD4sIGVsbTogVCkge1xuICBpZiAoIUZwLmlzT2RkKSB0aHJvdyBuZXcgRXJyb3IoYEZpZWxkIGRvZXNuJ3QgaGF2ZSBpc09kZGApO1xuICBjb25zdCByb290ID0gRnAuc3FydChlbG0pO1xuICByZXR1cm4gRnAuaXNPZGQocm9vdCkgPyBGcC5uZWcocm9vdCkgOiByb290O1xufVxuXG4vKipcbiAqIEZJUFMgMTg2IEIuNC4xLWNvbXBsaWFudCBcImNvbnN0YW50LXRpbWVcIiBwcml2YXRlIGtleSBnZW5lcmF0aW9uIHV0aWxpdHkuXG4gKiBDYW4gdGFrZSAobis4KSBvciBtb3JlIGJ5dGVzIG9mIHVuaWZvcm0gaW5wdXQgZS5nLiBmcm9tIENTUFJORyBvciBLREZcbiAqIGFuZCBjb252ZXJ0IHRoZW0gaW50byBwcml2YXRlIHNjYWxhciwgd2l0aCB0aGUgbW9kdWxvIGJpYXMgYmVpbmcgbmVnbGlnaWJsZS5cbiAqIE5lZWRzIGF0IGxlYXN0IDQwIGJ5dGVzIG9mIGlucHV0IGZvciAzMi1ieXRlIHByaXZhdGUga2V5LlxuICogaHR0cHM6Ly9yZXNlYXJjaC5rdWRlbHNraXNlY3VyaXR5LmNvbS8yMDIwLzA3LzI4L3RoZS1kZWZpbml0aXZlLWd1aWRlLXRvLW1vZHVsby1iaWFzLWFuZC1ob3ctdG8tYXZvaWQtaXQvXG4gKiBAcGFyYW0gaGFzaCBoYXNoIG91dHB1dCBmcm9tIFNIQTMgb3IgYSBzaW1pbGFyIGZ1bmN0aW9uXG4gKiBAcGFyYW0gZ3JvdXBPcmRlciBzaXplIG9mIHN1Ymdyb3VwIC0gKGUuZy4gY3VydmVGbi5DVVJWRS5uKVxuICogQHBhcmFtIGlzTEUgaW50ZXJwcmV0IGhhc2ggYnl0ZXMgYXMgTEUgbnVtXG4gKiBAcmV0dXJucyB2YWxpZCBwcml2YXRlIHNjYWxhclxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaFRvUHJpdmF0ZVNjYWxhcihcbiAgaGFzaDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgZ3JvdXBPcmRlcjogYmlnaW50LFxuICBpc0xFID0gZmFsc2Vcbik6IGJpZ2ludCB7XG4gIGhhc2ggPSBlbnN1cmVCeXRlcygncHJpdmF0ZUhhc2gnLCBoYXNoKTtcbiAgY29uc3QgaGFzaExlbiA9IGhhc2gubGVuZ3RoO1xuICBjb25zdCBtaW5MZW4gPSBuTGVuZ3RoKGdyb3VwT3JkZXIpLm5CeXRlTGVuZ3RoICsgODtcbiAgaWYgKG1pbkxlbiA8IDI0IHx8IGhhc2hMZW4gPCBtaW5MZW4gfHwgaGFzaExlbiA+IDEwMjQpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBoYXNoVG9Qcml2YXRlU2NhbGFyOiBleHBlY3RlZCAke21pbkxlbn0tMTAyNCBieXRlcyBvZiBpbnB1dCwgZ290ICR7aGFzaExlbn1gKTtcbiAgY29uc3QgbnVtID0gaXNMRSA/IGJ5dGVzVG9OdW1iZXJMRShoYXNoKSA6IGJ5dGVzVG9OdW1iZXJCRShoYXNoKTtcbiAgcmV0dXJuIG1vZChudW0sIGdyb3VwT3JkZXIgLSBfMW4pICsgXzFuO1xufVxuIiwiLyohIG5vYmxlLWN1cnZlcyAtIE1JVCBMaWNlbnNlIChjKSAyMDIyIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL1xuLy8gQWJlbGlhbiBncm91cCB1dGlsaXRpZXNcbmltcG9ydCB7IElGaWVsZCwgdmFsaWRhdGVGaWVsZCwgbkxlbmd0aCB9IGZyb20gJy4vbW9kdWxhci5qcyc7XG5pbXBvcnQgeyB2YWxpZGF0ZU9iamVjdCB9IGZyb20gJy4vdXRpbHMuanMnO1xuY29uc3QgXzBuID0gQmlnSW50KDApO1xuY29uc3QgXzFuID0gQmlnSW50KDEpO1xuXG5leHBvcnQgdHlwZSBBZmZpbmVQb2ludDxUPiA9IHtcbiAgeDogVDtcbiAgeTogVDtcbn0gJiB7IHo/OiBuZXZlcjsgdD86IG5ldmVyIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXA8VCBleHRlbmRzIEdyb3VwPFQ+PiB7XG4gIGRvdWJsZSgpOiBUO1xuICBuZWdhdGUoKTogVDtcbiAgYWRkKG90aGVyOiBUKTogVDtcbiAgc3VidHJhY3Qob3RoZXI6IFQpOiBUO1xuICBlcXVhbHMob3RoZXI6IFQpOiBib29sZWFuO1xuICBtdWx0aXBseShzY2FsYXI6IGJpZ2ludCk6IFQ7XG59XG5cbmV4cG9ydCB0eXBlIEdyb3VwQ29uc3RydWN0b3I8VD4gPSB7XG4gIEJBU0U6IFQ7XG4gIFpFUk86IFQ7XG59O1xuZXhwb3J0IHR5cGUgTWFwcGVyPFQ+ID0gKGk6IFRbXSkgPT4gVFtdO1xuXG4vLyBFbGxpcHRpYyBjdXJ2ZSBtdWx0aXBsaWNhdGlvbiBvZiBQb2ludCBieSBzY2FsYXIuIEZyYWdpbGUuXG4vLyBTY2FsYXJzIHNob3VsZCBhbHdheXMgYmUgbGVzcyB0aGFuIGN1cnZlIG9yZGVyOiB0aGlzIHNob3VsZCBiZSBjaGVja2VkIGluc2lkZSBvZiBhIGN1cnZlIGl0c2VsZi5cbi8vIENyZWF0ZXMgcHJlY29tcHV0YXRpb24gdGFibGVzIGZvciBmYXN0IG11bHRpcGxpY2F0aW9uOlxuLy8gLSBwcml2YXRlIHNjYWxhciBpcyBzcGxpdCBieSBmaXhlZCBzaXplIHdpbmRvd3Mgb2YgVyBiaXRzXG4vLyAtIGV2ZXJ5IHdpbmRvdyBwb2ludCBpcyBjb2xsZWN0ZWQgZnJvbSB3aW5kb3cncyB0YWJsZSAmIGFkZGVkIHRvIGFjY3VtdWxhdG9yXG4vLyAtIHNpbmNlIHdpbmRvd3MgYXJlIGRpZmZlcmVudCwgc2FtZSBwb2ludCBpbnNpZGUgdGFibGVzIHdvbid0IGJlIGFjY2Vzc2VkIG1vcmUgdGhhbiBvbmNlIHBlciBjYWxjXG4vLyAtIGVhY2ggbXVsdGlwbGljYXRpb24gaXMgJ01hdGguY2VpbChDVVJWRV9PUkRFUiAvIPCdkYopICsgMScgcG9pbnQgYWRkaXRpb25zIChmaXhlZCBmb3IgYW55IHNjYWxhcilcbi8vIC0gKzEgd2luZG93IGlzIG5lY2Nlc3NhcnkgZm9yIHdOQUZcbi8vIC0gd05BRiByZWR1Y2VzIHRhYmxlIHNpemU6IDJ4IGxlc3MgbWVtb3J5ICsgMnggZmFzdGVyIGdlbmVyYXRpb24sIGJ1dCAxMCUgc2xvd2VyIG11bHRpcGxpY2F0aW9uXG4vLyBUT0RPOiBSZXNlYXJjaCByZXR1cm5pbmcgMmQgSlMgYXJyYXkgb2Ygd2luZG93cywgaW5zdGVhZCBvZiBhIHNpbmdsZSB3aW5kb3cuIFRoaXMgd291bGQgYWxsb3dcbi8vIHdpbmRvd3MgdG8gYmUgaW4gZGlmZmVyZW50IG1lbW9yeSBsb2NhdGlvbnNcbmV4cG9ydCBmdW5jdGlvbiB3TkFGPFQgZXh0ZW5kcyBHcm91cDxUPj4oYzogR3JvdXBDb25zdHJ1Y3RvcjxUPiwgYml0czogbnVtYmVyKSB7XG4gIGNvbnN0IGNvbnN0VGltZU5lZ2F0ZSA9IChjb25kaXRpb246IGJvb2xlYW4sIGl0ZW06IFQpOiBUID0+IHtcbiAgICBjb25zdCBuZWcgPSBpdGVtLm5lZ2F0ZSgpO1xuICAgIHJldHVybiBjb25kaXRpb24gPyBuZWcgOiBpdGVtO1xuICB9O1xuICBjb25zdCBvcHRzID0gKFc6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IHdpbmRvd3MgPSBNYXRoLmNlaWwoYml0cyAvIFcpICsgMTsgLy8gKzEsIGJlY2F1c2VcbiAgICBjb25zdCB3aW5kb3dTaXplID0gMiAqKiAoVyAtIDEpOyAvLyAtMSBiZWNhdXNlIHdlIHNraXAgemVyb1xuICAgIHJldHVybiB7IHdpbmRvd3MsIHdpbmRvd1NpemUgfTtcbiAgfTtcbiAgcmV0dXJuIHtcbiAgICBjb25zdFRpbWVOZWdhdGUsXG4gICAgLy8gbm9uLWNvbnN0IHRpbWUgbXVsdGlwbGljYXRpb24gbGFkZGVyXG4gICAgdW5zYWZlTGFkZGVyKGVsbTogVCwgbjogYmlnaW50KSB7XG4gICAgICBsZXQgcCA9IGMuWkVSTztcbiAgICAgIGxldCBkOiBUID0gZWxtO1xuICAgICAgd2hpbGUgKG4gPiBfMG4pIHtcbiAgICAgICAgaWYgKG4gJiBfMW4pIHAgPSBwLmFkZChkKTtcbiAgICAgICAgZCA9IGQuZG91YmxlKCk7XG4gICAgICAgIG4gPj49IF8xbjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgd05BRiBwcmVjb21wdXRhdGlvbiB3aW5kb3cuIFVzZWQgZm9yIGNhY2hpbmcuXG4gICAgICogRGVmYXVsdCB3aW5kb3cgc2l6ZSBpcyBzZXQgYnkgYHV0aWxzLnByZWNvbXB1dGUoKWAgYW5kIGlzIGVxdWFsIHRvIDguXG4gICAgICogTnVtYmVyIG9mIHByZWNvbXB1dGVkIHBvaW50cyBkZXBlbmRzIG9uIHRoZSBjdXJ2ZSBzaXplOlxuICAgICAqIDJeKPCdkYriiJIxKSAqIChNYXRoLmNlaWwo8J2RmyAvIPCdkYopICsgMSksIHdoZXJlOlxuICAgICAqIC0g8J2RiiBpcyB0aGUgd2luZG93IHNpemVcbiAgICAgKiAtIPCdkZsgaXMgdGhlIGJpdGxlbmd0aCBvZiB0aGUgY3VydmUgb3JkZXIuXG4gICAgICogRm9yIGEgMjU2LWJpdCBjdXJ2ZSBhbmQgd2luZG93IHNpemUgOCwgdGhlIG51bWJlciBvZiBwcmVjb21wdXRlZCBwb2ludHMgaXMgMTI4ICogMzMgPSA0MjI0LlxuICAgICAqIEByZXR1cm5zIHByZWNvbXB1dGVkIHBvaW50IHRhYmxlcyBmbGF0dGVuZWQgdG8gYSBzaW5nbGUgYXJyYXlcbiAgICAgKi9cbiAgICBwcmVjb21wdXRlV2luZG93KGVsbTogVCwgVzogbnVtYmVyKTogR3JvdXA8VD5bXSB7XG4gICAgICBjb25zdCB7IHdpbmRvd3MsIHdpbmRvd1NpemUgfSA9IG9wdHMoVyk7XG4gICAgICBjb25zdCBwb2ludHM6IFRbXSA9IFtdO1xuICAgICAgbGV0IHA6IFQgPSBlbG07XG4gICAgICBsZXQgYmFzZSA9IHA7XG4gICAgICBmb3IgKGxldCB3aW5kb3cgPSAwOyB3aW5kb3cgPCB3aW5kb3dzOyB3aW5kb3crKykge1xuICAgICAgICBiYXNlID0gcDtcbiAgICAgICAgcG9pbnRzLnB1c2goYmFzZSk7XG4gICAgICAgIC8vID0xLCBiZWNhdXNlIHdlIHNraXAgemVyb1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHdpbmRvd1NpemU7IGkrKykge1xuICAgICAgICAgIGJhc2UgPSBiYXNlLmFkZChwKTtcbiAgICAgICAgICBwb2ludHMucHVzaChiYXNlKTtcbiAgICAgICAgfVxuICAgICAgICBwID0gYmFzZS5kb3VibGUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwb2ludHM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEltcGxlbWVudHMgZWMgbXVsdGlwbGljYXRpb24gdXNpbmcgcHJlY29tcHV0ZWQgdGFibGVzIGFuZCB3LWFyeSBub24tYWRqYWNlbnQgZm9ybS5cbiAgICAgKiBAcGFyYW0gVyB3aW5kb3cgc2l6ZVxuICAgICAqIEBwYXJhbSBwcmVjb21wdXRlcyBwcmVjb21wdXRlZCB0YWJsZXNcbiAgICAgKiBAcGFyYW0gbiBzY2FsYXIgKHdlIGRvbid0IGNoZWNrIGhlcmUsIGJ1dCBzaG91bGQgYmUgbGVzcyB0aGFuIGN1cnZlIG9yZGVyKVxuICAgICAqIEByZXR1cm5zIHJlYWwgYW5kIGZha2UgKGZvciBjb25zdC10aW1lKSBwb2ludHNcbiAgICAgKi9cbiAgICB3TkFGKFc6IG51bWJlciwgcHJlY29tcHV0ZXM6IFRbXSwgbjogYmlnaW50KTogeyBwOiBUOyBmOiBUIH0ge1xuICAgICAgLy8gVE9ETzogbWF5YmUgY2hlY2sgdGhhdCBzY2FsYXIgaXMgbGVzcyB0aGFuIGdyb3VwIG9yZGVyPyB3TkFGIGJlaGF2aW91cyBpcyB1bmRlZmluZWQgb3RoZXJ3aXNlXG4gICAgICAvLyBCdXQgbmVlZCB0byBjYXJlZnVsbHkgcmVtb3ZlIG90aGVyIGNoZWNrcyBiZWZvcmUgd05BRi4gT1JERVIgPT0gYml0cyBoZXJlXG4gICAgICBjb25zdCB7IHdpbmRvd3MsIHdpbmRvd1NpemUgfSA9IG9wdHMoVyk7XG5cbiAgICAgIGxldCBwID0gYy5aRVJPO1xuICAgICAgbGV0IGYgPSBjLkJBU0U7XG5cbiAgICAgIGNvbnN0IG1hc2sgPSBCaWdJbnQoMiAqKiBXIC0gMSk7IC8vIENyZWF0ZSBtYXNrIHdpdGggVyBvbmVzOiAwYjExMTEgZm9yIFc9NCBldGMuXG4gICAgICBjb25zdCBtYXhOdW1iZXIgPSAyICoqIFc7XG4gICAgICBjb25zdCBzaGlmdEJ5ID0gQmlnSW50KFcpO1xuXG4gICAgICBmb3IgKGxldCB3aW5kb3cgPSAwOyB3aW5kb3cgPCB3aW5kb3dzOyB3aW5kb3crKykge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB3aW5kb3cgKiB3aW5kb3dTaXplO1xuICAgICAgICAvLyBFeHRyYWN0IFcgYml0cy5cbiAgICAgICAgbGV0IHdiaXRzID0gTnVtYmVyKG4gJiBtYXNrKTtcblxuICAgICAgICAvLyBTaGlmdCBudW1iZXIgYnkgVyBiaXRzLlxuICAgICAgICBuID4+PSBzaGlmdEJ5O1xuXG4gICAgICAgIC8vIElmIHRoZSBiaXRzIGFyZSBiaWdnZXIgdGhhbiBtYXggc2l6ZSwgd2UnbGwgc3BsaXQgdGhvc2UuXG4gICAgICAgIC8vICsyMjQgPT4gMjU2IC0gMzJcbiAgICAgICAgaWYgKHdiaXRzID4gd2luZG93U2l6ZSkge1xuICAgICAgICAgIHdiaXRzIC09IG1heE51bWJlcjtcbiAgICAgICAgICBuICs9IF8xbjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgY29kZSB3YXMgZmlyc3Qgd3JpdHRlbiB3aXRoIGFzc3VtcHRpb24gdGhhdCAnZicgYW5kICdwJyB3aWxsIG5ldmVyIGJlIGluZmluaXR5IHBvaW50OlxuICAgICAgICAvLyBzaW5jZSBlYWNoIGFkZGl0aW9uIGlzIG11bHRpcGxpZWQgYnkgMiAqKiBXLCBpdCBjYW5ub3QgY2FuY2VsIGVhY2ggb3RoZXIuIEhvd2V2ZXIsXG4gICAgICAgIC8vIHRoZXJlIGlzIG5lZ2F0ZSBub3c6IGl0IGlzIHBvc3NpYmxlIHRoYXQgbmVnYXRlZCBlbGVtZW50IGZyb20gbG93IHZhbHVlXG4gICAgICAgIC8vIHdvdWxkIGJlIHRoZSBzYW1lIGFzIGhpZ2ggZWxlbWVudCwgd2hpY2ggd2lsbCBjcmVhdGUgY2FycnkgaW50byBuZXh0IHdpbmRvdy5cbiAgICAgICAgLy8gSXQncyBub3Qgb2J2aW91cyBob3cgdGhpcyBjYW4gZmFpbCwgYnV0IHN0aWxsIHdvcnRoIGludmVzdGlnYXRpbmcgbGF0ZXIuXG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UncmUgb250byBaZXJvIHBvaW50LlxuICAgICAgICAvLyBBZGQgcmFuZG9tIHBvaW50IGluc2lkZSBjdXJyZW50IHdpbmRvdyB0byBmLlxuICAgICAgICBjb25zdCBvZmZzZXQxID0gb2Zmc2V0O1xuICAgICAgICBjb25zdCBvZmZzZXQyID0gb2Zmc2V0ICsgTWF0aC5hYnMod2JpdHMpIC0gMTsgLy8gLTEgYmVjYXVzZSB3ZSBza2lwIHplcm9cbiAgICAgICAgY29uc3QgY29uZDEgPSB3aW5kb3cgJSAyICE9PSAwO1xuICAgICAgICBjb25zdCBjb25kMiA9IHdiaXRzIDwgMDtcbiAgICAgICAgaWYgKHdiaXRzID09PSAwKSB7XG4gICAgICAgICAgLy8gVGhlIG1vc3QgaW1wb3J0YW50IHBhcnQgZm9yIGNvbnN0LXRpbWUgZ2V0UHVibGljS2V5XG4gICAgICAgICAgZiA9IGYuYWRkKGNvbnN0VGltZU5lZ2F0ZShjb25kMSwgcHJlY29tcHV0ZXNbb2Zmc2V0MV0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwID0gcC5hZGQoY29uc3RUaW1lTmVnYXRlKGNvbmQyLCBwcmVjb21wdXRlc1tvZmZzZXQyXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBKSVQtY29tcGlsZXIgc2hvdWxkIG5vdCBlbGltaW5hdGUgZiBoZXJlLCBzaW5jZSBpdCB3aWxsIGxhdGVyIGJlIHVzZWQgaW4gbm9ybWFsaXplWigpXG4gICAgICAvLyBFdmVuIGlmIHRoZSB2YXJpYWJsZSBpcyBzdGlsbCB1bnVzZWQsIHRoZXJlIGFyZSBzb21lIGNoZWNrcyB3aGljaCB3aWxsXG4gICAgICAvLyB0aHJvdyBhbiBleGNlcHRpb24sIHNvIGNvbXBpbGVyIG5lZWRzIHRvIHByb3ZlIHRoZXkgd29uJ3QgaGFwcGVuLCB3aGljaCBpcyBoYXJkLlxuICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGVyZSBpcyBhIHdheSB0byBGIGJlIGluZmluaXR5LXBvaW50IGV2ZW4gaWYgcCBpcyBub3QsXG4gICAgICAvLyB3aGljaCBtYWtlcyBpdCBsZXNzIGNvbnN0LXRpbWU6IGFyb3VuZCAxIGJpZ2ludCBtdWx0aXBseS5cbiAgICAgIHJldHVybiB7IHAsIGYgfTtcbiAgICB9LFxuXG4gICAgd05BRkNhY2hlZChQOiBULCBwcmVjb21wdXRlc01hcDogTWFwPFQsIFRbXT4sIG46IGJpZ2ludCwgdHJhbnNmb3JtOiBNYXBwZXI8VD4pOiB7IHA6IFQ7IGY6IFQgfSB7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBjb25zdCBXOiBudW1iZXIgPSBQLl9XSU5ET1dfU0laRSB8fCAxO1xuICAgICAgLy8gQ2FsY3VsYXRlIHByZWNvbXB1dGVzIG9uIGEgZmlyc3QgcnVuLCByZXVzZSB0aGVtIGFmdGVyXG4gICAgICBsZXQgY29tcCA9IHByZWNvbXB1dGVzTWFwLmdldChQKTtcbiAgICAgIGlmICghY29tcCkge1xuICAgICAgICBjb21wID0gdGhpcy5wcmVjb21wdXRlV2luZG93KFAsIFcpIGFzIFRbXTtcbiAgICAgICAgaWYgKFcgIT09IDEpIHtcbiAgICAgICAgICBwcmVjb21wdXRlc01hcC5zZXQoUCwgdHJhbnNmb3JtKGNvbXApKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMud05BRihXLCBjb21wLCBuKTtcbiAgICB9LFxuICB9O1xufVxuXG4vLyBHZW5lcmljIEJhc2ljQ3VydmUgaW50ZXJmYWNlOiB3b3JrcyBldmVuIGZvciBwb2x5bm9taWFsIGZpZWxkcyAoQkxTKTogUCwgbiwgaCB3b3VsZCBiZSBvay5cbi8vIFRob3VnaCBnZW5lcmF0b3IgY2FuIGJlIGRpZmZlcmVudCAoRnAyIC8gRnA2IGZvciBCTFMpLlxuZXhwb3J0IHR5cGUgQmFzaWNDdXJ2ZTxUPiA9IHtcbiAgRnA6IElGaWVsZDxUPjsgLy8gRmllbGQgb3ZlciB3aGljaCB3ZSdsbCBkbyBjYWxjdWxhdGlvbnMgKEZwKVxuICBuOiBiaWdpbnQ7IC8vIEN1cnZlIG9yZGVyLCB0b3RhbCBjb3VudCBvZiB2YWxpZCBwb2ludHMgaW4gdGhlIGZpZWxkXG4gIG5CaXRMZW5ndGg/OiBudW1iZXI7IC8vIGJpdCBsZW5ndGggb2YgY3VydmUgb3JkZXJcbiAgbkJ5dGVMZW5ndGg/OiBudW1iZXI7IC8vIGJ5dGUgbGVuZ3RoIG9mIGN1cnZlIG9yZGVyXG4gIGg6IGJpZ2ludDsgLy8gY29mYWN0b3IuIHdlIGNhbiBhc3NpZ24gZGVmYXVsdD0xLCBidXQgdXNlcnMgd2lsbCBqdXN0IGlnbm9yZSBpdCB3L28gdmFsaWRhdGlvblxuICBoRWZmPzogYmlnaW50OyAvLyBOdW1iZXIgdG8gbXVsdGlwbHkgdG8gY2xlYXIgY29mYWN0b3JcbiAgR3g6IFQ7IC8vIGJhc2UgcG9pbnQgWCBjb29yZGluYXRlXG4gIEd5OiBUOyAvLyBiYXNlIHBvaW50IFkgY29vcmRpbmF0ZVxuICBhbGxvd0luZmluaXR5UG9pbnQ/OiBib29sZWFuOyAvLyBibHMxMi0zODEgcmVxdWlyZXMgaXQuIFpFUk8gcG9pbnQgaXMgdmFsaWQsIGJ1dCBpbnZhbGlkIHB1YmtleVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQmFzaWM8RlAsIFQ+KGN1cnZlOiBCYXNpY0N1cnZlPEZQPiAmIFQpIHtcbiAgdmFsaWRhdGVGaWVsZChjdXJ2ZS5GcCk7XG4gIHZhbGlkYXRlT2JqZWN0KFxuICAgIGN1cnZlLFxuICAgIHtcbiAgICAgIG46ICdiaWdpbnQnLFxuICAgICAgaDogJ2JpZ2ludCcsXG4gICAgICBHeDogJ2ZpZWxkJyxcbiAgICAgIEd5OiAnZmllbGQnLFxuICAgIH0sXG4gICAge1xuICAgICAgbkJpdExlbmd0aDogJ2lzU2FmZUludGVnZXInLFxuICAgICAgbkJ5dGVMZW5ndGg6ICdpc1NhZmVJbnRlZ2VyJyxcbiAgICB9XG4gICk7XG4gIC8vIFNldCBkZWZhdWx0c1xuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgLi4ubkxlbmd0aChjdXJ2ZS5uLCBjdXJ2ZS5uQml0TGVuZ3RoKSxcbiAgICAuLi5jdXJ2ZSxcbiAgICAuLi57IHA6IGN1cnZlLkZwLk9SREVSIH0sXG4gIH0gYXMgY29uc3QpO1xufVxuIl19
|