From 85ed85835dae2da990ef06e0c0267011399d8fe2 Mon Sep 17 00:00:00 2001 From: gamalielhere Date: Thu, 29 Nov 2018 13:22:51 -0800 Subject: [PATCH] Release: v3.27.0 --- CHANGELOG.md | 3 + app/includes/header.tpl | 6 +- app/manifest.json | 2 +- app/package.json | 2 +- chrome-extension/contest.html | 4 +- chrome-extension/cx-wallet.html | 4 +- chrome-extension/helpers.html | 4 +- chrome-extension/js/etherwallet-master.js | 226836 ++++++++++--------- chrome-extension/manifest.json | 2 +- chrome-extension/phishing.html | 4 +- chrome-extension/privacy-policy.html | 4 +- dist/contest.html | 4 +- dist/helpers.html | 4 +- dist/index.html | 4 +- dist/js/etherwallet-master.js | 226836 ++++++++++--------- dist/package.json | 2 +- dist/phishing.html | 4 +- dist/privacy-policy.html | 4 +- 18 files changed, 227028 insertions(+), 226701 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 809ee67270..cff2e49e64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ +### Release v3.27.0 + ### New +- Fix send null and browser check issues [#2165](https://github.com/kvhnuke/etherwallet/pull/2165) - Add PIT, SKE tokens, add HUM contract [#2165](https://github.com/kvhnuke/etherwallet/pull/2165) - Add ZIX token [#2163](https://github.com/kvhnuke/etherwallet/pull/2163) - Add CRO contract [#2160](https://github.com/kvhnuke/etherwallet/pull/2160) diff --git a/app/includes/header.tpl b/app/includes/header.tpl index f29bfa89d2..6b7507bec6 100644 --- a/app/includes/header.tpl +++ b/app/includes/header.tpl @@ -100,18 +100,18 @@ @@if (site === 'mew' ) { MyEtherWallet -

3.26.0

+

3.27.0

} @@if (site === 'cx' ) { MyEtherWallet -

3.26.0

+

3.27.0

}
- + diff --git a/app/manifest.json b/app/manifest.json index 7c0c65c37e..0f56e57e84 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,6 +1,6 @@ { "name": "MyEtherWallet", - "version": "3.26.0", + "version": "3.27.0", "manifest_version": 2, "description": "MyEtherWallet Chrome Extension", "homepage_url": "https://www.myetherwallet.com/", diff --git a/app/package.json b/app/package.json index 0cd96813e7..6969ad6861 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "MyEtherWallet", - "version": "3.26.0", + "version": "3.27.0", "description": "An NPM dist of MyEtherWallet. For easier downloading & updating via CLI.", "author": "MyEtherWallet", "license": "ISC", diff --git a/chrome-extension/contest.html b/chrome-extension/contest.html index 0e8bd78100..aee37ef5df 100644 --- a/chrome-extension/contest.html +++ b/chrome-extension/contest.html @@ -100,13 +100,13 @@ MyEtherWallet -

3.26.0

+

3.27.0

- + diff --git a/chrome-extension/cx-wallet.html b/chrome-extension/cx-wallet.html index 2ad970724a..a9e90657e6 100644 --- a/chrome-extension/cx-wallet.html +++ b/chrome-extension/cx-wallet.html @@ -83,12 +83,12 @@ MyEtherWallet -

3.26.0

+

3.27.0

- + diff --git a/chrome-extension/helpers.html b/chrome-extension/helpers.html index 0e3738f079..cf3c66dd7f 100644 --- a/chrome-extension/helpers.html +++ b/chrome-extension/helpers.html @@ -101,13 +101,13 @@ MyEtherWallet -

3.26.0

+

3.27.0

- + diff --git a/chrome-extension/js/etherwallet-master.js b/chrome-extension/js/etherwallet-master.js index c3c9f99e4c..bf276c4e51 100644 --- a/chrome-extension/js/etherwallet-master.js +++ b/chrome-extension/js/etherwallet-master.js @@ -368,6 +368,11 @@ module.exports=[ "abi": '[{"constant": true, "inputs": [], "name": "name", "outputs": [{"name": "", "type": "string"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "endBlock", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "spender", "type": "address"}, {"name": "value", "type": "uint256"}], "name": "approve", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "totalSupply", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "from", "type": "address"}, {"name": "to", "type": "address"}, {"name": "value", "type": "uint256"}], "name": "transferFrom", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "ethFundAddress", "outputs": [{"name": "", "type": "address"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "secondCapEndingBlock", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "decimals", "outputs": [{"name": "", "type": "uint8"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "isStopped", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "minCap", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "tokenExchangeRate", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [], "name": "claimTokens", "outputs": [], "payable": true, "stateMutability": "payable", "type": "function"}, {"constant": true, "inputs": [], "name": "startBlock", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "baseTokenCapPerAddress", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [], "name": "finalize", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": false, "inputs": [], "name": "refund", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "blocksInSecondCapPeriod", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [{"name": "owner", "type": "address"}], "name": "balanceOf", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [], "name": "restartSale", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": false, "inputs": [{"name": "targets", "type": "address[]"}, {"name": "isRegistered", "type": "bool"}], "name": "changeRegistrationStatuses", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [{"name": "", "type": "address"}], "name": "purchases", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "isFinalized", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "owner", "outputs": [{"name": "", "type": "address"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "symbol", "outputs": [{"name": "", "type": "string"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "_newOwner", "type": "address"}], "name": "changeOwner", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": false, "inputs": [{"name": "to", "type": "address"}, {"name": "value", "type": "uint256"}], "name": "transfer", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "assignedSupply", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [{"name": "", "type": "address"}], "name": "registered", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "blocksInFirstCapPeriod", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "gmtFundAddress", "outputs": [{"name": "", "type": "address"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "gmtFund", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [{"name": "owner", "type": "address"}, {"name": "spender", "type": "address"}], "name": "allowance", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "baseEthCapPerAddress", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": true, "inputs": [], "name": "firstCapEndingBlock", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [], "name": "stopSale", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "tokenUnit", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"constant": false, "inputs": [{"name": "target", "type": "address"}, {"name": "isRegistered", "type": "bool"}], "name": "changeRegistrationStatus", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function"}, {"constant": true, "inputs": [], "name": "gasLimitInWei", "outputs": [{"name": "", "type": "uint256"}], "payable": false, "stateMutability": "view", "type": "function"}, {"inputs": [{"name": "_ethFundAddress", "type": "address"}, {"name": "_gmtFundAddress", "type": "address"}, {"name": "_startBlock", "type": "uint256"}, {"name": "_endBlock", "type": "uint256"}, {"name": "_tokenExchangeRate", "type": "uint256"}], "payable": false, "stateMutability": "nonpayable", "type": "constructor"}, {"payable": true, "stateMutability": "payable", "type": "fallback"}, {"anonymous": false, "inputs": [{"indexed": true, "name": "_to", "type": "address"}, {"indexed": false, "name": "_value", "type": "uint256"}], "name": "RefundSent", "type": "event"}, {"anonymous": false, "inputs": [{"indexed": true, "name": "_to", "type": "address"}, {"indexed": false, "name": "_value", "type": "uint256"}], "name": "ClaimGMT", "type": "event"}, {"anonymous": false, "inputs": [{"indexed": true, "name": "from", "type": "address"}, {"indexed": true, "name": "to", "type": "address"}, {"indexed": false, "name": "value", "type": "uint256"}], "name": "Transfer", "type": "event"}, {"anonymous": false, "inputs": [{"indexed": true, "name": "owner", "type": "address"}, {"indexed": true, "name": "spender", "type": "address"}, {"indexed": false, "name": "value", "type": "uint256"}], "name": "Approval", "type": "event"}]' }, + { + "name": "GNY", + "address": "0x247551F2EB3362E222c742E9c788B8957D9BC87e", + "abi": '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeSub","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeDiv","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeMul","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeAdd","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]' + }, { "name": "Havven (HAV)", "address": "0xD989a04AD891528B571eF73dAcaEFeB0402a65b3", @@ -379,6 +384,11 @@ module.exports=[ "address": "0xC011A72400E58ecD99Ee497CF89E3775d4bd732F", "abi": '[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"nominsIssued","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"issuer","type":"address"}],"name":"remainingIssuableNomins","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"issuer","type":"address"}],"name":"maxIssuableNomins","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"issueNomins","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"issueMaxNomins","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"burnNomins","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawFees","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"FeesWithdrawn","type":"event"},{"constant":true,"inputs":[],"name":"lastFeesCollected","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]' }, + { + "name": "HUMToken (HUM)", + "address": "0xb0514a5b4aa58ac6e954f537598dd42a71916581", + "abi": '[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"owners","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"lockTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_villains","type":"address[]"}],"name":"addManyToBlacklist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_villain","type":"address"}],"name":"addToBlacklist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_villain","type":"address"}],"name":"removeFromBlacklist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isUnlocked","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"newOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unlockTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"deleteOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"root","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"blacklist","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_wallet","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]' + }, { "name": "IIC - Ibiscoin ERC20 Token Contract", "address": "0x16662F73dF3e79e54c6c5938b4313f92C524C120", @@ -419,6 +429,11 @@ module.exports=[ "abi": '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"minter","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_for","type":"address"},{"name":"tokenCount","type":"uint256"}],"name":"burnTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newAddress","type":"address"}],"name":"changeMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_for","type":"address"},{"name":"tokenCount","type":"uint256"}],"name":"issueTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"exchanger","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"founder","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newAddress","type":"address"}],"name":"changeFounder","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newAddress","type":"address"}],"name":"changeExchanger","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Issuance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Burn","type":"event"}]' }, + { + "name": "LML", + "address": "0x25B6325f5BB1c1E03cfbC3e53F470E1F1ca022E3", + "abi": '[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeSub","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeDiv","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeMul","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"safeAdd","outputs":[{"name":"c","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]' + }, { "name": "LookRev Crowdsale", "address": "0x21ae23b882a340a22282162086bc98d3e2b73018", @@ -787,7 +802,22 @@ module.exports=[ "name": "URB", "address": "0x931684139f756C24eC0731E9F74FE50e5548dDeF", "abi":'[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_fromVault","type":"address"},{"name":"_tokensAmount","type":"uint256"},{"name":"_beneficiary","type":"address"},{"name":"_unlockTime","type":"uint256"}],"name":"lockTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"vestingCountOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"urbitTeamTokensVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"HARD_CAP","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"saleClosedTimestamp","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"releasableBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"releaseVestedTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokensAmount","type":"uint256"},{"name":"_beneficiary","type":"address"},{"name":"_duration","type":"uint256"}],"name":"lockBountyTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"lockedBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"retainedTokensVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"senderIsAdmin","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAGNITUDE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"vestingOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newUrbitAdminAddress","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"burnUnsoldTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"createSaleTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"rewardsTokensVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"saleTokensAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"saleClosed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_fromVault","type":"address"},{"name":"_tokensAmount","type":"uint256"},{"name":"_beneficiary","type":"address"},{"name":"_start","type":"uint256"},{"name":"_cliff","type":"uint256"},{"name":"_duration","type":"uint256"},{"name":"_revocable","type":"bool"}],"name":"vestTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_owner","type":"address"}],"name":"releaseVestedTokensFor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"bountyTokensVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"vestingsOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"urbitAdminAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"closeSale","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"advisorsTokensVault","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_urbitAdminAddress","type":"address"},{"name":"_saleTokensAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]' - } + }, + { + "name": "ABBC Cash(ABCH) Token", + "address": "0xcc7d26d8ea6281bb363c8448515f2c61f7bc19f0", + "abi":'[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_addr","type":"address"}],"name":"isContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"tokens","type":"uint256"},{"name":"data","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"newOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"tokens","type":"uint256"}],"name":"transferAnyERC20Token","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenOwner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Approval","type":"event"}]' + }, + { + "name": "PTON", + "address": "0x4946583c5b86e01ccd30c71a05617d06e3e73060", + "abi":'[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"INITIAL_SUPPLY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"transferEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenOfferingAddr","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"adminAddr","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"TOKEN_OFFERING_ALLOWANCE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ADMIN_ALLOWANCE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"admin","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"name":"offeringAddr","type":"address"},{"name":"amountForSale","type":"uint256"}],"name":"setTokenOffering","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"enableTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]' + }, + { + "name": "CRO", + "address": "0xA0b73E1Ff0B80914AB6fe0444E65848C4C34450b", + "abi":'[{"constant":false,"inputs":[{"name":"addr","type":"address"},{"name":"state","type":"bool"}],"name":"setTransferAgent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"secondarySaleReserveWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"setReleaseAgent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"upgradeAgent","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"releaseTokenTransfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"upgradeMaster","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mainNetLaunchIncentiveReserveWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getUpgradeState","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"transferAgents","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"released","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"canUpgrade","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"capitalReserveWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"airdropReserveWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalUpgraded","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"releaseAgent","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"agent","type":"address"}],"name":"setUpgradeAgent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ecosystemGrantsReserveWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"master","type":"address"}],"name":"setUpgradeMaster","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_initialSupply","type":"uint256"},{"name":"_decimals","type":"uint8"},{"name":"_mintable","type":"bool"},{"name":"_secondarySaleReserveWallet","type":"address"},{"name":"_mainNetLaunchIncentiveReserveWallet","type":"address"},{"name":"_capitalReserveWallet","type":"address"},{"name":"_ecosystemGrantsReserveWallet","type":"address"},{"name":"_airdropReserveWallet","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newName","type":"string"},{"indexed":false,"name":"newSymbol","type":"string"}],"name":"UpdatedTokenInformation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Upgrade","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"agent","type":"address"}],"name":"UpgradeAgentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]' + } ] },{}],10:[function(require,module,exports){ @@ -1011,6 +1041,8 @@ bity.post = function (path, data, callback) { module.exports = bity; },{}],27:[function(require,module,exports){ +"use strict"; + var darklist = function darklist() { return [{ address: "0xF193a9aFb00715AaCF7ca9Ebffafe02C77517C2E", @@ -7226,7 +7258,7 @@ var signMsgCtrl = function signMsgCtrl($scope, $sce, walletService) { module.exports = signMsgCtrl; }).call(this,require("buffer").Buffer) -},{"buffer":262,"u2f-api":847}],44:[function(require,module,exports){ +},{"buffer":414,"u2f-api":999}],44:[function(require,module,exports){ 'use strict'; function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } @@ -9340,6 +9372,8 @@ var walletGenCtrl = function walletGenCtrl($scope) { module.exports = walletGenCtrl; },{}],51:[function(require,module,exports){ +'use strict'; + // For token sale holders: // 1. Add the address users are sending to // 2. Add the gas limit users should use to send successfully (this avoids OOG errors) @@ -9786,6 +9820,12 @@ module.exports = [{ gasLimit: 200000, data: '', msg: 'Credits token sale https://credits.com' +}, { + // ABBC Cash (ABCH) Token Sale + to: '0xcc7d26d8ea6281bb363c8448515f2c61f7bc19f0', + gasLimit: 250000, + data: '', + msg: 'ABCH Token Sale. - https://abbcfoundation.com' }]; },{}],52:[function(require,module,exports){ @@ -10095,6 +10135,8 @@ var walletDecryptDrtv = function walletDecryptDrtv() { module.exports = walletDecryptDrtv; },{"./walletDecryptDrtv.html":60}],62:[function(require,module,exports){ +'use strict'; + var ens = require('./ens'); var domainsaleInterface = require('./domainsaleConfigs/domainsaleABI.json'); @@ -10676,6 +10718,8 @@ module.exports=[ },{}],64:[function(require,module,exports){ (function (Buffer){ +'use strict'; + function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } var uts46 = require('idna-uts46'); @@ -11074,7 +11118,7 @@ ens.prototype.checkDomain = function () { module.exports = ens; }).call(this,require("buffer").Buffer) -},{"./ensConfigs/ETHConfig.json":65,"./ensConfigs/ROPConfig.json":66,"./ensConfigs/RinkebyConfig.json":67,"./ensConfigs/auctionABI.json":68,"./ensConfigs/deedABI.json":69,"./ensConfigs/registryABI.json":70,"./ensConfigs/resolverABI.json":71,"./ensConfigs/subDomainABI.json":72,"buffer":262,"idna-uts46":740}],65:[function(require,module,exports){ +},{"./ensConfigs/ETHConfig.json":65,"./ensConfigs/ROPConfig.json":66,"./ensConfigs/RinkebyConfig.json":67,"./ensConfigs/auctionABI.json":68,"./ensConfigs/deedABI.json":69,"./ensConfigs/registryABI.json":70,"./ensConfigs/resolverABI.json":71,"./ensConfigs/subDomainABI.json":72,"buffer":414,"idna-uts46":892}],65:[function(require,module,exports){ module.exports={ "public": { "resolver": "0x1da022710dF5002339274AaDEe8D58218e9D6AB5", @@ -14220,6 +14264,8 @@ module.exports={ } },{}],77:[function(require,module,exports){ +'use strict'; + function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } var mainKyberNetworkABI = require('./kyberConfig/KyberNetworkABI.json'); @@ -16126,7 +16172,7 @@ if (IS_CX) { app.controller("cxDecryptWalletCtrl", ["$scope", "$sce", "walletService", cxDecryptWalletCtrl]); } -},{"./ajaxReq":25,"./bity":26,"./constants/darkListConst":27,"./controllers/CX/addWalletCtrl":28,"./controllers/CX/cxDecryptWalletCtrl":29,"./controllers/CX/mainPopCtrl":30,"./controllers/CX/myWalletsCtrl":31,"./controllers/CX/quickSendCtrl":32,"./controllers/bulkGenCtrl":33,"./controllers/contractsCtrl":34,"./controllers/decryptWalletCtrl":35,"./controllers/domainsaleCtrl":36,"./controllers/ensCtrl":37,"./controllers/footerCtrl":38,"./controllers/helpersCtrl":39,"./controllers/offlineTxCtrl":40,"./controllers/onboardingCtrl":41,"./controllers/sendTxCtrl":42,"./controllers/signMsgCtrl":43,"./controllers/swapCtrl":44,"./controllers/tabsCtrl":45,"./controllers/txStatusCtrl":46,"./controllers/viewCtrl":47,"./controllers/viewWalletCtrl":48,"./controllers/walletBalanceCtrl":49,"./controllers/walletGenCtrl":50,"./customGas.js":51,"./cxFuncs":52,"./directives/QRCodeDrtv":53,"./directives/addressFieldDrtv":54,"./directives/balanceDrtv":56,"./directives/blockiesDrtv":57,"./directives/cxWalletDecryptDrtv":58,"./directives/fileReaderDrtv":59,"./directives/walletDecryptDrtv":61,"./domainsale":62,"./ens":64,"./ethFuncs":73,"./etherUnits":74,"./globalFuncs":75,"./homoglyphs.json":76,"./kyber":77,"./localStoragePolyfill":85,"./myetherwallet":87,"./nodes":95,"./services/globalService":96,"./services/walletService":97,"./solidity/coder":101,"./solidity/utils":112,"./staticJS/customMarked":113,"./staticJS/digitalBitboxEth":114,"./staticJS/digitalBitboxUsb":115,"./staticJS/ledger-eth":116,"./staticJS/ledger3":117,"./staticJS/mewConnectEth":118,"./staticJS/secalotEth":119,"./staticJS/secalotUsb":120,"./tokenlib":121,"./translations/translate.js":167,"./uiFuncs":171,"./validator":172,"./web3Wallet":173,"@myetherwallet/mewconnect-web-client":870,"angular":181,"angular-animate":175,"angular-sanitize":177,"angular-translate":179,"angular-translate-handler-log":178,"babel-polyfill":200,"bignumber.js":217,"bip39":218,"crypto":688,"detect-browser":695,"ethereumjs-tx":719,"ethereumjs-util":720,"hdkey":737,"levenshtein":755,"punycode":258,"scryptsy":799,"similarity":814,"string-format":816,"trezor-connect":830,"unicode/category/Ll":850,"uuid":854,"wallet-address-validator":867,"xss-filters":869}],87:[function(require,module,exports){ +},{"./ajaxReq":25,"./bity":26,"./constants/darkListConst":27,"./controllers/CX/addWalletCtrl":28,"./controllers/CX/cxDecryptWalletCtrl":29,"./controllers/CX/mainPopCtrl":30,"./controllers/CX/myWalletsCtrl":31,"./controllers/CX/quickSendCtrl":32,"./controllers/bulkGenCtrl":33,"./controllers/contractsCtrl":34,"./controllers/decryptWalletCtrl":35,"./controllers/domainsaleCtrl":36,"./controllers/ensCtrl":37,"./controllers/footerCtrl":38,"./controllers/helpersCtrl":39,"./controllers/offlineTxCtrl":40,"./controllers/onboardingCtrl":41,"./controllers/sendTxCtrl":42,"./controllers/signMsgCtrl":43,"./controllers/swapCtrl":44,"./controllers/tabsCtrl":45,"./controllers/txStatusCtrl":46,"./controllers/viewCtrl":47,"./controllers/viewWalletCtrl":48,"./controllers/walletBalanceCtrl":49,"./controllers/walletGenCtrl":50,"./customGas.js":51,"./cxFuncs":52,"./directives/QRCodeDrtv":53,"./directives/addressFieldDrtv":54,"./directives/balanceDrtv":56,"./directives/blockiesDrtv":57,"./directives/cxWalletDecryptDrtv":58,"./directives/fileReaderDrtv":59,"./directives/walletDecryptDrtv":61,"./domainsale":62,"./ens":64,"./ethFuncs":73,"./etherUnits":74,"./globalFuncs":75,"./homoglyphs.json":76,"./kyber":77,"./localStoragePolyfill":85,"./myetherwallet":87,"./nodes":95,"./services/globalService":96,"./services/walletService":97,"./solidity/coder":101,"./solidity/utils":112,"./staticJS/customMarked":113,"./staticJS/digitalBitboxEth":114,"./staticJS/digitalBitboxUsb":115,"./staticJS/ledger-eth":116,"./staticJS/ledger3":117,"./staticJS/mewConnectEth":118,"./staticJS/secalotEth":119,"./staticJS/secalotUsb":120,"./tokenlib":121,"./translations/translate.js":167,"./uiFuncs":171,"./validator":172,"./web3Wallet":173,"@myetherwallet/mewconnect-web-client":174,"angular":333,"angular-animate":327,"angular-sanitize":329,"angular-translate":331,"angular-translate-handler-log":330,"babel-polyfill":352,"bignumber.js":369,"bip39":370,"crypto":840,"detect-browser":847,"ethereumjs-tx":871,"ethereumjs-util":872,"hdkey":889,"levenshtein":907,"punycode":410,"scryptsy":951,"similarity":966,"string-format":968,"trezor-connect":982,"unicode/category/Ll":1002,"uuid":1006,"wallet-address-validator":1019,"xss-filters":1021}],87:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -16533,7 +16579,7 @@ Wallet.getWalletFromPrivKeyFile = function (strjson, password) { module.exports = Wallet; }).call(this,require("buffer").Buffer) -},{"buffer":262}],88:[function(require,module,exports){ +},{"buffer":414}],88:[function(require,module,exports){ 'use strict'; var customNode = function customNode(srvrUrl, port, httpBasicAuthentication) { @@ -17524,6 +17570,8 @@ var walletService = function walletService() { module.exports = walletService; },{}],98:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -17552,6 +17600,8 @@ SolidityTypeAddress.prototype.isType = function (name) { module.exports = SolidityTypeAddress; },{"./formatters":104,"./type":109}],99:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -17580,6 +17630,8 @@ SolidityTypeBool.prototype.isType = function (name) { module.exports = SolidityTypeBool; },{"./formatters":104,"./type":109}],100:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -17611,6 +17663,8 @@ SolidityTypeBytes.prototype.isType = function (name) { module.exports = SolidityTypeBytes; },{"./formatters":104,"./type":109}],101:[function(require,module,exports){ +'use strict'; + /* This file is part of web3.js. @@ -17862,6 +17916,8 @@ var coder = new SolidityCoder([new SolidityTypeAddress(), new SolidityTypeBool() module.exports = coder; },{"./address":98,"./bool":99,"./bytes":100,"./dynamicbytes":103,"./formatters":104,"./int":105,"./real":107,"./string":108,"./uint":110,"./ureal":111,"./utils":112}],102:[function(require,module,exports){ +'use strict'; + /* This file is part of web3.js. @@ -17912,7 +17968,9 @@ module.exports = { defaultAccount: undefined }; -},{"bignumber.js":217}],103:[function(require,module,exports){ +},{"bignumber.js":369}],103:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -17935,6 +17993,8 @@ SolidityTypeDynamicBytes.prototype.isDynamicType = function () { module.exports = SolidityTypeDynamicBytes; },{"./formatters":104,"./type":109}],104:[function(require,module,exports){ +'use strict'; + /* This file is part of web3.js. @@ -18187,7 +18247,9 @@ module.exports = { formatOutputAddress: formatOutputAddress }; -},{"./config":102,"./param":106,"./utils":112,"bignumber.js":217}],105:[function(require,module,exports){ +},{"./config":102,"./param":106,"./utils":112,"bignumber.js":369}],105:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -18222,6 +18284,8 @@ SolidityTypeInt.prototype.isType = function (name) { module.exports = SolidityTypeInt; },{"./formatters":104,"./type":109}],106:[function(require,module,exports){ +'use strict'; + /* This file is part of web3.js. @@ -18373,6 +18437,8 @@ SolidityParam.encodeList = function (params) { module.exports = SolidityParam; },{"./utils":112}],107:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -18407,6 +18473,8 @@ SolidityTypeReal.prototype.isType = function (name) { module.exports = SolidityTypeReal; },{"./formatters":104,"./type":109}],108:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -18429,6 +18497,8 @@ SolidityTypeString.prototype.isDynamicType = function () { module.exports = SolidityTypeString; },{"./formatters":104,"./type":109}],109:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityParam = require('./param'); @@ -18681,6 +18751,8 @@ SolidityType.prototype.decode = function (bytes, offset, name) { module.exports = SolidityType; },{"./formatters":104,"./param":106}],110:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -18715,6 +18787,8 @@ SolidityTypeUInt.prototype.isType = function (name) { module.exports = SolidityTypeUInt; },{"./formatters":104,"./type":109}],111:[function(require,module,exports){ +'use strict'; + var f = require('./formatters'); var SolidityType = require('./type'); @@ -18749,6 +18823,8 @@ SolidityTypeUReal.prototype.isType = function (name) { module.exports = SolidityTypeUReal; },{"./formatters":104,"./type":109}],112:[function(require,module,exports){ +'use strict'; + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /* @@ -19335,7 +19411,7 @@ module.exports = { isJson: isJson }; -},{"bignumber.js":217,"ethereumjs-util":720,"utf8":852}],113:[function(require,module,exports){ +},{"bignumber.js":369,"ethereumjs-util":872,"utf8":1004}],113:[function(require,module,exports){ 'use strict'; var marked = require('marked'); @@ -19366,7 +19442,7 @@ marked.setOptions({ }); module.exports = marked; -},{"marked":756}],114:[function(require,module,exports){ +},{"marked":908}],114:[function(require,module,exports){ (function (Buffer){ /** * (c) 2017 Douglas Bakkum, Shift Devices AG @@ -19534,7 +19610,7 @@ DigitalBitboxEth.prototype.signMessage = function (path, messageHex, callback) { module.exports = DigitalBitboxEth; }).call(this,require("buffer").Buffer) -},{"buffer":262,"crypto":688,"hdkey":737}],115:[function(require,module,exports){ +},{"buffer":414,"crypto":840,"hdkey":889}],115:[function(require,module,exports){ (function (Buffer){ /** * (c) 2017 Douglas Bakkum, Shift Devices AG @@ -19591,7 +19667,7 @@ DigitalBitboxUsb.prototype.exchange = function (msg, callback) { module.exports = DigitalBitboxUsb; }).call(this,require("buffer").Buffer) -},{"buffer":262,"u2f-api":847}],116:[function(require,module,exports){ +},{"buffer":414,"u2f-api":999}],116:[function(require,module,exports){ (function (Buffer){ /******************************************************************************** * Ledger Communication toolkit @@ -19806,7 +19882,7 @@ LedgerEth.prototype.signPersonalMessage_async = function (path, messageHex, call module.exports = LedgerEth; }).call(this,require("buffer").Buffer) -},{"buffer":262}],117:[function(require,module,exports){ +},{"buffer":414}],117:[function(require,module,exports){ (function (Buffer){ /******************************************************************************** * Ledger Communication toolkit @@ -19880,7 +19956,9 @@ Ledger3.prototype.exchange = function (apduHex, callback) { module.exports = Ledger3; }).call(this,require("buffer").Buffer) -},{"buffer":262,"u2f-api":847}],118:[function(require,module,exports){ +},{"buffer":414,"u2f-api":999}],118:[function(require,module,exports){ +'use strict'; + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -20343,7 +20421,7 @@ SecalotEth.prototype.signMessage = function (path, message, callback) { module.exports = SecalotEth; }).call(this,require("buffer").Buffer) -},{"buffer":262}],120:[function(require,module,exports){ +},{"buffer":414}],120:[function(require,module,exports){ (function (Buffer){ "use strict"; @@ -20390,7 +20468,7 @@ SecalotUsb.prototype.exchange = function (apduHex, callback) { module.exports = SecalotUsb; }).call(this,require("buffer").Buffer) -},{"buffer":262,"u2f-api":847}],121:[function(require,module,exports){ +},{"buffer":414,"u2f-api":999}],121:[function(require,module,exports){ 'use strict'; var Token = function Token(contractAddress, userAddress, symbol, decimal, type) { @@ -20618,6 +20696,12 @@ module.exports=[ "decimal": 18, "type": "default" }, + { + "address": "0xcc7d26d8ea6281bb363c8448515f2c61f7bc19f0", + "symbol": "ABCH", + "decimal": 18, + "type": "default" + }, { "address": "0xb98d4c97425d9908e66e53a6fdf673acca0be986", "symbol": "ABT", @@ -22262,6 +22346,12 @@ module.exports=[ "decimal": 18, "type": "default" }, + { + "address": "0x497bAEF294c11a5f0f5Bea3f2AdB3073DB448B56", + "symbol": "DEX", + "decimal": 18, + "type": "default" + }, { "address": "0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A", "symbol": "DGD", @@ -22898,6 +22988,12 @@ module.exports=[ "decimal": 18, "type": "default" }, + { + "address": "0xd9a8cfe21c232d485065cb62a96866799d4645f7", + "symbol": "FGP", + "decimal": 18, + "type": "default" + }, { "address": "0x52fb36c83ad33c1824912fc81071ca5eeb8ab390", "symbol": "FID", @@ -23198,6 +23294,12 @@ module.exports=[ "decimal": 9, "type": "default" }, + { + "address": "0x247551F2EB3362E222c742E9c788B8957D9BC87e", + "symbol": "GNY", + "decimal": 18, + "type": "default" + }, { "address": "0xeAb43193CF0623073Ca89DB9B712796356FA7414", "symbol": "GOLDX", @@ -23222,6 +23324,12 @@ module.exports=[ "decimal": 18, "type": "default" }, + { + "address": "0xC17195bde49D70CefCF8A9F2ee1759FFC27BF0B1", + "symbol": "GROO", + "decimal": 18, + "type": "default" + }, { "address": "0x0a9A9ce600D08BF9b76F49FA4e7b38A67EBEB1E6", "symbol": "GROW", @@ -23918,6 +24026,12 @@ module.exports=[ "decimal": 5, "type": "default" }, + { + "address": "0xc520F3Ac303a107D8F4B08b326B6ea66A4f961cd", + "symbol": "LG", + "decimal": 18, + "type": "default" + }, { "address": "0x59061b6f26BB4A9cE5828A19d35CFD5A4B80F056", "symbol": "LGD", @@ -23936,6 +24050,12 @@ module.exports=[ "decimal": 8, "type": "default" }, + { + "address": "0xe6dfbf1faca95036b8e76e1fb28933d025b76cc0", + "symbol": "LIBER", + "decimal": 18, + "type": "default" + }, { "address": "0xEB9951021698B42e4399f9cBb6267Aa35F82D59D", "symbol": "LIF", @@ -23978,6 +24098,12 @@ module.exports=[ "decimal": 18, "type": "default" }, + { + "address": "0x25B6325f5BB1c1E03cfbC3e53F470E1F1ca022E3", + "symbol": "LML", + "decimal": 18, + "type": "default" + }, { "address": "0x63e634330A20150DbB61B15648bC73855d6CCF07", "symbol": "LNC", @@ -24454,7 +24580,13 @@ module.exports=[ }, { "address": "0x5d48f293baed247a2d0189058ba37aa238bd4725", - "symbol": "NCC", + "symbol": "NCC (NeuroChain)", + "decimal": 18, + "type": "default" + }, + { + "address": "0x9344b383b1D59b5ce3468B234DAB43C7190ba735", + "symbol": "NCC (NeedsCoin)", "decimal": 18, "type": "default" }, @@ -24926,6 +25058,12 @@ module.exports=[ "decimal": 8, "type": "default" }, + { + "address": "0x0ff161071e627a0e6de138105c73970f86ca7922", + "symbol": "PIT", + "decimal": 18, + "type": "default" + }, { "address": "0x8eFFd494eB698cc399AF6231fCcd39E08fd20B15", "symbol": "PIX", @@ -25130,6 +25268,12 @@ module.exports=[ "decimal": 18, "type": "default" }, + { + "address": "0x4946583c5b86e01ccd30c71a05617d06e3e73060", + "symbol": "PTON", + "decimal": 18, + "type": "default" + }, { "address": "0x8Ae4BF2C33a8e667de34B54938B0ccD03Eb8CC06", "symbol": "PTOY", @@ -25676,6 +25820,12 @@ module.exports=[ "decimal": 8, "type": "default" }, + { + "address": "0x13DB74B3cf512F65C4b91683940B4f3955E05085", + "symbol": "SKE", + "decimal": 8, + "type": "default" + }, { "address": "0x2bDC0D42996017fCe214b21607a515DA41A9E0C5", "symbol": "SKIN", @@ -27049,6 +27199,18 @@ module.exports=[ "symbol": "ZXC", "decimal": 18, "type": "default" + }, + { + "address": "0xabC1280A0187a2020cC675437aed400185F86Db6", + "symbol": "SAC", + "decimal": 18, + "type": "default" + }, + { + "address": "0xf3C092cA8CD6D3d4ca004Dc1d0f1fe8CcAB53599", + "symbol": "ZIX", + "decimal": 18, + "type": "default" } ] @@ -31618,7 +31780,7 @@ uiFuncs.notifier = { module.exports = uiFuncs; }).call(this,require("buffer").Buffer) -},{"buffer":262,"u2f-api":847}],172:[function(require,module,exports){ +},{"buffer":414,"u2f-api":999}],172:[function(require,module,exports){ 'use strict'; var validator = function validator() {}; @@ -31756,100211 +31918,79182 @@ Web3Wallet.prototype.getV3Filename = function (timestamp) { module.exports = Web3Wallet; },{"./myetherwallet.js":87}],174:[function(require,module,exports){ -/** - * @license AngularJS v1.7.5 - * (c) 2010-2018 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular) {'use strict'; +(function (Buffer){ +'use strict'; -var ELEMENT_NODE = 1; -var COMMENT_NODE = 8; +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var ADD_CLASS_SUFFIX = '-add'; -var REMOVE_CLASS_SUFFIX = '-remove'; -var EVENT_CLASS_PREFIX = 'ng-'; -var ACTIVE_CLASS_SUFFIX = '-active'; -var PREPARE_CLASS_SUFFIX = '-prepare'; +var createLogger = _interopDefault(require('logging')); +var EventEmitter = _interopDefault(require('events')); +var browserOrNode = require('browser-or-node'); +var detectBrowser = require('detect-browser'); +var eccrypto = _interopDefault(require('eccrypto')); +var ethUtils = _interopDefault(require('ethereumjs-util')); +var crypto = _interopDefault(require('crypto')); +var secp256k1 = _interopDefault(require('secp256k1')); +var debugLogger = _interopDefault(require('debug')); +var io = _interopDefault(require('socket.io-client')); +var SimplePeer = _interopDefault(require('simple-peer')); -var NG_ANIMATE_CLASSNAME = 'ng-animate'; -var NG_ANIMATE_CHILDREN_DATA = '$$ngAnimateChildren'; +var version = "1.0.9"; -// Detect proper transitionend/animationend event names. -var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT; +var version$1 = version; -// If unprefixed events are not supported but webkit-prefixed are, use the latter. -// Otherwise, just use W3C names, browsers not supporting them at all will just ignore them. -// Note: Chrome implements `window.onwebkitanimationend` and doesn't implement `window.onanimationend` -// but at the same time dispatches the `animationend` event and not `webkitAnimationEnd`. -// Register both events in case `window.onanimationend` is not supported because of that, -// do the same for `transitionend` as Safari is likely to exhibit similar behavior. -// Also, the only modern browser that uses vendor prefixes for transitions/keyframes is webkit -// therefore there is no reason to test anymore for other vendor prefixes: -// http://caniuse.com/#search=transition -if ((window.ontransitionend === undefined) && (window.onwebkittransitionend !== undefined)) { - CSS_PREFIX = '-webkit-'; - TRANSITION_PROP = 'WebkitTransition'; - TRANSITIONEND_EVENT = 'webkitTransitionEnd transitionend'; -} else { - TRANSITION_PROP = 'transition'; - TRANSITIONEND_EVENT = 'transitionend'; -} +var stunServers = [{ urls: 'stun:global.stun.twilio.com:3478?transport=udp' }]; -if ((window.onanimationend === undefined) && (window.onwebkitanimationend !== undefined)) { - CSS_PREFIX = '-webkit-'; - ANIMATION_PROP = 'WebkitAnimation'; - ANIMATIONEND_EVENT = 'webkitAnimationEnd animationend'; -} else { - ANIMATION_PROP = 'animation'; - ANIMATIONEND_EVENT = 'animationend'; -} +var versions = ['0.0.1']; -var DURATION_KEY = 'Duration'; -var PROPERTY_KEY = 'Property'; -var DELAY_KEY = 'Delay'; -var TIMING_KEY = 'TimingFunction'; -var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount'; -var ANIMATION_PLAYSTATE_KEY = 'PlayState'; -var SAFE_FAST_FORWARD_DURATION_VALUE = 9999; +var connectionCodeSchemas = { + '0.0.1': ['version', 'key', 'connId'] +}; -var ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY; -var ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY; -var TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY; -var TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY; +var connectionCodeSeparator = '_'; -var ngMinErr = angular.$$minErr('ng'); -function assertArg(arg, name, reason) { - if (!arg) { - throw ngMinErr('areq', 'Argument \'{0}\' is {1}', (name || '?'), (reason || 'required')); - } - return arg; -} +var signal = { + attemptingTurn: 'attemptingTurn', + turnToken: 'turnToken', + tryTurn: 'tryTurn', + connection: 'connection', + connect: 'connect', + signature: 'signature', + offerSignal: 'offerSignal', + offer: 'offer', + answerSignal: 'answerSignal', + answer: 'answer', + rtcConnected: 'rtcConnected', + disconnect: 'disconnect', + handshake: 'handshake', + confirmation: 'confirmation', + invalidConnection: 'InvalidConnection', + confirmationFailedBusy: 'confirmationFailedBusy', + confirmationFailed: 'confirmationFailed' +}; -function mergeClasses(a,b) { - if (!a && !b) return ''; - if (!a) return b; - if (!b) return a; - if (isArray(a)) a = a.join(' '); - if (isArray(b)) b = b.join(' '); - return a + ' ' + b; -} +var rtc = { + error: 'error', + connect: 'connect', + close: 'close', + data: 'data', + signal: 'signal' +}; -function packageStyles(options) { - var styles = {}; - if (options && (options.to || options.from)) { - styles.to = options.to; - styles.from = options.from; - } - return styles; -} +var iceConnectionState = { + new: 'new', + connecting: 'connecting', + connected: 'connected', + disconnected: 'disconnected', + failed: 'failed', + closed: 'closed' +}; -function pendClasses(classes, fix, isPrefix) { - var className = ''; - classes = isArray(classes) - ? classes - : classes && isString(classes) && classes.length - ? classes.split(/\s+/) - : []; - forEach(classes, function(klass, i) { - if (klass && klass.length > 0) { - className += (i > 0) ? ' ' : ''; - className += isPrefix ? fix + klass - : klass + fix; - } - }); - return className; -} +var stages = { + initiator: 'initiator', + receiver: 'receiver' +}; -function removeFromArray(arr, val) { - var index = arr.indexOf(val); - if (val >= 0) { - arr.splice(index, 1); - } -} +var lifeCycle = { + RtcInitiatedEvent: 'RtcInitiatedEvent', + signatureCheck: 'signatureCheck', + SocketConnectedEvent: 'SocketConnectedEvent', + confirmationFailedEvent: 'confirmationFailedEvent', + confirmationFailedBusyEvent: 'confirmationFailedBusyEvent', + invalidConnectionEvent: 'invalidConnectionEvent', + codeDisplay: 'codeDisplay', + checkNumber: 'checkNumber', + ConnectionId: 'ConnectionId', + receiverVersion: 'receiverVersion', + offerCreated: 'offerCreated', + sendOffer: 'sendOffer', + answerReceived: 'answerReceived', + RtcConnectedEvent: 'RtcConnectedEvent', + RtcConnectedEmitted: "RtcConnectedEmitted", + RtcClosedEvent: 'RtcClosedEvent', + RtcDisconnectEvent: 'RtcDisconnectEvent', + RtcFailedEvent: 'RtcFailedEvent', + RtcErrorEvent: 'RtcErrorEvent', + UsingFallback: 'UsingFallback', + Failed: 'failed', + attemptedDisconnectedSend: 'attemptedDisconnectedSend' +}; -function stripCommentsFromElement(element) { - if (element instanceof jqLite) { - switch (element.length) { - case 0: - return element; +var communicationTypes = { + address: 'address', + signMessage: 'signMessage', + signTx: 'signTx' +}; - case 1: - // there is no point of stripping anything if the element - // is the only element within the jqLite wrapper. - // (it's important that we retain the element instance.) - if (element[0].nodeType === ELEMENT_NODE) { - return element; +var asyncToGenerator = function (fn) { + return function () { + var gen = fn.apply(this, arguments); + return new Promise(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; } - break; - default: - return jqLite(extractElementNode(element)); - } - } + if (info.done) { + resolve(value); + } else { + return Promise.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } - if (element.nodeType === ELEMENT_NODE) { - return jqLite(element); + return step("next"); + }); + }; +}; + +var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); } -} +}; -function extractElementNode(element) { - if (!element[0]) return element; - for (var i = 0; i < element.length; i++) { - var elm = element[i]; - if (elm.nodeType === ELEMENT_NODE) { - return elm; +var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); } } -} -function $$addClass($$jqLite, element, className) { - forEach(element, function(elm) { - $$jqLite.addClass(elm, className); - }); -} + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +}(); -function $$removeClass($$jqLite, element, className) { - forEach(element, function(elm) { - $$jqLite.removeClass(elm, className); - }); -} +var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; -function applyAnimationClassesFactory($$jqLite) { - return function(element, options) { - if (options.addClass) { - $$addClass($$jqLite, element, options.addClass); - options.addClass = null; - } - if (options.removeClass) { - $$removeClass($$jqLite, element, options.removeClass); - options.removeClass = null; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } } - }; -} - -function prepareAnimationOptions(options) { - options = options || {}; - if (!options.$$prepared) { - var domOperation = options.domOperation || noop; - options.domOperation = function() { - options.$$domOperationFired = true; - domOperation(); - domOperation = noop; - }; - options.$$prepared = true; } - return options; -} -function applyAnimationStyles(element, options) { - applyAnimationFromStyles(element, options); - applyAnimationToStyles(element, options); -} + return target; +}; -function applyAnimationFromStyles(element, options) { - if (options.from) { - element.css(options.from); - options.from = null; +var inherits = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } -} -function applyAnimationToStyles(element, options) { - if (options.to) { - element.css(options.to); - options.to = null; + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; +}; + +var possibleConstructorReturn = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } -} -function mergeAnimationDetails(element, oldAnimation, newAnimation) { - var target = oldAnimation.options || {}; - var newOptions = newAnimation.options || {}; + return call && (typeof call === "object" || typeof call === "function") ? call : self; +}; - var toAdd = (target.addClass || '') + ' ' + (newOptions.addClass || ''); - var toRemove = (target.removeClass || '') + ' ' + (newOptions.removeClass || ''); - var classes = resolveElementClasses(element.attr('class'), toAdd, toRemove); +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - if (newOptions.preparationClasses) { - target.preparationClasses = concatWithSpace(newOptions.preparationClasses, target.preparationClasses); - delete newOptions.preparationClasses; + return arr2; + } else { + return Array.from(arr); } +}; - // noop is basically when there is no callback; otherwise something has been set - var realDomOperation = target.domOperation !== noop ? target.domOperation : null; +/* eslint-disable no-undef */ - extend(target, newOptions); +var logger = createLogger('MewConnectCommon'); - // TODO(matsko or sreeramu): proper fix is to maintain all animation callback in array and call at last,but now only leave has the callback so no issue with this. - if (realDomOperation) { - target.domOperation = realDomOperation; - } +var MewConnectCommon = function (_EventEmitter) { + inherits(MewConnectCommon, _EventEmitter); - if (classes.addClass) { - target.addClass = classes.addClass; - } else { - target.addClass = null; - } + function MewConnectCommon() { + classCallCheck(this, MewConnectCommon); - if (classes.removeClass) { - target.removeClass = classes.removeClass; - } else { - target.removeClass = null; + var _this = possibleConstructorReturn(this, (MewConnectCommon.__proto__ || Object.getPrototypeOf(MewConnectCommon)).call(this)); + + _this.isBrowser = browserOrNode.isBrowser; + + _this.jsonDetails = { + stunSrvers: [].concat(toConsumableArray(stunServers)), + signals: _extends({}, signal), + stages: _extends({}, stages), + lifeCycle: _extends({}, lifeCycle), + rtc: _extends({}, rtc), + communicationTypes: _extends({}, communicationTypes), + iceConnectionState: _extends({}, iceConnectionState), + connectionCodeSeparator: connectionCodeSeparator, + version: version$1, + versions: versions, + connectionCodeSchemas: connectionCodeSchemas + }; + return _this; } - oldAnimation.addClass = target.addClass; - oldAnimation.removeClass = target.removeClass; + createClass(MewConnectCommon, [{ + key: 'isJSON', + value: function isJSON(arg) { + try { + JSON.parse(arg); + return true; + } catch (e) { + return false; + } + } + }], [{ + key: 'getBrowserRTC', + value: function getBrowserRTC() { + if (typeof window === 'undefined') return null; + var wrtc = { + RTCPeerConnection: window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection, + RTCSessionDescription: window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription, + RTCIceCandidate: window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate + }; + if (!wrtc.RTCPeerConnection) return null; + return wrtc; + } + }, { + key: 'checkWebRTCAvailable', + value: function checkWebRTCAvailable() { + var doesNotHaveWebRTC = MewConnectCommon.getBrowserRTC() == null; + return !doesNotHaveWebRTC; + // return false + } + }, { + key: 'checkBrowser', + value: function checkBrowser() { + var browser = detectBrowser.detect(); + if (browser === null) { + browser = { version: { split: function split() { + return [1]; + } } }; + } + var browserVersion = browser.version.split(0, 1)[0]; + /* + * Chrome > 23 + * Firefox > 22 + * Opera > 18 + * Safari > 11 (caveats exist) + * Edge - none (RTCDataChannel not supported) + * IE - none + * */ + if (typeof window !== 'undefined') { + if (browser.name === 'safari') { + // eslint-disable-next-line global-require + require('webrtc-adapter'); + return MewConnectCommon.buildBrowserResult(true, 'Safari', 'version: ' + browser.version); + } + if (browser.name === 'ie') { + return MewConnectCommon.buildBrowserResult(true, 'Internet Explorer', '', true); + } + if (browser.name === 'edge') { + return MewConnectCommon.buildBrowserResult(true, 'Edge', 'version: ' + browser.version, true); + } + var name = ''; + var minVersion = 0; - return target; -} + if (browser.name === 'opera') { + name = 'Opera'; + minVersion = 18; + } else if (browser.name === 'firefox') { + name = 'Firefox'; + minVersion = 22; + } else if (browser.name === 'chrome') { + name = 'Chrome'; + minVersion = 23; + } else { + return MewConnectCommon.buildBrowserResult(false, '', '', true); + } -function resolveElementClasses(existing, toAdd, toRemove) { - var ADD_CLASS = 1; - var REMOVE_CLASS = -1; + try { + if (minVersion >= +browserVersion) { + return MewConnectCommon.buildBrowserResult(true, name, 'version: ' + browserVersion); + } + return MewConnectCommon.buildBrowserResult(false, '', ''); + } catch (e) { + logger.error(e); + } + } + } + }, { + key: 'buildBrowserResult', + value: function buildBrowserResult(status, browser, browserVersion, noSupport) { + return { + status: status, + browser: browser, + browserVersion: browserVersion, + noSupport: noSupport || false + }; + } + }]); + return MewConnectCommon; +}(EventEmitter); - var flags = {}; - existing = splitClassesToLookup(existing); +var logger$1 = createLogger('MewCrypto'); - toAdd = splitClassesToLookup(toAdd); - forEach(toAdd, function(value, key) { - flags[key] = ADD_CLASS; - }); +var MewConnectCrypto = function () { + function MewConnectCrypto() { + classCallCheck(this, MewConnectCrypto); + } - toRemove = splitClassesToLookup(toRemove); - forEach(toRemove, function(value, key) { - flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS; - }); + createClass(MewConnectCrypto, [{ + key: 'setPrivate', + value: function setPrivate(pvtKey) { + this.prvt = Buffer.from(pvtKey, 'hex'); + } + }, { + key: 'generateMessage', + value: function generateMessage() { + return crypto.randomBytes(32).toString('hex'); + } - var classes = { - addClass: '', - removeClass: '' - }; + // Not for the Address, but generate them for the connection check - forEach(flags, function(val, klass) { - var prop, allow; - if (val === ADD_CLASS) { - prop = 'addClass'; - allow = !existing[klass] || existing[klass + REMOVE_CLASS_SUFFIX]; - } else if (val === REMOVE_CLASS) { - prop = 'removeClass'; - allow = existing[klass] || existing[klass + ADD_CLASS_SUFFIX]; + }, { + key: 'prepareKey', + value: function prepareKey() { + this.prvt = this.generatePrivate(); + this.pub = this.generatePublic(this.prvt); + return { pub: this.pub, pvt: this.prvt }; } - if (allow) { - if (classes[prop].length) { - classes[prop] += ' '; - } - classes[prop] += klass; + }, { + key: 'generatePrivate', + value: function generatePrivate() { + var privKey = void 0; + do { + privKey = crypto.randomBytes(32); + } while (!secp256k1.privateKeyVerify(privKey)); + return privKey; } - }); + }, { + key: 'generatePublic', + value: function generatePublic(privKey) { + var pvt = Buffer.from(privKey, 'hex'); + this.prvt = pvt; + return secp256k1.publicKeyCreate(pvt); + } + }, { + key: 'encrypt', + value: function encrypt(dataToSend) { + var publicKeyA = eccrypto.getPublic(this.prvt); + return new Promise(function (resolve, reject) { + eccrypto.encrypt(publicKeyA, Buffer.from(dataToSend)).then(function (_initial) { + resolve(_initial); + }).catch(function (error) { + reject(error); + }); + }); + } + }, { + key: 'decrypt', + value: function decrypt(dataToSee) { + var _this = this; - function splitClassesToLookup(classes) { - if (isString(classes)) { - classes = classes.split(' '); + return new Promise(function (resolve, reject) { + eccrypto.decrypt(_this.prvt, { + ciphertext: Buffer.from(dataToSee.ciphertext), + ephemPublicKey: Buffer.from(dataToSee.ephemPublicKey), + iv: Buffer.from(dataToSee.iv), + mac: Buffer.from(dataToSee.mac) + }).then(function (_initial) { + var result = void 0; + try { + if (_this.isJSON(_initial)) { + var humanRadable = JSON.parse(_initial); + if (Array.isArray(humanRadable)) { + result = humanRadable[0]; + } else { + result = humanRadable; + } + } else { + result = _initial.toString(); + } + } catch (e) { + logger$1.error(e); + } + resolve(JSON.stringify(result)); + }).catch(function (error) { + reject(error); + }); + }); } + }, { + key: 'signMessage', + value: function signMessage(msgToSign) { + var _this2 = this; - var obj = {}; - forEach(classes, function(klass) { - // sometimes the split leaves empty string values - // incase extra spaces were applied to the options - if (klass.length) { - obj[klass] = true; + return new Promise(function (resolve, reject) { + try { + var msg = ethUtils.hashPersonalMessage(ethUtils.toBuffer(msgToSign)); + var signed = ethUtils.ecsign(Buffer.from(msg), Buffer.from(_this2.prvt, 'hex')); + var combined = Buffer.concat([Buffer.from([signed.v]), Buffer.from(signed.r), Buffer.from(signed.s)]); + var combinedHex = combined.toString('hex'); + resolve(combinedHex); + } catch (e) { + reject(e); + } + }); + } + }, { + key: 'bufferToConnId', + value: function bufferToConnId(buf) { + return buf.toString('hex').slice(32); + } + }, { + key: 'isJSON', + value: function isJSON(arg) { + try { + JSON.parse(arg); + return true; + } catch (e) { + return false; } - }); - return obj; - } + } + }], [{ + key: 'create', + value: function create() { + return new MewConnectCrypto(); + } + }]); + return MewConnectCrypto; +}(); - return classes; -} +var debug = debugLogger('MEWconnect:initiator'); -function getDomNode(element) { - return (element instanceof jqLite) ? element[0] : element; -} +var logger$2 = createLogger('MewConnectInitiator'); -function applyGeneratedPreparationClasses($$jqLite, element, event, options) { - var classes = ''; - if (event) { - classes = pendClasses(event, EVENT_CLASS_PREFIX, true); - } - if (options.addClass) { - classes = concatWithSpace(classes, pendClasses(options.addClass, ADD_CLASS_SUFFIX)); - } - if (options.removeClass) { - classes = concatWithSpace(classes, pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX)); - } - if (classes.length) { - options.preparationClasses = classes; - element.addClass(classes); - } -} +var MewConnectInitiator = function (_MewConnectCommon) { + inherits(MewConnectInitiator, _MewConnectCommon); -function clearGeneratedClasses(element, options) { - if (options.preparationClasses) { - element.removeClass(options.preparationClasses); - options.preparationClasses = null; - } - if (options.activeClasses) { - element.removeClass(options.activeClasses); - options.activeClasses = null; - } -} + function MewConnectInitiator() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + classCallCheck(this, MewConnectInitiator); -function blockTransitions(node, duration) { - // we use a negative delay value since it performs blocking - // yet it doesn't kill any existing transitions running on the - // same element which makes this safe for class-based animations - var value = duration ? '-' + duration + 's' : ''; - applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]); - return [TRANSITION_DELAY_PROP, value]; -} + var _this = possibleConstructorReturn(this, (MewConnectInitiator.__proto__ || Object.getPrototypeOf(MewConnectInitiator)).call(this)); -function blockKeyframeAnimations(node, applyBlock) { - var value = applyBlock ? 'paused' : ''; - var key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY; - applyInlineStyle(node, [key, value]); - return [key, value]; -} + _this.supportedBrowser = MewConnectCommon.checkBrowser(); -function applyInlineStyle(node, styleTuple) { - var prop = styleTuple[0]; - var value = styleTuple[1]; - node.style[prop] = value; -} + _this.destroyOnUnload(); + _this.p = null; + _this.socketConnected = false; + _this.connected = false; + _this.tryingTurn = false; + _this.turnDisabled = false; + _this.signalUrl = null; + _this.iceState = ''; + _this.turnServers = []; -function concatWithSpace(a,b) { - if (!a) return b; - if (!b) return a; - return a + ' ' + b; -} + _this.io = options.io || io; + _this.Peer = options.wrtc || SimplePeer; + _this.mewCrypto = options.cryptoImpl || MewConnectCrypto.create(); -var $$rAFSchedulerFactory = ['$$rAF', function($$rAF) { - var queue, cancelFn; + _this.signals = _this.jsonDetails.signals; + _this.rtcEvents = _this.jsonDetails.rtc; + _this.version = _this.jsonDetails.version; + _this.versions = _this.jsonDetails.versions; + _this.lifeCycle = _this.jsonDetails.lifeCycle; + _this.stunServers = _this.jsonDetails.stunSrvers; + _this.iceStates = _this.jsonDetails.iceConnectionState; - function scheduler(tasks) { - // we make a copy since RAFScheduler mutates the state - // of the passed in array variable and this would be difficult - // to track down on the outside code - queue = queue.concat(tasks); - nextTick(); + // Socket is abandoned. disconnect. + setTimeout(function () { + if (_this.socket) { + _this.socketDisconnect(); + } + }, 120000); + return _this; } - queue = scheduler.queue = []; - - /* waitUntilQuiet does two things: - * 1. It will run the FINAL `fn` value only when an uncanceled RAF has passed through - * 2. It will delay the next wave of tasks from running until the quiet `fn` has run. - * - * The motivation here is that animation code can request more time from the scheduler - * before the next wave runs. This allows for certain DOM properties such as classes to - * be resolved in time for the next animation to run. - */ - scheduler.waitUntilQuiet = function(fn) { - if (cancelFn) cancelFn(); + // Factory function to create instance using default supplied libraries - cancelFn = $$rAF(function() { - cancelFn = null; - fn(); - nextTick(); - }); - }; - return scheduler; + createClass(MewConnectInitiator, [{ + key: 'destroyOnUnload', - function nextTick() { - if (!queue.length) return; - var items = queue.shift(); - for (var i = 0; i < items.length; i++) { - items[i](); - } + // Check if a WebRTC connection exists before a window/tab is closed or refreshed + // Destroy the connection if one exists + value: function destroyOnUnload() { + var _this2 = this; - if (!cancelFn) { - $$rAF(function() { - if (!cancelFn) nextTick(); - }); + if (browserOrNode.isBrowser) { + // eslint-disable-next-line no-undef + window.onunload = window.onbeforeunload = function () { + var iceStates = [_this2.iceStates.new, _this2.iceStates.connecting, _this2.iceStates.connected]; + if (!_this2.Peer.destroyed || iceStates.includes(_this2.iceState)) { + _this2.rtcDestroy(); + } + }; + } } - } -}]; - -/** - * @ngdoc directive - * @name ngAnimateChildren - * @restrict AE - * @element ANY - * - * @description - * - * ngAnimateChildren allows you to specify that children of this element should animate even if any - * of the children's parents are currently animating. By default, when an element has an active `enter`, `leave`, or `move` - * (structural) animation, child elements that also have an active structural animation are not animated. - * - * Note that even if `ngAnimateChildren` is set, no child animations will run when the parent element is removed from the DOM (`leave` animation). - * - * - * @param {string} ngAnimateChildren If the value is empty, `true` or `on`, - * then child animations are allowed. If the value is `false`, child animations are not allowed. - * - * @example - * - -
- - -
-
-
- List of items: -
Item {{item}}
-
-
-
-
- + }, { + key: 'getSocketConnectionState', - .container.ng-enter, - .container.ng-leave { - transition: all ease 1.5s; - } - .container.ng-enter, - .container.ng-leave-active { - opacity: 0; - } + // Returns a boolean indicating whether the socket connection exists and is active + value: function getSocketConnectionState() { + return this.socketConnected; + } - .container.ng-leave, - .container.ng-enter-active { - opacity: 1; - } + // Returns a boolean indicating whether the WebRTC connection exists and is active - .item { - background: firebrick; - color: #FFF; - margin-bottom: 10px; - } + }, { + key: 'getConnectonState', + value: function getConnectonState() { + return this.connected; + } - .item.ng-enter, - .item.ng-leave { - transition: transform 1.5s ease; - } + // can be used to listen to specific events, especially those that pass data - .item.ng-enter { - transform: translateX(50px); - } + }, { + key: 'uiCommunicator', + value: function uiCommunicator(event, data) { + this.emit(event, data); + this.emitStatus(event); + } - .item.ng-enter-active { - transform: translateX(0); - } - - - angular.module('ngAnimateChildren', ['ngAnimate']) - .controller('MainController', function MainController() { - this.animateChildren = false; - this.enterElement = false; - }); - -
- */ -var $$AnimateChildrenDirective = ['$interpolate', function($interpolate) { - return { - link: function(scope, element, attrs) { - var val = attrs.ngAnimateChildren; - if (isString(val) && val.length === 0) { //empty attribute - element.data(NG_ANIMATE_CHILDREN_DATA, true); - } else { - // Interpolate and set the value, so that it is available to - // animations that run right after compilation - setData($interpolate(val)(scope)); - attrs.$observe('ngAnimateChildren', setData); - } + // special status emitter to allow simple listening of various statuses in one listener - function setData(value) { - value = value === 'on' || value === 'true'; - element.data(NG_ANIMATE_CHILDREN_DATA, value); - } + }, { + key: 'emitStatus', + value: function emitStatus(event) { + this.emit('status', event); } - }; -}]; -/* exported $AnimateCssProvider */ + // Emit/Provide the details used in creating the QR Code -var ANIMATE_TIMER_KEY = '$$animateCss'; + }, { + key: 'displayCode', + value: function displayCode(data) { + debug('handshake', data); + this.socketKey = data; + var separator = this.jsonDetails.connectionCodeSeparator; + var qrCodeString = this.version + separator + data + separator + this.connId; -/** - * @ngdoc service - * @name $animateCss - * @kind object - * - * @description - * The `$animateCss` service is a useful utility to trigger customized CSS-based transitions/keyframes - * from a JavaScript-based animation or directly from a directive. The purpose of `$animateCss` is NOT - * to side-step how `$animate` and ngAnimate work, but the goal is to allow pre-existing animations or - * directives to create more complex animations that can be purely driven using CSS code. - * - * Note that only browsers that support CSS transitions and/or keyframe animations are capable of - * rendering animations triggered via `$animateCss` (bad news for IE9 and lower). - * - * ## General Use - * Once again, `$animateCss` is designed to be used inside of a registered JavaScript animation that - * is powered by ngAnimate. It is possible to use `$animateCss` directly inside of a directive, however, - * any automatic control over cancelling animations and/or preventing animations from being run on - * child elements will not be handled by AngularJS. For this to work as expected, please use `$animate` to - * trigger the animation and then setup a JavaScript animation that injects `$animateCss` to trigger - * the CSS animation. - * - * The example below shows how we can create a folding animation on an element using `ng-if`: - * - * ```html - * - *
- * This element will go BOOM - *
- * - * ``` - * - * Now we create the **JavaScript animation** that will trigger the CSS transition: - * - * ```js - * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) { - * return { - * enter: function(element, doneFn) { - * var height = element[0].offsetHeight; - * return $animateCss(element, { - * from: { height:'0px' }, - * to: { height:height + 'px' }, - * duration: 1 // one second - * }); - * } - * } - * }]); - * ``` - * - * ## More Advanced Uses - * - * `$animateCss` is the underlying code that ngAnimate uses to power **CSS-based animations** behind the scenes. Therefore CSS hooks - * like `.ng-EVENT`, `.ng-EVENT-active`, `.ng-EVENT-stagger` are all features that can be triggered using `$animateCss` via JavaScript code. - * - * This also means that just about any combination of adding classes, removing classes, setting styles, dynamically setting a keyframe animation, - * applying a hardcoded duration or delay value, changing the animation easing or applying a stagger animation are all options that work with - * `$animateCss`. The service itself is smart enough to figure out the combination of options and examine the element styling properties in order - * to provide a working animation that will run in CSS. - * - * The example below showcases a more advanced version of the `.fold-animation` from the example above: - * - * ```js - * ngModule.animation('.fold-animation', ['$animateCss', function($animateCss) { - * return { - * enter: function(element, doneFn) { - * var height = element[0].offsetHeight; - * return $animateCss(element, { - * addClass: 'red large-text pulse-twice', - * easing: 'ease-out', - * from: { height:'0px' }, - * to: { height:height + 'px' }, - * duration: 1 // one second - * }); - * } - * } - * }]); - * ``` - * - * Since we're adding/removing CSS classes then the CSS transition will also pick those up: - * - * ```css - * /* since a hardcoded duration value of 1 was provided in the JavaScript animation code, - * the CSS classes below will be transitioned despite them being defined as regular CSS classes */ - * .red { background:red; } - * .large-text { font-size:20px; } - * - * /* we can also use a keyframe animation and $animateCss will make it work alongside the transition */ - * .pulse-twice { - * animation: 0.5s pulse linear 2; - * -webkit-animation: 0.5s pulse linear 2; - * } - * - * @keyframes pulse { - * from { transform: scale(0.5); } - * to { transform: scale(1.5); } - * } - * - * @-webkit-keyframes pulse { - * from { -webkit-transform: scale(0.5); } - * to { -webkit-transform: scale(1.5); } - * } - * ``` - * - * Given this complex combination of CSS classes, styles and options, `$animateCss` will figure everything out and make the animation happen. - * - * ## How the Options are handled - * - * `$animateCss` is very versatile and intelligent when it comes to figuring out what configurations to apply to the element to ensure the animation - * works with the options provided. Say for example we were adding a class that contained a keyframe value and we wanted to also animate some inline - * styles using the `from` and `to` properties. - * - * ```js - * var animator = $animateCss(element, { - * from: { background:'red' }, - * to: { background:'blue' } - * }); - * animator.start(); - * ``` - * - * ```css - * .rotating-animation { - * animation:0.5s rotate linear; - * -webkit-animation:0.5s rotate linear; - * } - * - * @keyframes rotate { - * from { transform: rotate(0deg); } - * to { transform: rotate(360deg); } - * } - * - * @-webkit-keyframes rotate { - * from { -webkit-transform: rotate(0deg); } - * to { -webkit-transform: rotate(360deg); } - * } - * ``` - * - * The missing pieces here are that we do not have a transition set (within the CSS code nor within the `$animateCss` options) and the duration of the animation is - * going to be detected from what the keyframe styles on the CSS class are. In this event, `$animateCss` will automatically create an inline transition - * style matching the duration detected from the keyframe style (which is present in the CSS class that is being added) and then prepare both the transition - * and keyframe animations to run in parallel on the element. Then when the animation is underway the provided `from` and `to` CSS styles will be applied - * and spread across the transition and keyframe animation. - * - * ## What is returned - * - * `$animateCss` works in two stages: a preparation phase and an animation phase. Therefore when `$animateCss` is first called it will NOT actually - * start the animation. All that is going on here is that the element is being prepared for the animation (which means that the generated CSS classes are - * added and removed on the element). Once `$animateCss` is called it will return an object with the following properties: - * - * ```js - * var animator = $animateCss(element, { ... }); - * ``` - * - * Now what do the contents of our `animator` variable look like: - * - * ```js - * { - * // starts the animation - * start: Function, - * - * // ends (aborts) the animation - * end: Function - * } - * ``` - * - * To actually start the animation we need to run `animation.start()` which will then return a promise that we can hook into to detect when the animation ends. - * If we choose not to run the animation then we MUST run `animation.end()` to perform a cleanup on the element (since some CSS classes and styles may have been - * applied to the element during the preparation phase). Note that all other properties such as duration, delay, transitions and keyframes are just properties - * and that changing them will not reconfigure the parameters of the animation. - * - * ### runner.done() vs runner.then() - * It is documented that `animation.start()` will return a promise object and this is true, however, there is also an additional method available on the - * runner called `.done(callbackFn)`. The done method works the same as `.finally(callbackFn)`, however, it does **not trigger a digest to occur**. - * Therefore, for performance reasons, it's always best to use `runner.done(callback)` instead of `runner.then()`, `runner.catch()` or `runner.finally()` - * unless you really need a digest to kick off afterwards. - * - * Keep in mind that, to make this easier, ngAnimate has tweaked the JS animations API to recognize when a runner instance is returned from $animateCss - * (so there is no need to call `runner.done(doneFn)` inside of your JavaScript animation code). - * Check the {@link ngAnimate.$animateCss#usage animation code above} to see how this works. - * - * @param {DOMElement} element the element that will be animated - * @param {object} options the animation-related options that will be applied during the animation - * - * * `event` - The DOM event (e.g. enter, leave, move). When used, a generated CSS class of `ng-EVENT` and `ng-EVENT-active` will be applied - * to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.) - * * `structural` - Indicates that the `ng-` prefix will be added to the event class. Setting to `false` or omitting will turn `ng-EVENT` and - * `ng-EVENT-active` in `EVENT` and `EVENT-active`. Unused if `event` is omitted. - * * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both). - * * `transitionStyle` - The raw CSS transition style that will be used (e.g. `1s linear all`). - * * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`). - * * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation. - * * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition. - * * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation. - * * `removeClass` - A space separated list of CSS classes that will be removed from the element and spread across the animation. - * * `duration` - A number value representing the total duration of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `0` - * is provided then the animation will be skipped entirely. - * * `delay` - A number value representing the total delay of the transition and/or keyframe (note that a value of 1 is 1000ms). If a value of `true` is - * used then whatever delay value is detected from the CSS classes will be mirrored on the elements styles (e.g. by setting delay true then the style value - * of the element will be `transition-delay: DETECTED_VALUE`). Using `true` is useful when you want the CSS classes and inline styles to all share the same - * CSS delay value. - * * `stagger` - A numeric time value representing the delay between successively animated elements - * ({@link ngAnimate#css-staggering-animations Click here to learn how CSS-based staggering works in ngAnimate.}) - * * `staggerIndex` - The numeric index representing the stagger item (e.g. a value of 5 is equal to the sixth item in the stagger; therefore when a - * `stagger` option value of `0.1` is used then there will be a stagger delay of `600ms`) - * * `applyClassesEarly` - Whether or not the classes being added or removed will be used when detecting the animation. This is set by `$animate` when enter/leave/move animations are fired to ensure that the CSS classes are resolved in time. (Note that this will prevent any transitions from occurring on the classes being added and removed.) - * * `cleanupStyles` - Whether or not the provided `from` and `to` styles will be removed once - * the animation is closed. This is useful for when the styles are used purely for the sake of - * the animation and do not have a lasting visual effect on the element (e.g. a collapse and open animation). - * By default this value is set to `false`. - * - * @return {object} an object with start and end methods and details about the animation. - * - * * `start` - The method to start the animation. This will return a `Promise` when called. - * * `end` - This method will cancel the animation and remove all applied CSS classes and styles. - */ -var ONE_SECOND = 1000; + this.uiCommunicator(this.lifeCycle.codeDisplay, qrCodeString); + this.uiCommunicator(this.lifeCycle.checkNumber, data); + this.uiCommunicator(this.lifeCycle.ConnectionId, this.connId); + } -var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3; -var CLOSING_TIME_BUFFER = 1.5; + // ===================== [Start] WebSocket Communication Methods and Handlers ======================== -var DETECT_CSS_PROPERTIES = { - transitionDuration: TRANSITION_DURATION_PROP, - transitionDelay: TRANSITION_DELAY_PROP, - transitionProperty: TRANSITION_PROP + PROPERTY_KEY, - animationDuration: ANIMATION_DURATION_PROP, - animationDelay: ANIMATION_DELAY_PROP, - animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY -}; + // The initial method called to initiate the exchange that can create a WebRTC connection -var DETECT_STAGGER_CSS_PROPERTIES = { - transitionDuration: TRANSITION_DURATION_PROP, - transitionDelay: TRANSITION_DELAY_PROP, - animationDuration: ANIMATION_DURATION_PROP, - animationDelay: ANIMATION_DELAY_PROP -}; + }, { + key: 'regenerateCode', + value: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(this.signalUrl === null)) { + _context.next = 2; + break; + } -function getCssKeyframeDurationStyle(duration) { - return [ANIMATION_DURATION_PROP, duration + 's']; -} + throw Error('regenerateCode called before initial code generation'); -function getCssDelayStyle(delay, isKeyframeAnimation) { - var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP; - return [prop, delay + 's']; -} + case 2: + this.socketDisconnect(); + this.initiatorStart(this.signalUrl); -function computeCssStyles($window, element, properties) { - var styles = Object.create(null); - var detectedStyles = $window.getComputedStyle(element) || {}; - forEach(properties, function(formalStyleName, actualStyleName) { - var val = detectedStyles[formalStyleName]; - if (val) { - var c = val.charAt(0); + case 4: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); - // only numerical-based values have a negative sign or digit as the first value - if (c === '-' || c === '+' || c >= 0) { - val = parseMaxTime(val); + function regenerateCode() { + return _ref.apply(this, arguments); } - // by setting this to null in the event that the delay is not set or is set directly as 0 - // then we can still allow for negative values to be used later on and not mistake this - // value for being greater than any other negative value. - if (val === 0) { - val = null; - } - styles[actualStyleName] = val; - } - }); + return regenerateCode; + }() + }, { + key: 'useFallback', + value: function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() { + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + this.socketEmit(this.signals.tryTurn, { connId: this.connId }); - return styles; -} + case 1: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); -function parseMaxTime(str) { - var maxValue = 0; - var values = str.split(/\s*,\s*/); - forEach(values, function(value) { - // it's always safe to consider only second values and omit `ms` values since - // getComputedStyle will always handle the conversion for us - if (value.charAt(value.length - 1) === 's') { - value = value.substring(0, value.length - 1); - } - value = parseFloat(value) || 0; - maxValue = maxValue ? Math.max(value, maxValue) : value; - }); - return maxValue; -} + function useFallback() { + return _ref2.apply(this, arguments); + } -function truthyTimingValue(val) { - return val === 0 || val != null; -} + return useFallback; + }() -function getCssTransitionDurationStyle(duration, applyOnlyDuration) { - var style = TRANSITION_PROP; - var value = duration + 's'; - if (applyOnlyDuration) { - style += DURATION_KEY; - } else { - value += ' linear all'; - } - return [style, value]; -} + // Initalize a websocket connection with the signal server -// we do not reassign an already present style value since -// if we detect the style property value again we may be -// detecting styles that were added via the `from` styles. -// We make use of `isDefined` here since an empty string -// or null value (which is what getPropertyValue will return -// for a non-existing style) will still be marked as a valid -// value for the style (a falsy value implies that the style -// is to be removed at the end of the animation). If we had a simple -// "OR" statement then it would not be enough to catch that. -function registerRestorableStyles(backup, node, properties) { - forEach(properties, function(prop) { - backup[prop] = isDefined(backup[prop]) - ? backup[prop] - : node.style.getPropertyValue(prop); - }); -} + }, { + key: 'initiatorStart', + value: function () { + var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(url) { + var toSign, options; + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (this.signalUrl === null) { + this.signalUrl = url; + } + this.keys = this.mewCrypto.prepareKey(); + toSign = this.mewCrypto.generateMessage(); + _context3.next = 5; + return this.mewCrypto.signMessage(this.keys.pvt.toString('hex')); -var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animateProvider) { + case 5: + this.signed = _context3.sent; - this.$get = ['$window', '$$jqLite', '$$AnimateRunner', '$timeout', '$$animateCache', - '$$forceReflow', '$sniffer', '$$rAFScheduler', '$$animateQueue', - function($window, $$jqLite, $$AnimateRunner, $timeout, $$animateCache, - $$forceReflow, $sniffer, $$rAFScheduler, $$animateQueue) { + this.connId = this.mewCrypto.bufferToConnId(this.keys.pub); + this.displayCode(this.keys.pvt.toString('hex')); + this.uiCommunicator(this.lifeCycle.signatureCheck); + options = { + query: { + stage: 'initiator', + signed: this.signed, + message: toSign, + connId: this.connId + }, + transports: ['websocket', 'polling', 'flashsocket'], + secure: true + }; - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + this.socketManager = this.io(url, options); + this.socket = this.socketManager.connect(); + this.initiatorConnect(this.socket); - function computeCachedCssStyles(node, className, cacheKey, allowNoDuration, properties) { - var timings = $$animateCache.get(cacheKey); + case 13: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + })); - if (!timings) { - timings = computeCssStyles($window, node, properties); - if (timings.animationIterationCount === 'infinite') { - timings.animationIterationCount = 1; - } + function initiatorStart(_x2) { + return _ref3.apply(this, arguments); } - // if a css animation has no duration we - // should mark that so that repeated addClass/removeClass calls are skipped - var hasDuration = allowNoDuration || (timings.transitionDuration > 0 || timings.animationDuration > 0); + return initiatorStart; + }() - // we keep putting this in multiple times even though the value and the cacheKey are the same - // because we're keeping an internal tally of how many duplicate animations are detected. - $$animateCache.put(cacheKey, timings, hasDuration); + // ------------- WebSocket Communication Methods and Handlers ------------------------------ - return timings; + // ----- Wrapper around Socket.IO methods + // socket.emit wrapper + + }, { + key: 'socketEmit', + value: function socketEmit(signal, data) { + this.socket.binary(false).emit(signal, data); } - function computeCachedCssStaggerStyles(node, className, cacheKey, properties) { - var stagger; - var staggerCacheKey = 'stagger-' + cacheKey; + // socket.disconnect wrapper - // if we have one or more existing matches of matching elements - // containing the same parent + CSS styles (which is how cacheKey works) - // then staggering is possible - if ($$animateCache.count(cacheKey) > 0) { - stagger = $$animateCache.get(staggerCacheKey); + }, { + key: 'socketDisconnect', + value: function socketDisconnect() { + this.socket.disconnect(); + this.socketConnected = false; + } - if (!stagger) { - var staggerClassName = pendClasses(className, '-stagger'); + // socket.on listener registration wrapper - $$jqLite.addClass(node, staggerClassName); + }, { + key: 'socketOn', + value: function socketOn(signal, func) { + this.socket.on(signal, func); + } - stagger = computeCssStyles($window, node, properties); + // ----- Setup handlers for communication with the signal server - // force the conversion of a null value to zero incase not set - stagger.animationDuration = Math.max(stagger.animationDuration, 0); - stagger.transitionDuration = Math.max(stagger.transitionDuration, 0); + }, { + key: 'initiatorConnect', + value: function initiatorConnect(socket) { + var _this3 = this; - $$jqLite.removeClass(node, staggerClassName); + debug('INITIATOR CONNECT'); + this.uiCommunicator(this.lifeCycle.SocketConnectedEvent); - $$animateCache.put(staggerCacheKey, stagger, true); - } - } + this.socket.on(this.signals.connect, function () { + debug('SOCKET CONNECTED'); + _this3.socketConnected = true; + }); - return stagger || {}; + this.socketOn(this.signals.confirmation, this.sendOffer.bind(this)); // response + this.socketOn(this.signals.answer, this.recieveAnswer.bind(this)); + this.socketOn(this.signals.confirmationFailedBusy, this.busyFailure.bind(this)); + this.socketOn(this.signals.confirmationFailed, this.confirmationFailure.bind(this)); + this.socketOn(this.signals.invalidConnection, this.invalidFailure.bind(this)); + this.socketOn(this.signals.disconnect, this.socketDisconnectHandler.bind(this)); + this.socketOn(this.signals.attemptingTurn, this.willAttemptTurn.bind(this)); + this.socketOn(this.signals.turnToken, this.beginTurn.bind(this)); + return socket; } - var rafWaitQueue = []; - function waitUntilQuiet(callback) { - rafWaitQueue.push(callback); - $$rAFScheduler.waitUntilQuiet(function() { - $$animateCache.flush(); + // ----- Socket Event handlers - // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable. - // PLEASE EXAMINE THE `$$forceReflow` service to understand why. - var pageWidth = $$forceReflow(); + // Handle Socket Disconnect Event - // we use a for loop to ensure that if the queue is changed - // during this looping then it will consider new requests - for (var i = 0; i < rafWaitQueue.length; i++) { - rafWaitQueue[i](pageWidth); - } - rafWaitQueue.length = 0; - }); + }, { + key: 'socketDisconnectHandler', + value: function socketDisconnectHandler(reason) { + debug(reason); + this.socketConnected = false; } - function computeTimings(node, className, cacheKey, allowNoDuration) { - var timings = computeCachedCssStyles(node, className, cacheKey, allowNoDuration, DETECT_CSS_PROPERTIES); - var aD = timings.animationDelay; - var tD = timings.transitionDelay; - timings.maxDelay = aD && tD - ? Math.max(aD, tD) - : (aD || tD); - timings.maxDuration = Math.max( - timings.animationDuration * timings.animationIterationCount, - timings.transitionDuration); + // Handle Socket Attempting Turn informative signal + // Provide Notice that initial WebRTC connection failed and the fallback method will be used - return timings; + }, { + key: 'willAttemptTurn', + value: function willAttemptTurn() { + this.tryingTurn = true; + debug('TRY TURN CONNECTION'); + this.uiCommunicator(this.lifeCycle.UsingFallback); } - return function init(element, initialOptions) { - // all of the animation functions should create - // a copy of the options data, however, if a - // parent service has already created a copy then - // we should stick to using that - var options = initialOptions || {}; - if (!options.$$prepared) { - options = prepareAnimationOptions(copy(options)); - } - - var restoreStyles = {}; - var node = getDomNode(element); - if (!node - || !node.parentNode - || !$$animateQueue.enabled()) { - return closeAndReturnNoopAnimator(); - } + // Handle Socket event to initiate turn connection + // Handle Receipt of TURN server details, and begin a WebRTC connection attempt using TURN - var temporaryStyles = []; - var classes = element.attr('class'); - var styles = packageStyles(options); - var animationClosed; - var animationPaused; - var animationCompleted; - var runner; - var runnerHost; - var maxDelay; - var maxDelayTime; - var maxDuration; - var maxDurationTime; - var startTime; - var events = []; + }, { + key: 'beginTurn', + value: function beginTurn(data) { + this.tryingTurn = true; + this.retryViaTurn(data); + } - if (options.duration === 0 || (!$sniffer.animations && !$sniffer.transitions)) { - return closeAndReturnNoopAnimator(); - } + // ----- Failure Handlers - var method = options.event && isArray(options.event) - ? options.event.join(' ') - : options.event; + // Handle Failure due to an attempt to join a connection with two existing endpoints - var isStructural = method && options.structural; - var structuralClassName = ''; - var addRemoveClassName = ''; + }, { + key: 'busyFailure', + value: function busyFailure() { + this.uiCommunicator(this.lifeCycle.Failed, this.lifeCycle.confirmationFailedBusyEvent); + debug('confirmation Failed: Busy'); + } - if (isStructural) { - structuralClassName = pendClasses(method, EVENT_CLASS_PREFIX, true); - } else if (method) { - structuralClassName = method; - } + // Handle Failure due to no opposing peer existing - if (options.addClass) { - addRemoveClassName += pendClasses(options.addClass, ADD_CLASS_SUFFIX); - } + }, { + key: 'invalidFailure', + value: function invalidFailure() { + this.uiCommunicator(this.lifeCycle.Failed, this.lifeCycle.invalidConnectionEvent); + debug('confirmation Failed: no opposite peer found'); + } - if (options.removeClass) { - if (addRemoveClassName.length) { - addRemoveClassName += ' '; - } - addRemoveClassName += pendClasses(options.removeClass, REMOVE_CLASS_SUFFIX); - } + // Handle Failure due to the handshake/ verify details being invalid for the connection ID - // there may be a situation where a structural animation is combined together - // with CSS classes that need to resolve before the animation is computed. - // However this means that there is no explicit CSS code to block the animation - // from happening (by setting 0s none in the class name). If this is the case - // we need to apply the classes before the first rAF so we know to continue if - // there actually is a detected transition or keyframe animation - if (options.applyClassesEarly && addRemoveClassName.length) { - applyAnimationClasses(element, options); - } + }, { + key: 'confirmationFailure', + value: function confirmationFailure() { + this.uiCommunicator(this.lifeCycle.Failed, this.lifeCycle.confirmationFailedEvent); + debug('confirmation Failed: invalid confirmation'); + } - var preparationClasses = [structuralClassName, addRemoveClassName].join(' ').trim(); - var fullClassName = classes + ' ' + preparationClasses; - var hasToStyles = styles.to && Object.keys(styles.to).length > 0; - var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0; + // =============== [End] WebSocket Communication Methods and Handlers ======================== - // there is no way we can trigger an animation if no styles and - // no classes are being applied which would then trigger a transition, - // unless there a is raw keyframe value that is applied to the element. - if (!containsKeyframeAnimation - && !hasToStyles - && !preparationClasses) { - return closeAndReturnNoopAnimator(); - } + // ======================== [Start] WebRTC Communication Methods ============================= - var stagger, cacheKey = $$animateCache.cacheKey(node, method, options.addClass, options.removeClass); - if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) { - preparationClasses = null; - return closeAndReturnNoopAnimator(); - } + // ----- WebRTC Setup Methods - if (options.stagger > 0) { - var staggerVal = parseFloat(options.stagger); - stagger = { - transitionDelay: staggerVal, - animationDelay: staggerVal, - transitionDuration: 0, - animationDuration: 0 - }; - } else { - stagger = computeCachedCssStaggerStyles(node, preparationClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES); - } + // A connection pair exists, create and send WebRTC OFFER - if (!options.$$skipPreparationClasses) { - $$jqLite.addClass(element, preparationClasses); - } + }, { + key: 'sendOffer', + value: function () { + var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(data) { + var plainTextVersion, options; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return this.mewCrypto.decrypt(data.version); - var applyOnlyDuration; + case 2: + plainTextVersion = _context4.sent; - if (options.transitionStyle) { - var transitionStyle = [TRANSITION_PROP, options.transitionStyle]; - applyInlineStyle(node, transitionStyle); - temporaryStyles.push(transitionStyle); - } + this.peerVersion = plainTextVersion; + this.uiCommunicator(this.lifeCycle.receiverVersion, plainTextVersion); + debug('sendOffer', data); + options = { + signalListener: this.initiatorSignalListener, + webRtcConfig: { + servers: this.stunServers + } + }; - if (options.duration >= 0) { - applyOnlyDuration = node.style[TRANSITION_PROP].length > 0; - var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration); + this.initiatorStartRTC(this.socket, options); - // we set the duration so that it will be picked up by getComputedStyle later - applyInlineStyle(node, durationStyle); - temporaryStyles.push(durationStyle); - } + case 8: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + })); - if (options.keyframeStyle) { - var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle]; - applyInlineStyle(node, keyframeStyle); - temporaryStyles.push(keyframeStyle); + function sendOffer(_x3) { + return _ref4.apply(this, arguments); } - var itemIndex = stagger - ? options.staggerIndex >= 0 - ? options.staggerIndex - : $$animateCache.count(cacheKey) - : 0; + return sendOffer; + }() + }, { + key: 'initiatorSignalListener', + value: function initiatorSignalListener(socket, options) { + var _this4 = this; - var isFirst = itemIndex === 0; + return function () { + var _ref5 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(data) { + var encryptedSend; + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.prev = 0; - // this is a pre-emptive way of forcing the setup classes to be added and applied INSTANTLY - // without causing any combination of transitions to kick in. By adding a negative delay value - // it forces the setup class' transition to end immediately. We later then remove the negative - // transition delay to allow for the transition to naturally do it's thing. The beauty here is - // that if there is no transition defined then nothing will happen and this will also allow - // other transitions to be stacked on top of each other without any chopping them out. - if (isFirst && !options.skipBlocking) { - blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE); - } + debug('SIGNAL', JSON.stringify(data)); + _context5.next = 4; + return _this4.mewCrypto.encrypt(JSON.stringify(data)); - var timings = computeTimings(node, fullClassName, cacheKey, !isStructural); - var relativeDelay = timings.maxDelay; - maxDelay = Math.max(relativeDelay, 0); - maxDuration = timings.maxDuration; + case 4: + encryptedSend = _context5.sent; - var flags = {}; - flags.hasTransitions = timings.transitionDuration > 0; - flags.hasAnimations = timings.animationDuration > 0; - flags.hasTransitionAll = flags.hasTransitions && timings.transitionProperty === 'all'; - flags.applyTransitionDuration = hasToStyles && ( - (flags.hasTransitions && !flags.hasTransitionAll) - || (flags.hasAnimations && !flags.hasTransitions)); - flags.applyAnimationDuration = options.duration && flags.hasAnimations; - flags.applyTransitionDelay = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions); - flags.applyAnimationDelay = truthyTimingValue(options.delay) && flags.hasAnimations; - flags.recalculateTimingStyles = addRemoveClassName.length > 0; + _this4.uiCommunicator(_this4.lifeCycle.sendOffer); + _this4.socketEmit(_this4.signals.offerSignal, { + data: encryptedSend, + connId: _this4.connId, + options: options.servers + }); + _context5.next = 12; + break; - if (flags.applyTransitionDuration || flags.applyAnimationDuration) { - maxDuration = options.duration ? parseFloat(options.duration) : maxDuration; + case 9: + _context5.prev = 9; + _context5.t0 = _context5['catch'](0); - if (flags.applyTransitionDuration) { - flags.hasTransitions = true; - timings.transitionDuration = maxDuration; - applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0; - temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration)); - } + logger$2.error(_context5.t0); - if (flags.applyAnimationDuration) { - flags.hasAnimations = true; - timings.animationDuration = maxDuration; - temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration)); - } - } + case 12: + case 'end': + return _context5.stop(); + } + } + }, _callee5, _this4, [[0, 9]]); + })); - if (maxDuration === 0 && !flags.recalculateTimingStyles) { - return closeAndReturnNoopAnimator(); - } + return function (_x4) { + return _ref5.apply(this, arguments); + }; + }(); + } - var activeClasses = pendClasses(preparationClasses, ACTIVE_CLASS_SUFFIX); + // Handle the WebRTC ANSWER from the opposite (mobile) peer - if (options.delay != null) { - var delayStyle; - if (typeof options.delay !== 'boolean') { - delayStyle = parseFloat(options.delay); - // number in options.delay means we have to recalculate the delay for the closing timeout - maxDelay = Math.max(delayStyle, 0); - } + }, { + key: 'recieveAnswer', + value: function () { + var _ref6 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6(data) { + var plainTextOffer; + return regeneratorRuntime.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _context6.prev = 0; + _context6.next = 3; + return this.mewCrypto.decrypt(data.data); - if (flags.applyTransitionDelay) { - temporaryStyles.push(getCssDelayStyle(delayStyle)); - } + case 3: + plainTextOffer = _context6.sent; - if (flags.applyAnimationDelay) { - temporaryStyles.push(getCssDelayStyle(delayStyle, true)); - } - } + this.rtcRecieveAnswer({ data: plainTextOffer }); + _context6.next = 10; + break; - // we need to recalculate the delay value since we used a pre-emptive negative - // delay value and the delay value is required for the final event checking. This - // property will ensure that this will happen after the RAF phase has passed. - if (options.duration == null && timings.transitionDuration > 0) { - flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst; - } + case 7: + _context6.prev = 7; + _context6.t0 = _context6['catch'](0); - maxDelayTime = maxDelay * ONE_SECOND; - maxDurationTime = maxDuration * ONE_SECOND; - if (!options.skipBlocking) { - flags.blockTransition = timings.transitionDuration > 0; - flags.blockKeyframeAnimation = timings.animationDuration > 0 && - stagger.animationDelay > 0 && - stagger.animationDuration === 0; - } + logger$2.error(_context6.t0); - if (options.from) { - if (options.cleanupStyles) { - registerRestorableStyles(restoreStyles, node, Object.keys(options.from)); - } - applyAnimationFromStyles(element, options); - } + case 10: + case 'end': + return _context6.stop(); + } + } + }, _callee6, this, [[0, 7]]); + })); - if (flags.blockTransition || flags.blockKeyframeAnimation) { - applyBlocking(maxDuration); - } else if (!options.skipBlocking) { - blockTransitions(node, false); + function recieveAnswer(_x5) { + return _ref6.apply(this, arguments); } - // TODO(matsko): for 1.5 change this code to have an animator object for better debugging - return { - $$willAnimate: true, - end: endFn, - start: function() { - if (animationClosed) return; - - runnerHost = { - end: endFn, - cancel: cancelFn, - resume: null, //this will be set during the start() phase - pause: null - }; - - runner = new $$AnimateRunner(runnerHost); + return recieveAnswer; + }() + }, { + key: 'rtcRecieveAnswer', + value: function rtcRecieveAnswer(data) { + this.uiCommunicator(this.lifeCycle.answerReceived); + this.p.signal(JSON.parse(data.data)); + } + }, { + key: 'initiatorStartRTC', + value: function initiatorStartRTC(socket, options) { + var _this5 = this; - waitUntilQuiet(start); + var webRtcConfig = options.webRtcConfig || {}; + var signalListener = this.initiatorSignalListener(socket, webRtcConfig.servers); + var webRtcServers = webRtcConfig.servers || this.stunServers; - // we don't have access to pause/resume the animation - // since it hasn't run yet. AnimateRunner will therefore - // set noop functions for resume and pause and they will - // later be overridden once the animation is triggered - return runner; + var suppliedOptions = options.webRtcOptions || {}; + var defaultOptions = { + initiator: true, + trickle: false, + iceTransportPolicy: 'relay', + config: { + iceServers: webRtcServers } }; - function endFn() { - close(); - } - - function cancelFn() { - close(true); - } - - function close(rejected) { - // if the promise has been called already then we shouldn't close - // the animation again - if (animationClosed || (animationCompleted && animationPaused)) return; - animationClosed = true; - animationPaused = false; - - if (preparationClasses && !options.$$skipPreparationClasses) { - $$jqLite.removeClass(element, preparationClasses); + var simpleOptions = _extends({}, defaultOptions, { + suppliedOptions: suppliedOptions + }); + debug('initiatorStartRTC - options: ' + simpleOptions); + this.uiCommunicator(this.lifeCycle.RtcInitiatedEvent); + this.p = new this.Peer(simpleOptions); + this.p.on(this.rtcEvents.error, this.onError.bind(this)); + this.p.on(this.rtcEvents.connect, this.onConnect.bind(this)); + this.p.on(this.rtcEvents.close, this.onClose.bind(this)); + this.p.on(this.rtcEvents.data, this.onData.bind(this)); + this.p.on(this.rtcEvents.signal, signalListener.bind(this)); + this.p._pc.addEventListener('iceconnectionstatechange', function (evt) { + // eslint-disable-next-line no-undef + if (typeof jest === 'undefined') { + // included because target is not defined in jest + debug('iceConnectionState: ' + evt.target.iceConnectionState); + if (evt.target.iceConnectionState === 'connected' || evt.target.iceConnectionState === 'completed') { + if (!_this5.connected) { + _this5.connected = true; + _this5.uiCommunicator(_this5.lifeCycle.RtcConnectedEvent); + } + } } + }); + } - if (activeClasses) { - $$jqLite.removeClass(element, activeClasses); - } + // ----- WebRTC Communication Event Handlers - blockKeyframeAnimations(node, false); - blockTransitions(node, false); + }, { + key: 'onConnect', + value: function onConnect() { + debug('CONNECT', 'ok'); + this.connected = true; + this.turnDisabled = true; + this.socketEmit(this.signals.rtcConnected, this.socketKey); + this.socketDisconnect(); + this.uiCommunicator(this.lifeCycle.RtcConnectedEvent); + } + }, { + key: 'onData', + value: function () { + var _ref7 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(data) { + var decryptedData, parsed; + return regeneratorRuntime.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + debug('DATA RECEIVED', data.toString()); + _context7.prev = 1; + decryptedData = void 0; - forEach(temporaryStyles, function(entry) { - // There is only one way to remove inline style properties entirely from elements. - // By using `removeProperty` this works, but we need to convert camel-cased CSS - // styles down to hyphenated values. - node.style[entry[0]] = ''; - }); + if (!this.isJSON(data)) { + _context7.next = 9; + break; + } - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); + _context7.next = 6; + return this.mewCrypto.decrypt(JSON.parse(data.toString())); - if (Object.keys(restoreStyles).length) { - forEach(restoreStyles, function(value, prop) { - if (value) { - node.style.setProperty(prop, value); - } else { - node.style.removeProperty(prop); - } - }); - } + case 6: + decryptedData = _context7.sent; + _context7.next = 12; + break; - // the reason why we have this option is to allow a synchronous closing callback - // that is fired as SOON as the animation ends (when the CSS is removed) or if - // the animation never takes off at all. A good example is a leave animation since - // the element must be removed just after the animation is over or else the element - // will appear on screen for one animation frame causing an overbearing flicker. - if (options.onDone) { - options.onDone(); - } + case 9: + _context7.next = 11; + return this.mewCrypto.decrypt(JSON.parse(data.toString())); - if (events && events.length) { - // Remove the transitionend / animationend listener(s) - element.off(events.join(' '), onAnimationProgress); - } + case 11: + decryptedData = _context7.sent; - //Cancel the fallback closing timeout and remove the timer data - var animationTimerData = element.data(ANIMATE_TIMER_KEY); - if (animationTimerData) { - $timeout.cancel(animationTimerData[0].timer); - element.removeData(ANIMATE_TIMER_KEY); - } - - // if the preparation function fails then the promise is not setup - if (runner) { - runner.complete(!rejected); - } - } + case 12: + if (this.isJSON(decryptedData)) { + parsed = JSON.parse(decryptedData); - function applyBlocking(duration) { - if (flags.blockTransition) { - blockTransitions(node, duration); - } + debug('DECRYPTED DATA RECEIVED', parsed); + this.emit(parsed.type, parsed.data); + } else { + debug('DECRYPTED DATA RECEIVED', decryptedData); + this.emit(decryptedData.type, decryptedData.data); + } + _context7.next = 20; + break; - if (flags.blockKeyframeAnimation) { - blockKeyframeAnimations(node, !!duration); - } - } + case 15: + _context7.prev = 15; + _context7.t0 = _context7['catch'](1); - function closeAndReturnNoopAnimator() { - runner = new $$AnimateRunner({ - end: endFn, - cancel: cancelFn - }); + logger$2.error(_context7.t0); + debug('onData ERROR: data=', data); + debug('onData ERROR: data.toString()=', data.toString()); - // should flush the cache animation - waitUntilQuiet(noop); - close(); + case 20: + case 'end': + return _context7.stop(); + } + } + }, _callee7, this, [[1, 15]]); + })); - return { - $$willAnimate: false, - start: function() { - return runner; - }, - end: endFn - }; + function onData(_x6) { + return _ref7.apply(this, arguments); } - function onAnimationProgress(event) { - event.stopPropagation(); - var ev = event.originalEvent || event; - - if (ev.target !== node) { - // Since TransitionEvent / AnimationEvent bubble up, - // we have to ignore events by finished child animations - return; - } + return onData; + }() + }, { + key: 'onClose', + value: function onClose(data) { + debug('WRTC CLOSE', data); + if (this.connected) { + this.connected = false; + this.uiCommunicator(this.lifeCycle.RtcClosedEvent); + } else { + this.connected = false; + } + } + }, { + key: 'onError', + value: function onError(err) { + debug(err.code); + debug('WRTC ERROR'); + debug('error', err); + if (!this.connected && !this.tryingTurn && !this.turnDisabled) { + this.useFallback(); + } else { + this.uiCommunicator(this.lifeCycle.RtcErrorEvent); + } + } - // we now always use `Date.now()` due to the recent changes with - // event.timeStamp in Firefox, Webkit and Chrome (see #13494 for more info) - var timeStamp = ev.$manualTimeStamp || Date.now(); + // ----- WebRTC Communication Methods - /* Firefox (or possibly just Gecko) likes to not round values up - * when a ms measurement is used for the animation */ - var elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)); + }, { + key: 'sendRtcMessageClosure', + value: function sendRtcMessageClosure(type, msg) { + var _this6 = this; - /* $manualTimeStamp is a mocked timeStamp value which is set - * within browserTrigger(). This is only here so that tests can - * mock animations properly. Real events fallback to event.timeStamp, - * or, if they don't, then a timeStamp is automatically created for them. - * We're checking to see if the timeStamp surpasses the expected delay, - * but we're using elapsedTime instead of the timeStamp on the 2nd - * pre-condition since animationPauseds sometimes close off early */ - if (Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration) { - // we set this flag to ensure that if the transition is paused then, when resumed, - // the animation will automatically close itself since transitions cannot be paused. - animationCompleted = true; - close(); - } - } + return function () { + debug('[SEND RTC MESSAGE Closure] type: ' + type + ', message: ' + msg); + _this6.rtcSend(JSON.stringify({ type: type, data: msg })); + }; + } + }, { + key: 'sendRtcMessage', + value: function sendRtcMessage(type, msg) { + debug('[SEND RTC MESSAGE] type: ' + type + ', message: ' + msg); + this.rtcSend(JSON.stringify({ type: type, data: msg })); + } + }, { + key: 'disconnectRTCClosure', + value: function disconnectRTCClosure() { + var _this7 = this; - function start() { - if (animationClosed) return; - if (!node.parentNode) { - close(); - return; - } + return function () { + debug('DISCONNECT RTC Closure'); + _this7.uiCommunicator(_this7.lifeCycle.RtcDisconnectEvent); + _this7.rtcDestroy(); + _this7.instance = null; + }; + } + }, { + key: 'disconnectRTC', + value: function disconnectRTC() { + debug('DISCONNECT RTC'); + this.uiCommunicator(this.lifeCycle.RtcDisconnectEvent); + this.rtcDestroy(); + this.instance = null; + } + }, { + key: 'rtcSend', + value: function () { + var _ref8 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(arg) { + var encryptedSend; + return regeneratorRuntime.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + if (!(this.p !== null)) { + _context8.next = 15; + break; + } - // even though we only pause keyframe animations here the pause flag - // will still happen when transitions are used. Only the transition will - // not be paused since that is not possible. If the animation ends when - // paused then it will not complete until unpaused or cancelled. - var playPause = function(playAnimation) { - if (!animationCompleted) { - animationPaused = !playAnimation; - if (timings.animationDuration) { - var value = blockKeyframeAnimations(node, animationPaused); - if (animationPaused) { - temporaryStyles.push(value); - } else { - removeFromArray(temporaryStyles, value); - } - } - } else if (animationPaused && playAnimation) { - animationPaused = false; - close(); - } - }; + encryptedSend = void 0; - // checking the stagger duration prevents an accidentally cascade of the CSS delay style - // being inherited from the parent. If the transition duration is zero then we can safely - // rely that the delay value is an intentional stagger delay style. - var maxStagger = itemIndex > 0 - && ((timings.transitionDuration && stagger.transitionDuration === 0) || - (timings.animationDuration && stagger.animationDuration === 0)) - && Math.max(stagger.animationDelay, stagger.transitionDelay); - if (maxStagger) { - $timeout(triggerAnimationStart, - Math.floor(maxStagger * itemIndex * ONE_SECOND), - false); - } else { - triggerAnimationStart(); - } + if (!(typeof arg === 'string')) { + _context8.next = 8; + break; + } - // this will decorate the existing promise runner with pause/resume methods - runnerHost.resume = function() { - playPause(true); - }; + _context8.next = 5; + return this.mewCrypto.encrypt(arg); - runnerHost.pause = function() { - playPause(false); - }; + case 5: + encryptedSend = _context8.sent; + _context8.next = 11; + break; - function triggerAnimationStart() { - // just incase a stagger animation kicks in when the animation - // itself was cancelled entirely - if (animationClosed) return; + case 8: + _context8.next = 10; + return this.mewCrypto.encrypt(JSON.stringify(arg)); - applyBlocking(false); + case 10: + encryptedSend = _context8.sent; - forEach(temporaryStyles, function(entry) { - var key = entry[0]; - var value = entry[1]; - node.style[key] = value; - }); + case 11: + debug('SENDING RTC'); + this.p.send(JSON.stringify(encryptedSend)); + _context8.next = 17; + break; - applyAnimationClasses(element, options); - $$jqLite.addClass(element, activeClasses); + case 15: + // eslint-disable-next-line + console.error('Attempted to send when no peer connection is connected'); + this.uiCommunicator(this.lifeCycle.attemptedDisconnectedSend); - if (flags.recalculateTimingStyles) { - fullClassName = node.getAttribute('class') + ' ' + preparationClasses; - cacheKey = $$animateCache.cacheKey(node, method, options.addClass, options.removeClass); + case 17: + case 'end': + return _context8.stop(); + } + } + }, _callee8, this); + })); - timings = computeTimings(node, fullClassName, cacheKey, false); - relativeDelay = timings.maxDelay; - maxDelay = Math.max(relativeDelay, 0); - maxDuration = timings.maxDuration; + function rtcSend(_x7) { + return _ref8.apply(this, arguments); + } - if (maxDuration === 0) { - close(); - return; - } + return rtcSend; + }() + }, { + key: 'rtcDestroy', + value: function rtcDestroy() { + if (this.p !== null) { + this.p.destroy(); + } + } - flags.hasTransitions = timings.transitionDuration > 0; - flags.hasAnimations = timings.animationDuration > 0; - } + // ----- WebRTC Communication TURN Fallback Initiator/Handler + // Fallback Step if initial webRTC connection attempt fails. + // Retries setting up the WebRTC connection using TURN - if (flags.applyAnimationDelay) { - relativeDelay = typeof options.delay !== 'boolean' && truthyTimingValue(options.delay) - ? parseFloat(options.delay) - : relativeDelay; + }, { + key: 'retryViaTurn', + value: function retryViaTurn(data) { + debug('Retrying via TURN'); + var options = { + signalListener: this.initiatorSignalListener, + webRtcConfig: { + servers: data.data + } + }; + this.initiatorStartRTC(this.socket, options); + } - maxDelay = Math.max(relativeDelay, 0); - timings.animationDelay = relativeDelay; - delayStyle = getCssDelayStyle(relativeDelay, true); - temporaryStyles.push(delayStyle); - node.style[delayStyle[0]] = delayStyle[1]; - } + // ======================== [End] WebRTC Communication Methods ============================= - maxDelayTime = maxDelay * ONE_SECOND; - maxDurationTime = maxDuration * ONE_SECOND; + }], [{ + key: 'init', + value: function init(opts) { + var options = opts !== null ? opts : {}; + return new MewConnectInitiator(options); + } + }, { + key: 'checkBrowser', + value: function checkBrowser() { + return MewConnectCommon.checkBrowser(); + } + }, { + key: 'checkWebRTCAvailable', + value: function checkWebRTCAvailable() { + return MewConnectCommon.checkWebRTCAvailable(); + } + }]); + return MewConnectInitiator; +}(MewConnectCommon); - if (options.easing) { - var easeProp, easeVal = options.easing; - if (flags.hasTransitions) { - easeProp = TRANSITION_PROP + TIMING_KEY; - temporaryStyles.push([easeProp, easeVal]); - node.style[easeProp] = easeVal; - } - if (flags.hasAnimations) { - easeProp = ANIMATION_PROP + TIMING_KEY; - temporaryStyles.push([easeProp, easeVal]); - node.style[easeProp] = easeVal; - } - } +// INITIATOR CLIENT - if (timings.transitionDuration) { - events.push(TRANSITIONEND_EVENT); - } +var index = { + Crypto: MewConnectCrypto, + Initiator: MewConnectInitiator +}; - if (timings.animationDuration) { - events.push(ANIMATIONEND_EVENT); - } +module.exports = index; - startTime = Date.now(); - var timerTime = maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime; - var endTime = startTime + timerTime; +}).call(this,require("buffer").Buffer) +},{"browser-or-node":183,"buffer":414,"crypto":840,"debug":191,"detect-browser":193,"eccrypto":194,"ethereumjs-util":225,"events":874,"logging":255,"secp256k1":278,"simple-peer":292,"socket.io-client":296,"webrtc-adapter":313}],175:[function(require,module,exports){ +module.exports = after - var animationsData = element.data(ANIMATE_TIMER_KEY) || []; - var setupFallbackTimer = true; - if (animationsData.length) { - var currentTimerData = animationsData[0]; - setupFallbackTimer = endTime > currentTimerData.expectedEndTime; - if (setupFallbackTimer) { - $timeout.cancel(currentTimerData.timer); - } else { - animationsData.push(close); - } - } +function after(count, callback, err_cb) { + var bail = false + err_cb = err_cb || noop + proxy.count = count - if (setupFallbackTimer) { - var timer = $timeout(onAnimationExpired, timerTime, false); - animationsData[0] = { - timer: timer, - expectedEndTime: endTime - }; - animationsData.push(close); - element.data(ANIMATE_TIMER_KEY, animationsData); - } + return (count === 0) ? callback() : proxy - if (events.length) { - element.on(events.join(' '), onAnimationProgress); - } + function proxy(err, result) { + if (proxy.count <= 0) { + throw new Error('after called too many times') + } + --proxy.count - if (options.to) { - if (options.cleanupStyles) { - registerRestorableStyles(restoreStyles, node, Object.keys(options.to)); - } - applyAnimationToStyles(element, options); - } + // after first error, rest are passed to err_cb + if (err) { + bail = true + callback(err) + // future error callbacks will go to error handler + callback = err_cb + } else if (proxy.count === 0 && !bail) { + callback(null, result) } + } +} - function onAnimationExpired() { - var animationsData = element.data(ANIMATE_TIMER_KEY); +function noop() {} - // this will be false in the event that the element was - // removed from the DOM (via a leave animation or something - // similar) - if (animationsData) { - for (var i = 1; i < animationsData.length; i++) { - animationsData[i](); - } - element.removeData(ANIMATE_TIMER_KEY); - } - } - } - }; - }]; -}]; +},{}],176:[function(require,module,exports){ +/** + * An abstraction for slicing an arraybuffer even when + * ArrayBuffer.prototype.slice is not supported + * + * @api public + */ -var $$AnimateCssDriverProvider = ['$$animationProvider', /** @this */ function($$animationProvider) { - $$animationProvider.drivers.push('$$animateCssDriver'); +module.exports = function(arraybuffer, start, end) { + var bytes = arraybuffer.byteLength; + start = start || 0; + end = end || bytes; - var NG_ANIMATE_SHIM_CLASS_NAME = 'ng-animate-shim'; - var NG_ANIMATE_ANCHOR_CLASS_NAME = 'ng-anchor'; + if (arraybuffer.slice) { return arraybuffer.slice(start, end); } - var NG_OUT_ANCHOR_CLASS_NAME = 'ng-anchor-out'; - var NG_IN_ANCHOR_CLASS_NAME = 'ng-anchor-in'; + if (start < 0) { start += bytes; } + if (end < 0) { end += bytes; } + if (end > bytes) { end = bytes; } - function isDocumentFragment(node) { - return node.parentNode && node.parentNode.nodeType === 11; + if (start >= bytes || start >= end || bytes === 0) { + return new ArrayBuffer(0); } - this.$get = ['$animateCss', '$rootScope', '$$AnimateRunner', '$rootElement', '$sniffer', '$$jqLite', '$document', - function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $sniffer, $$jqLite, $document) { + var abv = new Uint8Array(arraybuffer); + var result = new Uint8Array(end - start); + for (var i = start, ii = 0; i < end; i++, ii++) { + result[ii] = abv[i]; + } + return result.buffer; +}; - // only browsers that support these properties can render animations - if (!$sniffer.animations && !$sniffer.transitions) return noop; +},{}],177:[function(require,module,exports){ - var bodyNode = $document[0].body; - var rootNode = getDomNode($rootElement); +/** + * Expose `Backoff`. + */ - var rootBodyElement = jqLite( - // this is to avoid using something that exists outside of the body - // we also special case the doc fragment case because our unit test code - // appends the $rootElement to the body after the app has been bootstrapped - isDocumentFragment(rootNode) || bodyNode.contains(rootNode) ? rootNode : bodyNode - ); +module.exports = Backoff; - return function initDriverFn(animationDetails) { - return animationDetails.from && animationDetails.to - ? prepareFromToAnchorAnimation(animationDetails.from, - animationDetails.to, - animationDetails.classes, - animationDetails.anchors) - : prepareRegularAnimation(animationDetails); - }; +/** + * Initialize backoff timer with `opts`. + * + * - `min` initial timeout in milliseconds [100] + * - `max` max timeout [10000] + * - `jitter` [0] + * - `factor` [2] + * + * @param {Object} opts + * @api public + */ - function filterCssClasses(classes) { - //remove all the `ng-` stuff - return classes.replace(/\bng-\S+\b/g, ''); - } +function Backoff(opts) { + opts = opts || {}; + this.ms = opts.min || 100; + this.max = opts.max || 10000; + this.factor = opts.factor || 2; + this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; + this.attempts = 0; +} - function getUniqueValues(a, b) { - if (isString(a)) a = a.split(' '); - if (isString(b)) b = b.split(' '); - return a.filter(function(val) { - return b.indexOf(val) === -1; - }).join(' '); - } +/** + * Return the backoff duration. + * + * @return {Number} + * @api public + */ - function prepareAnchoredAnimation(classes, outAnchor, inAnchor) { - var clone = jqLite(getDomNode(outAnchor).cloneNode(true)); - var startingClasses = filterCssClasses(getClassVal(clone)); +Backoff.prototype.duration = function(){ + var ms = this.ms * Math.pow(this.factor, this.attempts++); + if (this.jitter) { + var rand = Math.random(); + var deviation = Math.floor(rand * this.jitter * ms); + ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; + } + return Math.min(ms, this.max) | 0; +}; - outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); - inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME); +/** + * Reset the number of attempts. + * + * @api public + */ - clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME); +Backoff.prototype.reset = function(){ + this.attempts = 0; +}; - rootBodyElement.append(clone); +/** + * Set the minimum duration + * + * @api public + */ - var animatorIn, animatorOut = prepareOutAnimation(); +Backoff.prototype.setMin = function(min){ + this.ms = min; +}; - // the user may not end up using the `out` animation and - // only making use of the `in` animation or vice-versa. - // In either case we should allow this and not assume the - // animation is over unless both animations are not used. - if (!animatorOut) { - animatorIn = prepareInAnimation(); - if (!animatorIn) { - return end(); - } - } +/** + * Set the maximum duration + * + * @api public + */ - var startingAnimator = animatorOut || animatorIn; +Backoff.prototype.setMax = function(max){ + this.max = max; +}; - return { - start: function() { - var runner; +/** + * Set the jitter + * + * @api public + */ - var currentAnimation = startingAnimator.start(); - currentAnimation.done(function() { - currentAnimation = null; - if (!animatorIn) { - animatorIn = prepareInAnimation(); - if (animatorIn) { - currentAnimation = animatorIn.start(); - currentAnimation.done(function() { - currentAnimation = null; - end(); - runner.complete(); - }); - return currentAnimation; - } - } - // in the event that there is no `in` animation - end(); - runner.complete(); - }); +Backoff.prototype.setJitter = function(jitter){ + this.jitter = jitter; +}; - runner = new $$AnimateRunner({ - end: endFn, - cancel: endFn - }); - return runner; +},{}],178:[function(require,module,exports){ +/* + * base64-arraybuffer + * https://github.com/niklasvh/base64-arraybuffer + * + * Copyright (c) 2012 Niklas von Hertzen + * Licensed under the MIT license. + */ +(function(){ + "use strict"; - function endFn() { - if (currentAnimation) { - currentAnimation.end(); - } - } - } - }; + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - function calculateAnchorStyles(anchor) { - var styles = {}; + // Use a lookup table to find the index. + var lookup = new Uint8Array(256); + for (var i = 0; i < chars.length; i++) { + lookup[chars.charCodeAt(i)] = i; + } - var coords = getDomNode(anchor).getBoundingClientRect(); + exports.encode = function(arraybuffer) { + var bytes = new Uint8Array(arraybuffer), + i, len = bytes.length, base64 = ""; - // we iterate directly since safari messes up and doesn't return - // all the keys for the coords object when iterated - forEach(['width','height','top','left'], function(key) { - var value = coords[key]; - switch (key) { - case 'top': - value += bodyNode.scrollTop; - break; - case 'left': - value += bodyNode.scrollLeft; - break; - } - styles[key] = Math.floor(value) + 'px'; - }); - return styles; - } + for (i = 0; i < len; i+=3) { + base64 += chars[bytes[i] >> 2]; + base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; + base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; + base64 += chars[bytes[i + 2] & 63]; + } - function prepareOutAnimation() { - var animator = $animateCss(clone, { - addClass: NG_OUT_ANCHOR_CLASS_NAME, - delay: true, - from: calculateAnchorStyles(outAnchor) - }); + if ((len % 3) === 2) { + base64 = base64.substring(0, base64.length - 1) + "="; + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + "=="; + } - // read the comment within `prepareRegularAnimation` to understand - // why this check is necessary - return animator.$$willAnimate ? animator : null; - } + return base64; + }; - function getClassVal(element) { - return element.attr('class') || ''; - } + exports.decode = function(base64) { + var bufferLength = base64.length * 0.75, + len = base64.length, i, p = 0, + encoded1, encoded2, encoded3, encoded4; - function prepareInAnimation() { - var endingClasses = filterCssClasses(getClassVal(inAnchor)); - var toAdd = getUniqueValues(endingClasses, startingClasses); - var toRemove = getUniqueValues(startingClasses, endingClasses); + if (base64[base64.length - 1] === "=") { + bufferLength--; + if (base64[base64.length - 2] === "=") { + bufferLength--; + } + } - var animator = $animateCss(clone, { - to: calculateAnchorStyles(inAnchor), - addClass: NG_IN_ANCHOR_CLASS_NAME + ' ' + toAdd, - removeClass: NG_OUT_ANCHOR_CLASS_NAME + ' ' + toRemove, - delay: true - }); + var arraybuffer = new ArrayBuffer(bufferLength), + bytes = new Uint8Array(arraybuffer); - // read the comment within `prepareRegularAnimation` to understand - // why this check is necessary - return animator.$$willAnimate ? animator : null; - } + for (i = 0; i < len; i+=4) { + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i+1)]; + encoded3 = lookup[base64.charCodeAt(i+2)]; + encoded4 = lookup[base64.charCodeAt(i+3)]; - function end() { - clone.remove(); - outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME); - inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME); - } + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); } - function prepareFromToAnchorAnimation(from, to, classes, anchors) { - var fromAnimation = prepareRegularAnimation(from, noop); - var toAnimation = prepareRegularAnimation(to, noop); + return arraybuffer; + }; +})(); - var anchorAnimations = []; - forEach(anchors, function(anchor) { - var outElement = anchor['out']; - var inElement = anchor['in']; - var animator = prepareAnchoredAnimation(classes, outElement, inElement); - if (animator) { - anchorAnimations.push(animator); - } - }); +},{}],179:[function(require,module,exports){ +// Reference https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki +// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] +// NOTE: SIGHASH byte ignored AND restricted, truncate before use - // no point in doing anything when there are no elements to animate - if (!fromAnimation && !toAnimation && anchorAnimations.length === 0) return; +var Buffer = require('safe-buffer').Buffer - return { - start: function() { - var animationRunners = []; +function check (buffer) { + if (buffer.length < 8) return false + if (buffer.length > 72) return false + if (buffer[0] !== 0x30) return false + if (buffer[1] !== buffer.length - 2) return false + if (buffer[2] !== 0x02) return false - if (fromAnimation) { - animationRunners.push(fromAnimation.start()); - } + var lenR = buffer[3] + if (lenR === 0) return false + if (5 + lenR >= buffer.length) return false + if (buffer[4 + lenR] !== 0x02) return false - if (toAnimation) { - animationRunners.push(toAnimation.start()); - } + var lenS = buffer[5 + lenR] + if (lenS === 0) return false + if ((6 + lenR + lenS) !== buffer.length) return false - forEach(anchorAnimations, function(animation) { - animationRunners.push(animation.start()); - }); + if (buffer[4] & 0x80) return false + if (lenR > 1 && (buffer[4] === 0x00) && !(buffer[5] & 0x80)) return false - var runner = new $$AnimateRunner({ - end: endFn, - cancel: endFn // CSS-driven animations cannot be cancelled, only ended - }); + if (buffer[lenR + 6] & 0x80) return false + if (lenS > 1 && (buffer[lenR + 6] === 0x00) && !(buffer[lenR + 7] & 0x80)) return false + return true +} - $$AnimateRunner.all(animationRunners, function(status) { - runner.complete(status); - }); +function decode (buffer) { + if (buffer.length < 8) throw new Error('DER sequence length is too short') + if (buffer.length > 72) throw new Error('DER sequence length is too long') + if (buffer[0] !== 0x30) throw new Error('Expected DER sequence') + if (buffer[1] !== buffer.length - 2) throw new Error('DER sequence length is invalid') + if (buffer[2] !== 0x02) throw new Error('Expected DER integer') - return runner; + var lenR = buffer[3] + if (lenR === 0) throw new Error('R length is zero') + if (5 + lenR >= buffer.length) throw new Error('R length is too long') + if (buffer[4 + lenR] !== 0x02) throw new Error('Expected DER integer (2)') - function endFn() { - forEach(animationRunners, function(runner) { - runner.end(); - }); - } - } - }; - } + var lenS = buffer[5 + lenR] + if (lenS === 0) throw new Error('S length is zero') + if ((6 + lenR + lenS) !== buffer.length) throw new Error('S length is invalid') - function prepareRegularAnimation(animationDetails) { - var element = animationDetails.element; - var options = animationDetails.options || {}; + if (buffer[4] & 0x80) throw new Error('R value is negative') + if (lenR > 1 && (buffer[4] === 0x00) && !(buffer[5] & 0x80)) throw new Error('R value excessively padded') - if (animationDetails.structural) { - options.event = animationDetails.event; - options.structural = true; - options.applyClassesEarly = true; + if (buffer[lenR + 6] & 0x80) throw new Error('S value is negative') + if (lenS > 1 && (buffer[lenR + 6] === 0x00) && !(buffer[lenR + 7] & 0x80)) throw new Error('S value excessively padded') - // we special case the leave animation since we want to ensure that - // the element is removed as soon as the animation is over. Otherwise - // a flicker might appear or the element may not be removed at all - if (animationDetails.event === 'leave') { - options.onDone = options.domOperation; - } - } + // non-BIP66 - extract R, S values + return { + r: buffer.slice(4, 4 + lenR), + s: buffer.slice(6 + lenR) + } +} - // We assign the preparationClasses as the actual animation event since - // the internals of $animateCss will just suffix the event token values - // with `-active` to trigger the animation. - if (options.preparationClasses) { - options.event = concatWithSpace(options.event, options.preparationClasses); - } +/* + * Expects r and s to be positive DER integers. + * + * The DER format uses the most significant bit as a sign bit (& 0x80). + * If the significant bit is set AND the integer is positive, a 0x00 is prepended. + * + * Examples: + * + * 0 => 0x00 + * 1 => 0x01 + * -1 => 0xff + * 127 => 0x7f + * -127 => 0x81 + * 128 => 0x0080 + * -128 => 0x80 + * 255 => 0x00ff + * -255 => 0xff01 + * 16300 => 0x3fac + * -16300 => 0xc054 + * 62300 => 0x00f35c + * -62300 => 0xff0ca4 +*/ +function encode (r, s) { + var lenR = r.length + var lenS = s.length + if (lenR === 0) throw new Error('R length is zero') + if (lenS === 0) throw new Error('S length is zero') + if (lenR > 33) throw new Error('R length is too long') + if (lenS > 33) throw new Error('S length is too long') + if (r[0] & 0x80) throw new Error('R value is negative') + if (s[0] & 0x80) throw new Error('S value is negative') + if (lenR > 1 && (r[0] === 0x00) && !(r[1] & 0x80)) throw new Error('R value excessively padded') + if (lenS > 1 && (s[0] === 0x00) && !(s[1] & 0x80)) throw new Error('S value excessively padded') - var animator = $animateCss(element, options); + var signature = Buffer.allocUnsafe(6 + lenR + lenS) - // the driver lookup code inside of $$animation attempts to spawn a - // driver one by one until a driver returns a.$$willAnimate animator object. - // $animateCss will always return an object, however, it will pass in - // a flag as a hint as to whether an animation was detected or not - return animator.$$willAnimate ? animator : null; - } - }]; -}]; + // 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] + signature[0] = 0x30 + signature[1] = signature.length - 2 + signature[2] = 0x02 + signature[3] = r.length + r.copy(signature, 4) + signature[4 + lenR] = 0x02 + signature[5 + lenR] = s.length + s.copy(signature, 6 + lenR) -// TODO(matsko): use caching here to speed things up for detection -// TODO(matsko): add documentation -// by the time... + return signature +} -var $$AnimateJsProvider = ['$animateProvider', /** @this */ function($animateProvider) { - this.$get = ['$injector', '$$AnimateRunner', '$$jqLite', - function($injector, $$AnimateRunner, $$jqLite) { +module.exports = { + check: check, + decode: decode, + encode: encode +} - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); - // $animateJs(element, 'enter'); - return function(element, event, classes, options) { - var animationClosed = false; +},{"safe-buffer":276}],180:[function(require,module,exports){ +(function (global){ +/** + * Create a blob builder even when vendor prefixes exist + */ - // the `classes` argument is optional and if it is not used - // then the classes will be resolved from the element's className - // property as well as options.addClass/options.removeClass. - if (arguments.length === 3 && isObject(classes)) { - options = classes; - classes = null; - } +var BlobBuilder = global.BlobBuilder + || global.WebKitBlobBuilder + || global.MSBlobBuilder + || global.MozBlobBuilder; - options = prepareAnimationOptions(options); - if (!classes) { - classes = element.attr('class') || ''; - if (options.addClass) { - classes += ' ' + options.addClass; - } - if (options.removeClass) { - classes += ' ' + options.removeClass; - } - } +/** + * Check if Blob constructor is supported + */ - var classesToAdd = options.addClass; - var classesToRemove = options.removeClass; +var blobSupported = (function() { + try { + var a = new Blob(['hi']); + return a.size === 2; + } catch(e) { + return false; + } +})(); - // the lookupAnimations function returns a series of animation objects that are - // matched up with one or more of the CSS classes. These animation objects are - // defined via the module.animation factory function. If nothing is detected then - // we don't return anything which then makes $animation query the next driver. - var animations = lookupAnimations(classes); - var before, after; - if (animations.length) { - var afterFn, beforeFn; - if (event === 'leave') { - beforeFn = 'leave'; - afterFn = 'afterLeave'; // TODO(matsko): get rid of this - } else { - beforeFn = 'before' + event.charAt(0).toUpperCase() + event.substr(1); - afterFn = event; - } +/** + * Check if Blob constructor supports ArrayBufferViews + * Fails in Safari 6, so we need to map to ArrayBuffers there. + */ - if (event !== 'enter' && event !== 'move') { - before = packageAnimations(element, event, options, animations, beforeFn); - } - after = packageAnimations(element, event, options, animations, afterFn); - } +var blobSupportsArrayBufferView = blobSupported && (function() { + try { + var b = new Blob([new Uint8Array([1,2])]); + return b.size === 2; + } catch(e) { + return false; + } +})(); - // no matching animations - if (!before && !after) return; +/** + * Check if BlobBuilder is supported + */ - function applyOptions() { - options.domOperation(); - applyAnimationClasses(element, options); - } +var blobBuilderSupported = BlobBuilder + && BlobBuilder.prototype.append + && BlobBuilder.prototype.getBlob; - function close() { - animationClosed = true; - applyOptions(); - applyAnimationStyles(element, options); +/** + * Helper function that maps ArrayBufferViews to ArrayBuffers + * Used by BlobBuilder constructor and old browsers that didn't + * support it in the Blob constructor. + */ + +function mapArrayBufferViews(ary) { + for (var i = 0; i < ary.length; i++) { + var chunk = ary[i]; + if (chunk.buffer instanceof ArrayBuffer) { + var buf = chunk.buffer; + + // if this is a subarray, make a copy so we only + // include the subarray region from the underlying buffer + if (chunk.byteLength !== buf.byteLength) { + var copy = new Uint8Array(chunk.byteLength); + copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); + buf = copy.buffer; } - var runner; + ary[i] = buf; + } + } +} - return { - $$willAnimate: true, - end: function() { - if (runner) { - runner.end(); - } else { - close(); - runner = new $$AnimateRunner(); - runner.complete(true); - } - return runner; - }, - start: function() { - if (runner) { - return runner; - } +function BlobBuilderConstructor(ary, options) { + options = options || {}; - runner = new $$AnimateRunner(); - var closeActiveAnimations; - var chain = []; + var bb = new BlobBuilder(); + mapArrayBufferViews(ary); - if (before) { - chain.push(function(fn) { - closeActiveAnimations = before(fn); - }); - } - - if (chain.length) { - chain.push(function(fn) { - applyOptions(); - fn(true); - }); - } else { - applyOptions(); - } - - if (after) { - chain.push(function(fn) { - closeActiveAnimations = after(fn); - }); - } - - runner.setHost({ - end: function() { - endAnimations(); - }, - cancel: function() { - endAnimations(true); - } - }); - - $$AnimateRunner.chain(chain, onComplete); - return runner; + for (var i = 0; i < ary.length; i++) { + bb.append(ary[i]); + } - function onComplete(success) { - close(success); - runner.complete(success); - } + return (options.type) ? bb.getBlob(options.type) : bb.getBlob(); +}; - function endAnimations(cancelled) { - if (!animationClosed) { - (closeActiveAnimations || noop)(cancelled); - onComplete(cancelled); - } - } - } - }; +function BlobConstructor(ary, options) { + mapArrayBufferViews(ary); + return new Blob(ary, options || {}); +}; - function executeAnimationFn(fn, element, event, options, onDone) { - var args; - switch (event) { - case 'animate': - args = [element, options.from, options.to, onDone]; - break; +module.exports = (function() { + if (blobSupported) { + return blobSupportsArrayBufferView ? global.Blob : BlobConstructor; + } else if (blobBuilderSupported) { + return BlobBuilderConstructor; + } else { + return undefined; + } +})(); - case 'setClass': - args = [element, classesToAdd, classesToRemove, onDone]; - break; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],181:[function(require,module,exports){ +(function (module, exports) { + 'use strict'; - case 'addClass': - args = [element, classesToAdd, onDone]; - break; + // Utils + function assert (val, msg) { + if (!val) throw new Error(msg || 'Assertion failed'); + } - case 'removeClass': - args = [element, classesToRemove, onDone]; - break; + // Could use `inherits` module, but don't want to move from single file + // architecture yet. + function inherits (ctor, superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } - default: - args = [element, onDone]; - break; - } + // BN - args.push(options); + function BN (number, base, endian) { + if (BN.isBN(number)) { + return number; + } - var value = fn.apply(fn, args); - if (value) { - if (isFunction(value.start)) { - value = value.start(); - } + this.negative = 0; + this.words = null; + this.length = 0; - if (value instanceof $$AnimateRunner) { - value.done(onDone); - } else if (isFunction(value)) { - // optional onEnd / onCancel callback - return value; - } - } + // Reduction context + this.red = null; - return noop; + if (number !== null) { + if (base === 'le' || base === 'be') { + endian = base; + base = 10; } - function groupEventedAnimations(element, event, options, animations, fnName) { - var operations = []; - forEach(animations, function(ani) { - var animation = ani[fnName]; - if (!animation) return; - - // note that all of these animations will run in parallel - operations.push(function() { - var runner; - var endProgressCb; + this._init(number || 0, base || 10, endian || 'be'); + } + } + if (typeof module === 'object') { + module.exports = BN; + } else { + exports.BN = BN; + } - var resolved = false; - var onAnimationComplete = function(rejected) { - if (!resolved) { - resolved = true; - (endProgressCb || noop)(rejected); - runner.complete(!rejected); - } - }; + BN.BN = BN; + BN.wordSize = 26; - runner = new $$AnimateRunner({ - end: function() { - onAnimationComplete(); - }, - cancel: function() { - onAnimationComplete(true); - } - }); + var Buffer; + try { + Buffer = require('buffer').Buffer; + } catch (e) { + } - endProgressCb = executeAnimationFn(animation, element, event, options, function(result) { - var cancelled = result === false; - onAnimationComplete(cancelled); - }); + BN.isBN = function isBN (num) { + if (num instanceof BN) { + return true; + } - return runner; - }); - }); + return num !== null && typeof num === 'object' && + num.constructor.wordSize === BN.wordSize && Array.isArray(num.words); + }; - return operations; - } + BN.max = function max (left, right) { + if (left.cmp(right) > 0) return left; + return right; + }; - function packageAnimations(element, event, options, animations, fnName) { - var operations = groupEventedAnimations(element, event, options, animations, fnName); - if (operations.length === 0) { - var a, b; - if (fnName === 'beforeSetClass') { - a = groupEventedAnimations(element, 'removeClass', options, animations, 'beforeRemoveClass'); - b = groupEventedAnimations(element, 'addClass', options, animations, 'beforeAddClass'); - } else if (fnName === 'setClass') { - a = groupEventedAnimations(element, 'removeClass', options, animations, 'removeClass'); - b = groupEventedAnimations(element, 'addClass', options, animations, 'addClass'); - } + BN.min = function min (left, right) { + if (left.cmp(right) < 0) return left; + return right; + }; - if (a) { - operations = operations.concat(a); - } - if (b) { - operations = operations.concat(b); - } - } + BN.prototype._init = function init (number, base, endian) { + if (typeof number === 'number') { + return this._initNumber(number, base, endian); + } - if (operations.length === 0) return; + if (typeof number === 'object') { + return this._initArray(number, base, endian); + } - // TODO(matsko): add documentation - return function startAnimation(callback) { - var runners = []; - if (operations.length) { - forEach(operations, function(animateFn) { - runners.push(animateFn()); - }); - } + if (base === 'hex') { + base = 16; + } + assert(base === (base | 0) && base >= 2 && base <= 36); - if (runners.length) { - $$AnimateRunner.all(runners, callback); - } else { - callback(); - } + number = number.toString().replace(/\s+/g, ''); + var start = 0; + if (number[0] === '-') { + start++; + } - return function endFn(reject) { - forEach(runners, function(runner) { - if (reject) { - runner.cancel(); - } else { - runner.end(); - } - }); - }; - }; - } - }; + if (base === 16) { + this._parseHex(number, start); + } else { + this._parseBase(number, base, start); + } - function lookupAnimations(classes) { - classes = isArray(classes) ? classes : classes.split(' '); - var matches = [], flagMap = {}; - for (var i = 0; i < classes.length; i++) { - var klass = classes[i], - animationFactory = $animateProvider.$$registeredAnimations[klass]; - if (animationFactory && !flagMap[klass]) { - matches.push($injector.get(animationFactory)); - flagMap[klass] = true; - } - } - return matches; + if (number[0] === '-') { + this.negative = 1; } - }]; -}]; -var $$AnimateJsDriverProvider = ['$$animationProvider', /** @this */ function($$animationProvider) { - $$animationProvider.drivers.push('$$animateJsDriver'); - this.$get = ['$$animateJs', '$$AnimateRunner', function($$animateJs, $$AnimateRunner) { - return function initDriverFn(animationDetails) { - if (animationDetails.from && animationDetails.to) { - var fromAnimation = prepareAnimation(animationDetails.from); - var toAnimation = prepareAnimation(animationDetails.to); - if (!fromAnimation && !toAnimation) return; + this.strip(); - return { - start: function() { - var animationRunners = []; + if (endian !== 'le') return; - if (fromAnimation) { - animationRunners.push(fromAnimation.start()); - } + this._initArray(this.toArray(), base, endian); + }; - if (toAnimation) { - animationRunners.push(toAnimation.start()); - } + BN.prototype._initNumber = function _initNumber (number, base, endian) { + if (number < 0) { + this.negative = 1; + number = -number; + } + if (number < 0x4000000) { + this.words = [ number & 0x3ffffff ]; + this.length = 1; + } else if (number < 0x10000000000000) { + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff + ]; + this.length = 2; + } else { + assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff, + 1 + ]; + this.length = 3; + } - $$AnimateRunner.all(animationRunners, done); + if (endian !== 'le') return; - var runner = new $$AnimateRunner({ - end: endFnFactory(), - cancel: endFnFactory() - }); + // Reverse the bytes + this._initArray(this.toArray(), base, endian); + }; - return runner; + BN.prototype._initArray = function _initArray (number, base, endian) { + // Perhaps a Uint8Array + assert(typeof number.length === 'number'); + if (number.length <= 0) { + this.words = [ 0 ]; + this.length = 1; + return this; + } - function endFnFactory() { - return function() { - forEach(animationRunners, function(runner) { - // at this point we cannot cancel animations for groups just yet. 1.5+ - runner.end(); - }); - }; - } + this.length = Math.ceil(number.length / 3); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) { + this.words[i] = 0; + } - function done(status) { - runner.complete(status); - } - } - }; - } else { - return prepareAnimation(animationDetails); + var j, w; + var off = 0; + if (endian === 'be') { + for (i = number.length - 1, j = 0; i >= 0; i -= 3) { + w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } else if (endian === 'le') { + for (i = 0, j = 0; i < number.length; i += 3) { + w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } } - }; - - function prepareAnimation(animationDetails) { - // TODO(matsko): make sure to check for grouped animations and delegate down to normal animations - var element = animationDetails.element; - var event = animationDetails.event; - var options = animationDetails.options; - var classes = animationDetails.classes; - return $$animateJs(element, event, classes, options); } - }]; -}]; - -var NG_ANIMATE_ATTR_NAME = 'data-ng-animate'; -var NG_ANIMATE_PIN_DATA = '$ngAnimatePin'; -var $$AnimateQueueProvider = ['$animateProvider', /** @this */ function($animateProvider) { - var PRE_DIGEST_STATE = 1; - var RUNNING_STATE = 2; - var ONE_SPACE = ' '; - - var rules = this.rules = { - skip: [], - cancel: [], - join: [] + return this.strip(); }; - function getEventData(options) { - return { - addClass: options.addClass, - removeClass: options.removeClass, - from: options.from, - to: options.to - }; - } + function parseHex (str, start, end) { + var r = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; - function makeTruthyCssClassMap(classString) { - if (!classString) { - return null; - } + r <<= 4; - var keys = classString.split(ONE_SPACE); - var map = Object.create(null); + // 'a' - 'f' + if (c >= 49 && c <= 54) { + r |= c - 49 + 0xa; - forEach(keys, function(key) { - map[key] = true; - }); - return map; - } + // 'A' - 'F' + } else if (c >= 17 && c <= 22) { + r |= c - 17 + 0xa; - function hasMatchingClasses(newClassString, currentClassString) { - if (newClassString && currentClassString) { - var currentClassMap = makeTruthyCssClassMap(currentClassString); - return newClassString.split(ONE_SPACE).some(function(className) { - return currentClassMap[className]; - }); + // '0' - '9' + } else { + r |= c & 0xf; + } } + return r; } - function isAllowed(ruleType, currentAnimation, previousAnimation) { - return rules[ruleType].some(function(fn) { - return fn(currentAnimation, previousAnimation); - }); - } - - function hasAnimationClasses(animation, and) { - var a = (animation.addClass || '').length > 0; - var b = (animation.removeClass || '').length > 0; - return and ? a && b : a || b; - } - - rules.join.push(function(newAnimation, currentAnimation) { - // if the new animation is class-based then we can just tack that on - return !newAnimation.structural && hasAnimationClasses(newAnimation); - }); - - rules.skip.push(function(newAnimation, currentAnimation) { - // there is no need to animate anything if no classes are being added and - // there is no structural animation that will be triggered - return !newAnimation.structural && !hasAnimationClasses(newAnimation); - }); - - rules.skip.push(function(newAnimation, currentAnimation) { - // why should we trigger a new structural animation if the element will - // be removed from the DOM anyway? - return currentAnimation.event === 'leave' && newAnimation.structural; - }); - - rules.skip.push(function(newAnimation, currentAnimation) { - // if there is an ongoing current animation then don't even bother running the class-based animation - return currentAnimation.structural && currentAnimation.state === RUNNING_STATE && !newAnimation.structural; - }); + BN.prototype._parseHex = function _parseHex (number, start) { + // Create possibly bigger array to ensure that it fits the number + this.length = Math.ceil((number.length - start) / 6); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) { + this.words[i] = 0; + } - rules.cancel.push(function(newAnimation, currentAnimation) { - // there can never be two structural animations running at the same time - return currentAnimation.structural && newAnimation.structural; - }); + var j, w; + // Scan 24-bit chunks and add them to the number + var off = 0; + for (i = number.length - 6, j = 0; i >= start; i -= 6) { + w = parseHex(number, i, i + 6); + this.words[j] |= (w << off) & 0x3ffffff; + // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + if (i + 6 !== start) { + w = parseHex(number, start, i + 6); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + } + this.strip(); + }; - rules.cancel.push(function(newAnimation, currentAnimation) { - // if the previous animation is already running, but the new animation will - // be triggered, but the new animation is structural - return currentAnimation.state === RUNNING_STATE && newAnimation.structural; - }); + function parseBase (str, start, end, mul) { + var r = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; - rules.cancel.push(function(newAnimation, currentAnimation) { - // cancel the animation if classes added / removed in both animation cancel each other out, - // but only if the current animation isn't structural + r *= mul; - if (currentAnimation.structural) return false; + // 'a' + if (c >= 49) { + r += c - 49 + 0xa; - var nA = newAnimation.addClass; - var nR = newAnimation.removeClass; - var cA = currentAnimation.addClass; - var cR = currentAnimation.removeClass; + // 'A' + } else if (c >= 17) { + r += c - 17 + 0xa; - // early detection to save the global CPU shortage :) - if ((isUndefined(nA) && isUndefined(nR)) || (isUndefined(cA) && isUndefined(cR))) { - return false; + // '0' - '9' + } else { + r += c; + } } + return r; + } - return hasMatchingClasses(nA, cR) || hasMatchingClasses(nR, cA); - }); - - this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$Map', - '$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite', '$$forceReflow', - '$$isDocumentHidden', - function($$rAF, $rootScope, $rootElement, $document, $$Map, - $$animation, $$AnimateRunner, $templateRequest, $$jqLite, $$forceReflow, - $$isDocumentHidden) { - - var activeAnimationsLookup = new $$Map(); - var disabledElementsLookup = new $$Map(); - var animationsEnabled = null; + BN.prototype._parseBase = function _parseBase (number, base, start) { + // Initialize as zero + this.words = [ 0 ]; + this.length = 1; - function removeFromDisabledElementsLookup(evt) { - disabledElementsLookup.delete(evt.target); + // Find length of limb in base + for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) { + limbLen++; } + limbLen--; + limbPow = (limbPow / base) | 0; - function postDigestTaskFactory() { - var postDigestCalled = false; - return function(fn) { - // we only issue a call to postDigest before - // it has first passed. This prevents any callbacks - // from not firing once the animation has completed - // since it will be out of the digest cycle. - if (postDigestCalled) { - fn(); - } else { - $rootScope.$$postDigest(function() { - postDigestCalled = true; - fn(); - }); - } - }; - } + var total = number.length - start; + var mod = total % limbLen; + var end = Math.min(total, total - mod) + start; - // Wait until all directive and route-related templates are downloaded and - // compiled. The $templateRequest.totalPendingRequests variable keeps track of - // all of the remote templates being currently downloaded. If there are no - // templates currently downloading then the watcher will still fire anyway. - var deregisterWatch = $rootScope.$watch( - function() { return $templateRequest.totalPendingRequests === 0; }, - function(isEmpty) { - if (!isEmpty) return; - deregisterWatch(); + var word = 0; + for (var i = start; i < end; i += limbLen) { + word = parseBase(number, i, i + limbLen, base); - // Now that all templates have been downloaded, $animate will wait until - // the post digest queue is empty before enabling animations. By having two - // calls to $postDigest calls we can ensure that the flag is enabled at the - // very end of the post digest queue. Since all of the animations in $animate - // use $postDigest, it's important that the code below executes at the end. - // This basically means that the page is fully downloaded and compiled before - // any animations are triggered. - $rootScope.$$postDigest(function() { - $rootScope.$$postDigest(function() { - // we check for null directly in the event that the application already called - // .enabled() with whatever arguments that it provided it with - if (animationsEnabled === null) { - animationsEnabled = true; - } - }); - }); + this.imuln(limbPow); + if (this.words[0] + word < 0x4000000) { + this.words[0] += word; + } else { + this._iaddn(word); } - ); - - var callbackRegistry = Object.create(null); - - // remember that the `customFilter`/`classNameFilter` are set during the - // provider/config stage therefore we can optimize here and setup helper functions - var customFilter = $animateProvider.customFilter(); - var classNameFilter = $animateProvider.classNameFilter(); - var returnTrue = function() { return true; }; + } - var isAnimatableByFilter = customFilter || returnTrue; - var isAnimatableClassName = !classNameFilter ? returnTrue : function(node, options) { - var className = [node.getAttribute('class'), options.addClass, options.removeClass].join(' '); - return classNameFilter.test(className); - }; + if (mod !== 0) { + var pow = 1; + word = parseBase(number, i, number.length, base); - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + for (i = 0; i < mod; i++) { + pow *= base; + } - function normalizeAnimationDetails(element, animation) { - return mergeAnimationDetails(element, animation, {}); + this.imuln(pow); + if (this.words[0] + word < 0x4000000) { + this.words[0] += word; + } else { + this._iaddn(word); + } } + }; - // IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259. - var contains = window.Node.prototype.contains || /** @this */ function(arg) { - // eslint-disable-next-line no-bitwise - return this === arg || !!(this.compareDocumentPosition(arg) & 16); - }; + BN.prototype.copy = function copy (dest) { + dest.words = new Array(this.length); + for (var i = 0; i < this.length; i++) { + dest.words[i] = this.words[i]; + } + dest.length = this.length; + dest.negative = this.negative; + dest.red = this.red; + }; - function findCallbacks(targetParentNode, targetNode, event) { - var matches = []; - var entries = callbackRegistry[event]; - if (entries) { - forEach(entries, function(entry) { - if (contains.call(entry.node, targetNode)) { - matches.push(entry.callback); - } else if (event === 'leave' && contains.call(entry.node, targetParentNode)) { - matches.push(entry.callback); - } - }); - } + BN.prototype.clone = function clone () { + var r = new BN(null); + this.copy(r); + return r; + }; - return matches; + BN.prototype._expand = function _expand (size) { + while (this.length < size) { + this.words[this.length++] = 0; } + return this; + }; - function filterFromRegistry(list, matchContainer, matchCallback) { - var containerNode = extractElementNode(matchContainer); - return list.filter(function(entry) { - var isMatch = entry.node === containerNode && - (!matchCallback || entry.callback === matchCallback); - return !isMatch; - }); + // Remove leading `0` from `this` + BN.prototype.strip = function strip () { + while (this.length > 1 && this.words[this.length - 1] === 0) { + this.length--; } + return this._normSign(); + }; - function cleanupEventListeners(phase, node) { - if (phase === 'close' && !node.parentNode) { - // If the element is not attached to a parentNode, it has been removed by - // the domOperation, and we can safely remove the event callbacks - $animate.off(node); - } + BN.prototype._normSign = function _normSign () { + // -0 = 0 + if (this.length === 1 && this.words[0] === 0) { + this.negative = 0; } + return this; + }; - var $animate = { - on: function(event, container, callback) { - var node = extractElementNode(container); - callbackRegistry[event] = callbackRegistry[event] || []; - callbackRegistry[event].push({ - node: node, - callback: callback - }); - - // Remove the callback when the element is removed from the DOM - jqLite(container).on('$destroy', function() { - var animationDetails = activeAnimationsLookup.get(node); + BN.prototype.inspect = function inspect () { + return (this.red ? ''; + }; - if (!animationDetails) { - // If there's an animation ongoing, the callback calling code will remove - // the event listeners. If we'd remove here, the callbacks would be removed - // before the animation ends - $animate.off(event, container, callback); - } - }); - }, + /* - off: function(event, container, callback) { - if (arguments.length === 1 && !isString(arguments[0])) { - container = arguments[0]; - for (var eventType in callbackRegistry) { - callbackRegistry[eventType] = filterFromRegistry(callbackRegistry[eventType], container); - } + var zeros = []; + var groupSizes = []; + var groupBases = []; - return; - } + var s = ''; + var i = -1; + while (++i < BN.wordSize) { + zeros[i] = s; + s += '0'; + } + groupSizes[0] = 0; + groupSizes[1] = 0; + groupBases[0] = 0; + groupBases[1] = 0; + var base = 2 - 1; + while (++base < 36 + 1) { + var groupSize = 0; + var groupBase = 1; + while (groupBase < (1 << BN.wordSize) / base) { + groupBase *= base; + groupSize += 1; + } + groupSizes[base] = groupSize; + groupBases[base] = groupBase; + } - var entries = callbackRegistry[event]; - if (!entries) return; + */ - callbackRegistry[event] = arguments.length === 1 - ? null - : filterFromRegistry(entries, container, callback); - }, + var zeros = [ + '', + '0', + '00', + '000', + '0000', + '00000', + '000000', + '0000000', + '00000000', + '000000000', + '0000000000', + '00000000000', + '000000000000', + '0000000000000', + '00000000000000', + '000000000000000', + '0000000000000000', + '00000000000000000', + '000000000000000000', + '0000000000000000000', + '00000000000000000000', + '000000000000000000000', + '0000000000000000000000', + '00000000000000000000000', + '000000000000000000000000', + '0000000000000000000000000' + ]; - pin: function(element, parentElement) { - assertArg(isElement(element), 'element', 'not an element'); - assertArg(isElement(parentElement), 'parentElement', 'not an element'); - element.data(NG_ANIMATE_PIN_DATA, parentElement); - }, + var groupSizes = [ + 0, 0, + 25, 16, 12, 11, 10, 9, 8, + 8, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 + ]; - push: function(element, event, options, domOperation) { - options = options || {}; - options.domOperation = domOperation; - return queueAnimation(element, event, options); - }, + var groupBases = [ + 0, 0, + 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, + 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, + 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, + 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, + 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 + ]; - // this method has four signatures: - // () - global getter - // (bool) - global setter - // (element) - element getter - // (element, bool) - element setter - enabled: function(element, bool) { - var argCount = arguments.length; + BN.prototype.toString = function toString (base, padding) { + base = base || 10; + padding = padding | 0 || 1; - if (argCount === 0) { - // () - Global getter - bool = !!animationsEnabled; + var out; + if (base === 16 || base === 'hex') { + out = ''; + var off = 0; + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i]; + var word = (((w << off) | carry) & 0xffffff).toString(16); + carry = (w >>> (24 - off)) & 0xffffff; + if (carry !== 0 || i !== this.length - 1) { + out = zeros[6 - word.length] + word + out; } else { - var hasElement = isElement(element); + out = word + out; + } + off += 2; + if (off >= 26) { + off -= 26; + i--; + } + } + if (carry !== 0) { + out = carry.toString(16) + out; + } + while (out.length % padding !== 0) { + out = '0' + out; + } + if (this.negative !== 0) { + out = '-' + out; + } + return out; + } - if (!hasElement) { - // (bool) - Global setter - bool = animationsEnabled = !!element; - } else { - var node = getDomNode(element); + if (base === (base | 0) && base >= 2 && base <= 36) { + // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); + var groupSize = groupSizes[base]; + // var groupBase = Math.pow(base, groupSize); + var groupBase = groupBases[base]; + out = ''; + var c = this.clone(); + c.negative = 0; + while (!c.isZero()) { + var r = c.modn(groupBase).toString(base); + c = c.idivn(groupBase); - if (argCount === 1) { - // (element) - Element getter - bool = !disabledElementsLookup.get(node); - } else { - // (element, bool) - Element setter - if (!disabledElementsLookup.has(node)) { - // The element is added to the map for the first time. - // Create a listener to remove it on `$destroy` (to avoid memory leak). - jqLite(element).on('$destroy', removeFromDisabledElementsLookup); - } - disabledElementsLookup.set(node, !bool); - } - } + if (!c.isZero()) { + out = zeros[groupSize - r.length] + r + out; + } else { + out = r + out; } - - return bool; } - }; - - return $animate; + if (this.isZero()) { + out = '0' + out; + } + while (out.length % padding !== 0) { + out = '0' + out; + } + if (this.negative !== 0) { + out = '-' + out; + } + return out; + } - function queueAnimation(originalElement, event, initialOptions) { - // we always make a copy of the options since - // there should never be any side effects on - // the input data when running `$animateCss`. - var options = copy(initialOptions); + assert(false, 'Base should be between 2 and 36'); + }; - var element = stripCommentsFromElement(originalElement); - var node = getDomNode(element); - var parentNode = node && node.parentNode; + BN.prototype.toNumber = function toNumber () { + var ret = this.words[0]; + if (this.length === 2) { + ret += this.words[1] * 0x4000000; + } else if (this.length === 3 && this.words[2] === 0x01) { + // NOTE: at this stage it is known that the top bit is set + ret += 0x10000000000000 + (this.words[1] * 0x4000000); + } else if (this.length > 2) { + assert(false, 'Number can only safely store up to 53 bits'); + } + return (this.negative !== 0) ? -ret : ret; + }; - options = prepareAnimationOptions(options); + BN.prototype.toJSON = function toJSON () { + return this.toString(16); + }; - // we create a fake runner with a working promise. - // These methods will become available after the digest has passed - var runner = new $$AnimateRunner(); + BN.prototype.toBuffer = function toBuffer (endian, length) { + assert(typeof Buffer !== 'undefined'); + return this.toArrayLike(Buffer, endian, length); + }; - // this is used to trigger callbacks in postDigest mode - var runInNextPostDigestOrNow = postDigestTaskFactory(); + BN.prototype.toArray = function toArray (endian, length) { + return this.toArrayLike(Array, endian, length); + }; - if (isArray(options.addClass)) { - options.addClass = options.addClass.join(' '); - } + BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) { + var byteLength = this.byteLength(); + var reqLength = length || Math.max(1, byteLength); + assert(byteLength <= reqLength, 'byte array longer than desired length'); + assert(reqLength > 0, 'Requested array length <= 0'); - if (options.addClass && !isString(options.addClass)) { - options.addClass = null; - } + this.strip(); + var littleEndian = endian === 'le'; + var res = new ArrayType(reqLength); - if (isArray(options.removeClass)) { - options.removeClass = options.removeClass.join(' '); + var b, i; + var q = this.clone(); + if (!littleEndian) { + // Assume big-endian + for (i = 0; i < reqLength - byteLength; i++) { + res[i] = 0; } - if (options.removeClass && !isString(options.removeClass)) { - options.removeClass = null; - } + for (i = 0; !q.isZero(); i++) { + b = q.andln(0xff); + q.iushrn(8); - if (options.from && !isObject(options.from)) { - options.from = null; + res[reqLength - i - 1] = b; } + } else { + for (i = 0; !q.isZero(); i++) { + b = q.andln(0xff); + q.iushrn(8); - if (options.to && !isObject(options.to)) { - options.to = null; + res[i] = b; } - // If animations are hard-disabled for the whole application there is no need to continue. - // There are also situations where a directive issues an animation for a jqLite wrapper that - // contains only comment nodes. In this case, there is no way we can perform an animation. - if (!animationsEnabled || - !node || - !isAnimatableByFilter(node, event, initialOptions) || - !isAnimatableClassName(node, options)) { - close(); - return runner; + for (; i < reqLength; i++) { + res[i] = 0; } + } - var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; - - var documentHidden = $$isDocumentHidden(); - - // This is a hard disable of all animations the element itself, therefore there is no need to - // continue further past this point if not enabled - // Animations are also disabled if the document is currently hidden (page is not visible - // to the user), because browsers slow down or do not flush calls to requestAnimationFrame - var skipAnimations = documentHidden || disabledElementsLookup.get(node); - var existingAnimation = (!skipAnimations && activeAnimationsLookup.get(node)) || {}; - var hasExistingAnimation = !!existingAnimation.state; + return res; + }; - // there is no point in traversing the same collection of parent ancestors if a followup - // animation will be run on the same element that already did all that checking work - if (!skipAnimations && (!hasExistingAnimation || existingAnimation.state !== PRE_DIGEST_STATE)) { - skipAnimations = !areAnimationsAllowed(node, parentNode, event); - } - - if (skipAnimations) { - // Callbacks should fire even if the document is hidden (regression fix for issue #14120) - if (documentHidden) notifyProgress(runner, event, 'start', getEventData(options)); - close(); - if (documentHidden) notifyProgress(runner, event, 'close', getEventData(options)); - return runner; - } - - if (isStructural) { - closeChildAnimations(node); + if (Math.clz32) { + BN.prototype._countBits = function _countBits (w) { + return 32 - Math.clz32(w); + }; + } else { + BN.prototype._countBits = function _countBits (w) { + var t = w; + var r = 0; + if (t >= 0x1000) { + r += 13; + t >>>= 13; } - - var newAnimation = { - structural: isStructural, - element: element, - event: event, - addClass: options.addClass, - removeClass: options.removeClass, - close: close, - options: options, - runner: runner - }; - - if (hasExistingAnimation) { - var skipAnimationFlag = isAllowed('skip', newAnimation, existingAnimation); - if (skipAnimationFlag) { - if (existingAnimation.state === RUNNING_STATE) { - close(); - return runner; - } else { - mergeAnimationDetails(element, existingAnimation, newAnimation); - return existingAnimation.runner; - } - } - var cancelAnimationFlag = isAllowed('cancel', newAnimation, existingAnimation); - if (cancelAnimationFlag) { - if (existingAnimation.state === RUNNING_STATE) { - // this will end the animation right away and it is safe - // to do so since the animation is already running and the - // runner callback code will run in async - existingAnimation.runner.end(); - } else if (existingAnimation.structural) { - // this means that the animation is queued into a digest, but - // hasn't started yet. Therefore it is safe to run the close - // method which will call the runner methods in async. - existingAnimation.close(); - } else { - // this will merge the new animation options into existing animation options - mergeAnimationDetails(element, existingAnimation, newAnimation); - - return existingAnimation.runner; - } - } else { - // a joined animation means that this animation will take over the existing one - // so an example would involve a leave animation taking over an enter. Then when - // the postDigest kicks in the enter will be ignored. - var joinAnimationFlag = isAllowed('join', newAnimation, existingAnimation); - if (joinAnimationFlag) { - if (existingAnimation.state === RUNNING_STATE) { - normalizeAnimationDetails(element, newAnimation); - } else { - applyGeneratedPreparationClasses($$jqLite, element, isStructural ? event : null, options); - - event = newAnimation.event = existingAnimation.event; - options = mergeAnimationDetails(element, existingAnimation, newAnimation); - - //we return the same runner since only the option values of this animation will - //be fed into the `existingAnimation`. - return existingAnimation.runner; - } - } - } - } else { - // normalization in this case means that it removes redundant CSS classes that - // already exist (addClass) or do not exist (removeClass) on the element - normalizeAnimationDetails(element, newAnimation); + if (t >= 0x40) { + r += 7; + t >>>= 7; } - - // when the options are merged and cleaned up we may end up not having to do - // an animation at all, therefore we should check this before issuing a post - // digest callback. Structural animations will always run no matter what. - var isValidAnimation = newAnimation.structural; - if (!isValidAnimation) { - // animate (from/to) can be quickly checked first, otherwise we check if any classes are present - isValidAnimation = (newAnimation.event === 'animate' && Object.keys(newAnimation.options.to || {}).length > 0) - || hasAnimationClasses(newAnimation); + if (t >= 0x8) { + r += 4; + t >>>= 4; } - - if (!isValidAnimation) { - close(); - clearElementAnimationState(node); - return runner; + if (t >= 0x02) { + r += 2; + t >>>= 2; } + return r + t; + }; + } - // the counter keeps track of cancelled animations - var counter = (existingAnimation.counter || 0) + 1; - newAnimation.counter = counter; - - markElementAnimationState(node, PRE_DIGEST_STATE, newAnimation); - - $rootScope.$$postDigest(function() { - // It is possible that the DOM nodes inside `originalElement` have been replaced. This can - // happen if the animated element is a transcluded clone and also has a `templateUrl` - // directive on it. Therefore, we must recreate `element` in order to interact with the - // actual DOM nodes. - // Note: We still need to use the old `node` for certain things, such as looking up in - // HashMaps where it was used as the key. - - element = stripCommentsFromElement(originalElement); - - var animationDetails = activeAnimationsLookup.get(node); - var animationCancelled = !animationDetails; - animationDetails = animationDetails || {}; - - // if addClass/removeClass is called before something like enter then the - // registered parent element may not be present. The code below will ensure - // that a final value for parent element is obtained - var parentElement = element.parent() || []; - - // animate/structural/class-based animations all have requirements. Otherwise there - // is no point in performing an animation. The parent node must also be set. - var isValidAnimation = parentElement.length > 0 - && (animationDetails.event === 'animate' - || animationDetails.structural - || hasAnimationClasses(animationDetails)); - - // this means that the previous animation was cancelled - // even if the follow-up animation is the same event - if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) { - // if another animation did not take over then we need - // to make sure that the domOperation and options are - // handled accordingly - if (animationCancelled) { - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - } - - // if the event changed from something like enter to leave then we do - // it, otherwise if it's the same then the end result will be the same too - if (animationCancelled || (isStructural && animationDetails.event !== event)) { - options.domOperation(); - runner.end(); - } - - // in the event that the element animation was not cancelled or a follow-up animation - // isn't allowed to animate from here then we need to clear the state of the element - // so that any future animations won't read the expired animation data. - if (!isValidAnimation) { - clearElementAnimationState(node); - } + BN.prototype._zeroBits = function _zeroBits (w) { + // Short-cut + if (w === 0) return 26; - return; - } + var t = w; + var r = 0; + if ((t & 0x1fff) === 0) { + r += 13; + t >>>= 13; + } + if ((t & 0x7f) === 0) { + r += 7; + t >>>= 7; + } + if ((t & 0xf) === 0) { + r += 4; + t >>>= 4; + } + if ((t & 0x3) === 0) { + r += 2; + t >>>= 2; + } + if ((t & 0x1) === 0) { + r++; + } + return r; + }; - // this combined multiple class to addClass / removeClass into a setClass event - // so long as a structural event did not take over the animation - event = !animationDetails.structural && hasAnimationClasses(animationDetails, true) - ? 'setClass' - : animationDetails.event; + // Return number of used bits in a BN + BN.prototype.bitLength = function bitLength () { + var w = this.words[this.length - 1]; + var hi = this._countBits(w); + return (this.length - 1) * 26 + hi; + }; - markElementAnimationState(node, RUNNING_STATE); - var realRunner = $$animation(element, event, animationDetails.options); + function toBitArray (num) { + var w = new Array(num.bitLength()); - // this will update the runner's flow-control events based on - // the `realRunner` object. - runner.setHost(realRunner); - notifyProgress(runner, event, 'start', getEventData(options)); + for (var bit = 0; bit < w.length; bit++) { + var off = (bit / 26) | 0; + var wbit = bit % 26; - realRunner.done(function(status) { - close(!status); - var animationDetails = activeAnimationsLookup.get(node); - if (animationDetails && animationDetails.counter === counter) { - clearElementAnimationState(node); - } - notifyProgress(runner, event, 'close', getEventData(options)); - }); - }); + w[bit] = (num.words[off] & (1 << wbit)) >>> wbit; + } - return runner; + return w; + } - function notifyProgress(runner, event, phase, data) { - runInNextPostDigestOrNow(function() { - var callbacks = findCallbacks(parentNode, node, event); - if (callbacks.length) { - // do not optimize this call here to RAF because - // we don't know how heavy the callback code here will - // be and if this code is buffered then this can - // lead to a performance regression. - $$rAF(function() { - forEach(callbacks, function(callback) { - callback(element, phase, data); - }); - cleanupEventListeners(phase, node); - }); - } else { - cleanupEventListeners(phase, node); - } - }); - runner.progress(event, phase, data); - } + // Number of trailing zero bits + BN.prototype.zeroBits = function zeroBits () { + if (this.isZero()) return 0; - function close(reject) { - clearGeneratedClasses(element, options); - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - options.domOperation(); - runner.complete(!reject); - } + var r = 0; + for (var i = 0; i < this.length; i++) { + var b = this._zeroBits(this.words[i]); + r += b; + if (b !== 26) break; } + return r; + }; - function closeChildAnimations(node) { - var children = node.querySelectorAll('[' + NG_ANIMATE_ATTR_NAME + ']'); - forEach(children, function(child) { - var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME), 10); - var animationDetails = activeAnimationsLookup.get(child); - if (animationDetails) { - switch (state) { - case RUNNING_STATE: - animationDetails.runner.end(); - /* falls through */ - case PRE_DIGEST_STATE: - activeAnimationsLookup.delete(child); - break; - } - } - }); - } + BN.prototype.byteLength = function byteLength () { + return Math.ceil(this.bitLength() / 8); + }; - function clearElementAnimationState(node) { - node.removeAttribute(NG_ANIMATE_ATTR_NAME); - activeAnimationsLookup.delete(node); + BN.prototype.toTwos = function toTwos (width) { + if (this.negative !== 0) { + return this.abs().inotn(width).iaddn(1); } + return this.clone(); + }; - /** - * This fn returns false if any of the following is true: - * a) animations on any parent element are disabled, and animations on the element aren't explicitly allowed - * b) a parent element has an ongoing structural animation, and animateChildren is false - * c) the element is not a child of the body - * d) the element is not a child of the $rootElement - */ - function areAnimationsAllowed(node, parentNode, event) { - var bodyNode = $document[0].body; - var rootNode = getDomNode($rootElement); - - var bodyNodeDetected = (node === bodyNode) || node.nodeName === 'HTML'; - var rootNodeDetected = (node === rootNode); - var parentAnimationDetected = false; - var elementDisabled = disabledElementsLookup.get(node); - var animateChildren; - - var parentHost = jqLite.data(node, NG_ANIMATE_PIN_DATA); - if (parentHost) { - parentNode = getDomNode(parentHost); - } + BN.prototype.fromTwos = function fromTwos (width) { + if (this.testn(width - 1)) { + return this.notn(width).iaddn(1).ineg(); + } + return this.clone(); + }; - while (parentNode) { - if (!rootNodeDetected) { - // AngularJS doesn't want to attempt to animate elements outside of the application - // therefore we need to ensure that the rootElement is an ancestor of the current element - rootNodeDetected = (parentNode === rootNode); - } + BN.prototype.isNeg = function isNeg () { + return this.negative !== 0; + }; - if (parentNode.nodeType !== ELEMENT_NODE) { - // no point in inspecting the #document element - break; - } + // Return negative clone of `this` + BN.prototype.neg = function neg () { + return this.clone().ineg(); + }; - var details = activeAnimationsLookup.get(parentNode) || {}; - // either an enter, leave or move animation will commence - // therefore we can't allow any animations to take place - // but if a parent animation is class-based then that's ok - if (!parentAnimationDetected) { - var parentNodeDisabled = disabledElementsLookup.get(parentNode); + BN.prototype.ineg = function ineg () { + if (!this.isZero()) { + this.negative ^= 1; + } - if (parentNodeDisabled === true && elementDisabled !== false) { - // disable animations if the user hasn't explicitly enabled animations on the - // current element - elementDisabled = true; - // element is disabled via parent element, no need to check anything else - break; - } else if (parentNodeDisabled === false) { - elementDisabled = false; - } - parentAnimationDetected = details.structural; - } + return this; + }; - if (isUndefined(animateChildren) || animateChildren === true) { - var value = jqLite.data(parentNode, NG_ANIMATE_CHILDREN_DATA); - if (isDefined(value)) { - animateChildren = value; - } - } + // Or `num` with `this` in-place + BN.prototype.iuor = function iuor (num) { + while (this.length < num.length) { + this.words[this.length++] = 0; + } - // there is no need to continue traversing at this point - if (parentAnimationDetected && animateChildren === false) break; + for (var i = 0; i < num.length; i++) { + this.words[i] = this.words[i] | num.words[i]; + } - if (!bodyNodeDetected) { - // we also need to ensure that the element is or will be a part of the body element - // otherwise it is pointless to even issue an animation to be rendered - bodyNodeDetected = (parentNode === bodyNode); - } + return this.strip(); + }; - if (bodyNodeDetected && rootNodeDetected) { - // If both body and root have been found, any other checks are pointless, - // as no animation data should live outside the application - break; - } + BN.prototype.ior = function ior (num) { + assert((this.negative | num.negative) === 0); + return this.iuor(num); + }; - if (!rootNodeDetected) { - // If `rootNode` is not detected, check if `parentNode` is pinned to another element - parentHost = jqLite.data(parentNode, NG_ANIMATE_PIN_DATA); - if (parentHost) { - // The pin target element becomes the next parent element - parentNode = getDomNode(parentHost); - continue; - } - } + // Or `num` with `this` + BN.prototype.or = function or (num) { + if (this.length > num.length) return this.clone().ior(num); + return num.clone().ior(this); + }; - parentNode = parentNode.parentNode; - } + BN.prototype.uor = function uor (num) { + if (this.length > num.length) return this.clone().iuor(num); + return num.clone().iuor(this); + }; - var allowAnimation = (!parentAnimationDetected || animateChildren) && elementDisabled !== true; - return allowAnimation && rootNodeDetected && bodyNodeDetected; + // And `num` with `this` in-place + BN.prototype.iuand = function iuand (num) { + // b = min-length(num, this) + var b; + if (this.length > num.length) { + b = num; + } else { + b = this; } - function markElementAnimationState(node, state, details) { - details = details || {}; - details.state = state; - - node.setAttribute(NG_ANIMATE_ATTR_NAME, state); - - var oldValue = activeAnimationsLookup.get(node); - var newValue = oldValue - ? extend(oldValue, details) - : details; - activeAnimationsLookup.set(node, newValue); + for (var i = 0; i < b.length; i++) { + this.words[i] = this.words[i] & num.words[i]; } - }]; -}]; - -/** @this */ -var $$AnimateCacheProvider = function() { - var KEY = '$$ngAnimateParentKey'; - var parentCounter = 0; - var cache = Object.create(null); + this.length = b.length; - this.$get = [function() { - return { - cacheKey: function(node, method, addClass, removeClass) { - var parentNode = node.parentNode; - var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter); - var parts = [parentID, method, node.getAttribute('class')]; - if (addClass) { - parts.push(addClass); - } - if (removeClass) { - parts.push(removeClass); - } - return parts.join(' '); - }, + return this.strip(); + }; - containsCachedAnimationWithoutDuration: function(key) { - var entry = cache[key]; + BN.prototype.iand = function iand (num) { + assert((this.negative | num.negative) === 0); + return this.iuand(num); + }; - // nothing cached, so go ahead and animate - // otherwise it should be a valid animation - return (entry && !entry.isValid) || false; - }, + // And `num` with `this` + BN.prototype.and = function and (num) { + if (this.length > num.length) return this.clone().iand(num); + return num.clone().iand(this); + }; - flush: function() { - cache = Object.create(null); - }, + BN.prototype.uand = function uand (num) { + if (this.length > num.length) return this.clone().iuand(num); + return num.clone().iuand(this); + }; - count: function(key) { - var entry = cache[key]; - return entry ? entry.total : 0; - }, + // Xor `num` with `this` in-place + BN.prototype.iuxor = function iuxor (num) { + // a.length > b.length + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } - get: function(key) { - var entry = cache[key]; - return entry && entry.value; - }, + for (var i = 0; i < b.length; i++) { + this.words[i] = a.words[i] ^ b.words[i]; + } - put: function(key, value, isValid) { - if (!cache[key]) { - cache[key] = { total: 1, value: value, isValid: isValid }; - } else { - cache[key].total++; - cache[key].value = value; - } + if (this !== a) { + for (; i < a.length; i++) { + this.words[i] = a.words[i]; } - }; - }]; -}; - -/* exported $$AnimationProvider */ - -var $$AnimationProvider = ['$animateProvider', /** @this */ function($animateProvider) { - var NG_ANIMATE_REF_ATTR = 'ng-animate-ref'; + } - var drivers = this.drivers = []; + this.length = a.length; - var RUNNER_STORAGE_KEY = '$$animationRunner'; - var PREPARE_CLASSES_KEY = '$$animatePrepareClasses'; + return this.strip(); + }; - function setRunner(element, runner) { - element.data(RUNNER_STORAGE_KEY, runner); - } + BN.prototype.ixor = function ixor (num) { + assert((this.negative | num.negative) === 0); + return this.iuxor(num); + }; - function removeRunner(element) { - element.removeData(RUNNER_STORAGE_KEY); - } + // Xor `num` with `this` + BN.prototype.xor = function xor (num) { + if (this.length > num.length) return this.clone().ixor(num); + return num.clone().ixor(this); + }; - function getRunner(element) { - return element.data(RUNNER_STORAGE_KEY); - } + BN.prototype.uxor = function uxor (num) { + if (this.length > num.length) return this.clone().iuxor(num); + return num.clone().iuxor(this); + }; - this.$get = ['$$jqLite', '$rootScope', '$injector', '$$AnimateRunner', '$$Map', '$$rAFScheduler', '$$animateCache', - function($$jqLite, $rootScope, $injector, $$AnimateRunner, $$Map, $$rAFScheduler, $$animateCache) { + // Not ``this`` with ``width`` bitwidth + BN.prototype.inotn = function inotn (width) { + assert(typeof width === 'number' && width >= 0); - var animationQueue = []; - var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); + var bytesNeeded = Math.ceil(width / 26) | 0; + var bitsLeft = width % 26; - function sortAnimations(animations) { - var tree = { children: [] }; - var i, lookup = new $$Map(); + // Extend the buffer with leading zeroes + this._expand(bytesNeeded); - // this is done first beforehand so that the map - // is filled with a list of the elements that will be animated - for (i = 0; i < animations.length; i++) { - var animation = animations[i]; - lookup.set(animation.domNode, animations[i] = { - domNode: animation.domNode, - element: animation.element, - fn: animation.fn, - children: [] - }); - } + if (bitsLeft > 0) { + bytesNeeded--; + } - for (i = 0; i < animations.length; i++) { - processNode(animations[i]); - } + // Handle complete words + for (var i = 0; i < bytesNeeded; i++) { + this.words[i] = ~this.words[i] & 0x3ffffff; + } - return flatten(tree); + // Handle the residue + if (bitsLeft > 0) { + this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft)); + } - function processNode(entry) { - if (entry.processed) return entry; - entry.processed = true; + // And remove leading zeroes + return this.strip(); + }; - var elementNode = entry.domNode; - var parentNode = elementNode.parentNode; - lookup.set(elementNode, entry); + BN.prototype.notn = function notn (width) { + return this.clone().inotn(width); + }; - var parentEntry; - while (parentNode) { - parentEntry = lookup.get(parentNode); - if (parentEntry) { - if (!parentEntry.processed) { - parentEntry = processNode(parentEntry); - } - break; - } - parentNode = parentNode.parentNode; - } + // Set `bit` of `this` + BN.prototype.setn = function setn (bit, val) { + assert(typeof bit === 'number' && bit >= 0); - (parentEntry || tree).children.push(entry); - return entry; - } + var off = (bit / 26) | 0; + var wbit = bit % 26; - function flatten(tree) { - var result = []; - var queue = []; - var i; + this._expand(off + 1); - for (i = 0; i < tree.children.length; i++) { - queue.push(tree.children[i]); - } + if (val) { + this.words[off] = this.words[off] | (1 << wbit); + } else { + this.words[off] = this.words[off] & ~(1 << wbit); + } - var remainingLevelEntries = queue.length; - var nextLevelEntries = 0; - var row = []; + return this.strip(); + }; - for (i = 0; i < queue.length; i++) { - var entry = queue[i]; - if (remainingLevelEntries <= 0) { - remainingLevelEntries = nextLevelEntries; - nextLevelEntries = 0; - result.push(row); - row = []; - } - row.push(entry); - entry.children.forEach(function(childEntry) { - nextLevelEntries++; - queue.push(childEntry); - }); - remainingLevelEntries--; - } + // Add `num` to `this` in-place + BN.prototype.iadd = function iadd (num) { + var r; - if (row.length) { - result.push(row); - } + // negative + positive + if (this.negative !== 0 && num.negative === 0) { + this.negative = 0; + r = this.isub(num); + this.negative ^= 1; + return this._normSign(); - return result; - } + // positive + negative + } else if (this.negative === 0 && num.negative !== 0) { + num.negative = 0; + r = this.isub(num); + num.negative = 1; + return r._normSign(); } - // TODO(matsko): document the signature in a better way - return function(element, event, options) { - options = prepareAnimationOptions(options); - var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0; - - // there is no animation at the current moment, however - // these runner methods will get later updated with the - // methods leading into the driver's end/cancel methods - // for now they just stop the animation from starting - var runner = new $$AnimateRunner({ - end: function() { close(); }, - cancel: function() { close(true); } - }); - - if (!drivers.length) { - close(); - return runner; - } + // a.length > b.length + var a, b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } - var classes = mergeClasses(element.attr('class'), mergeClasses(options.addClass, options.removeClass)); - var tempClasses = options.tempClasses; - if (tempClasses) { - classes += ' ' + tempClasses; - options.tempClasses = null; - } + var carry = 0; + for (var i = 0; i < b.length; i++) { + r = (a.words[i] | 0) + (b.words[i] | 0) + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + for (; carry !== 0 && i < a.length; i++) { + r = (a.words[i] | 0) + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } - if (isStructural) { - element.data(PREPARE_CLASSES_KEY, 'ng-' + event + PREPARE_CLASS_SUFFIX); + this.length = a.length; + if (carry !== 0) { + this.words[this.length] = carry; + this.length++; + // Copy the rest of the words + } else if (a !== this) { + for (; i < a.length; i++) { + this.words[i] = a.words[i]; } + } - setRunner(element, runner); - - animationQueue.push({ - // this data is used by the postDigest code and passed into - // the driver step function - element: element, - classes: classes, - event: event, - structural: isStructural, - options: options, - beforeStart: beforeStart, - close: close - }); - - element.on('$destroy', handleDestroyedElement); - - // we only want there to be one function called within the post digest - // block. This way we can group animations for all the animations that - // were apart of the same postDigest flush call. - if (animationQueue.length > 1) return runner; + return this; + }; - $rootScope.$$postDigest(function() { - var animations = []; - forEach(animationQueue, function(entry) { - // the element was destroyed early on which removed the runner - // form its storage. This means we can't animate this element - // at all and it already has been closed due to destruction. - if (getRunner(entry.element)) { - animations.push(entry); - } else { - entry.close(); - } - }); + // Add `num` to `this` + BN.prototype.add = function add (num) { + var res; + if (num.negative !== 0 && this.negative === 0) { + num.negative = 0; + res = this.sub(num); + num.negative ^= 1; + return res; + } else if (num.negative === 0 && this.negative !== 0) { + this.negative = 0; + res = num.sub(this); + this.negative = 1; + return res; + } - // now any future animations will be in another postDigest - animationQueue.length = 0; + if (this.length > num.length) return this.clone().iadd(num); - var groupedAnimations = groupAnimations(animations); - var toBeSortedAnimations = []; + return num.clone().iadd(this); + }; - forEach(groupedAnimations, function(animationEntry) { - var element = animationEntry.from ? animationEntry.from.element : animationEntry.element; - var extraClasses = options.addClass; + // Subtract `num` from `this` in-place + BN.prototype.isub = function isub (num) { + // this - (-num) = this + num + if (num.negative !== 0) { + num.negative = 0; + var r = this.iadd(num); + num.negative = 1; + return r._normSign(); - extraClasses = (extraClasses ? (extraClasses + ' ') : '') + NG_ANIMATE_CLASSNAME; - var cacheKey = $$animateCache.cacheKey(element[0], animationEntry.event, extraClasses, options.removeClass); + // -this - num = -(this + num) + } else if (this.negative !== 0) { + this.negative = 0; + this.iadd(num); + this.negative = 1; + return this._normSign(); + } - toBeSortedAnimations.push({ - element: element, - domNode: getDomNode(element), - fn: function triggerAnimationStart() { - var startAnimationFn, closeFn = animationEntry.close; + // At this point both numbers are positive + var cmp = this.cmp(num); - // in the event that we've cached the animation status for this element - // and it's in fact an invalid animation (something that has duration = 0) - // then we should skip all the heavy work from here on - if ($$animateCache.containsCachedAnimationWithoutDuration(cacheKey)) { - closeFn(); - return; - } + // Optimization - zeroify + if (cmp === 0) { + this.negative = 0; + this.length = 1; + this.words[0] = 0; + return this; + } - // it's important that we apply the `ng-animate` CSS class and the - // temporary classes before we do any driver invoking since these - // CSS classes may be required for proper CSS detection. - animationEntry.beforeStart(); + // a > b + var a, b; + if (cmp > 0) { + a = this; + b = num; + } else { + a = num; + b = this; + } - // in the event that the element was removed before the digest runs or - // during the RAF sequencing then we should not trigger the animation. - var targetElement = animationEntry.anchors - ? (animationEntry.from.element || animationEntry.to.element) - : animationEntry.element; + var carry = 0; + for (var i = 0; i < b.length; i++) { + r = (a.words[i] | 0) - (b.words[i] | 0) + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } + for (; carry !== 0 && i < a.length; i++) { + r = (a.words[i] | 0) + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } - if (getRunner(targetElement)) { - var operation = invokeFirstDriver(animationEntry); - if (operation) { - startAnimationFn = operation.start; - } - } + // Copy rest of the words + if (carry === 0 && i < a.length && a !== this) { + for (; i < a.length; i++) { + this.words[i] = a.words[i]; + } + } - if (!startAnimationFn) { - closeFn(); - } else { - var animationRunner = startAnimationFn(); - animationRunner.done(function(status) { - closeFn(!status); - }); - updateAnimationRunners(animationEntry, animationRunner); - } - } - }); - }); + this.length = Math.max(this.length, i); - // we need to sort each of the animations in order of parent to child - // relationships. This ensures that the child classes are applied at the - // right time. - var finalAnimations = sortAnimations(toBeSortedAnimations); - for (var i = 0; i < finalAnimations.length; i++) { - var innerArray = finalAnimations[i]; - for (var j = 0; j < innerArray.length; j++) { - var entry = innerArray[j]; - var element = entry.element; + if (a !== this) { + this.negative = 1; + } - // the RAFScheduler code only uses functions - finalAnimations[i][j] = entry.fn; + return this.strip(); + }; - // the first row of elements shouldn't have a prepare-class added to them - // since the elements are at the top of the animation hierarchy and they - // will be applied without a RAF having to pass... - if (i === 0) { - element.removeData(PREPARE_CLASSES_KEY); - continue; - } + // Subtract `num` from `this` + BN.prototype.sub = function sub (num) { + return this.clone().isub(num); + }; - var prepareClassName = element.data(PREPARE_CLASSES_KEY); - if (prepareClassName) { - $$jqLite.addClass(element, prepareClassName); - } - } - } + function smallMulTo (self, num, out) { + out.negative = num.negative ^ self.negative; + var len = (self.length + num.length) | 0; + out.length = len; + len = (len - 1) | 0; - $$rAFScheduler(finalAnimations); - }); + // Peel one iteration (compiler can't do it, because of code complexity) + var a = self.words[0] | 0; + var b = num.words[0] | 0; + var r = a * b; - return runner; + var lo = r & 0x3ffffff; + var carry = (r / 0x4000000) | 0; + out.words[0] = lo; - // TODO(matsko): change to reference nodes - function getAnchorNodes(node) { - var SELECTOR = '[' + NG_ANIMATE_REF_ATTR + ']'; - var items = node.hasAttribute(NG_ANIMATE_REF_ATTR) - ? [node] - : node.querySelectorAll(SELECTOR); - var anchors = []; - forEach(items, function(node) { - var attr = node.getAttribute(NG_ANIMATE_REF_ATTR); - if (attr && attr.length) { - anchors.push(node); - } - }); - return anchors; + for (var k = 1; k < len; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = carry >>> 26; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { + var i = (k - j) | 0; + a = self.words[i] | 0; + b = num.words[j] | 0; + r = a * b + rword; + ncarry += (r / 0x4000000) | 0; + rword = r & 0x3ffffff; } + out.words[k] = rword | 0; + carry = ncarry | 0; + } + if (carry !== 0) { + out.words[k] = carry | 0; + } else { + out.length--; + } - function groupAnimations(animations) { - var preparedAnimations = []; - var refLookup = {}; - forEach(animations, function(animation, index) { - var element = animation.element; - var node = getDomNode(element); - var event = animation.event; - var enterOrMove = ['enter', 'move'].indexOf(event) >= 0; - var anchorNodes = animation.structural ? getAnchorNodes(node) : []; - - if (anchorNodes.length) { - var direction = enterOrMove ? 'to' : 'from'; - - forEach(anchorNodes, function(anchor) { - var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR); - refLookup[key] = refLookup[key] || {}; - refLookup[key][direction] = { - animationID: index, - element: jqLite(anchor) - }; - }); - } else { - preparedAnimations.push(animation); - } - }); - - var usedIndicesLookup = {}; - var anchorGroups = {}; - forEach(refLookup, function(operations, key) { - var from = operations.from; - var to = operations.to; - - if (!from || !to) { - // only one of these is set therefore we can't have an - // anchor animation since all three pieces are required - var index = from ? from.animationID : to.animationID; - var indexKey = index.toString(); - if (!usedIndicesLookup[indexKey]) { - usedIndicesLookup[indexKey] = true; - preparedAnimations.push(animations[index]); - } - return; - } + return out.strip(); + } - var fromAnimation = animations[from.animationID]; - var toAnimation = animations[to.animationID]; - var lookupKey = from.animationID.toString(); - if (!anchorGroups[lookupKey]) { - var group = anchorGroups[lookupKey] = { - structural: true, - beforeStart: function() { - fromAnimation.beforeStart(); - toAnimation.beforeStart(); - }, - close: function() { - fromAnimation.close(); - toAnimation.close(); - }, - classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes), - from: fromAnimation, - to: toAnimation, - anchors: [] // TODO(matsko): change to reference nodes - }; + // TODO(indutny): it may be reasonable to omit it for users who don't need + // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit + // multiplication (like elliptic secp256k1). + var comb10MulTo = function comb10MulTo (self, num, out) { + var a = self.words; + var b = num.words; + var o = out.words; + var c = 0; + var lo; + var mid; + var hi; + var a0 = a[0] | 0; + var al0 = a0 & 0x1fff; + var ah0 = a0 >>> 13; + var a1 = a[1] | 0; + var al1 = a1 & 0x1fff; + var ah1 = a1 >>> 13; + var a2 = a[2] | 0; + var al2 = a2 & 0x1fff; + var ah2 = a2 >>> 13; + var a3 = a[3] | 0; + var al3 = a3 & 0x1fff; + var ah3 = a3 >>> 13; + var a4 = a[4] | 0; + var al4 = a4 & 0x1fff; + var ah4 = a4 >>> 13; + var a5 = a[5] | 0; + var al5 = a5 & 0x1fff; + var ah5 = a5 >>> 13; + var a6 = a[6] | 0; + var al6 = a6 & 0x1fff; + var ah6 = a6 >>> 13; + var a7 = a[7] | 0; + var al7 = a7 & 0x1fff; + var ah7 = a7 >>> 13; + var a8 = a[8] | 0; + var al8 = a8 & 0x1fff; + var ah8 = a8 >>> 13; + var a9 = a[9] | 0; + var al9 = a9 & 0x1fff; + var ah9 = a9 >>> 13; + var b0 = b[0] | 0; + var bl0 = b0 & 0x1fff; + var bh0 = b0 >>> 13; + var b1 = b[1] | 0; + var bl1 = b1 & 0x1fff; + var bh1 = b1 >>> 13; + var b2 = b[2] | 0; + var bl2 = b2 & 0x1fff; + var bh2 = b2 >>> 13; + var b3 = b[3] | 0; + var bl3 = b3 & 0x1fff; + var bh3 = b3 >>> 13; + var b4 = b[4] | 0; + var bl4 = b4 & 0x1fff; + var bh4 = b4 >>> 13; + var b5 = b[5] | 0; + var bl5 = b5 & 0x1fff; + var bh5 = b5 >>> 13; + var b6 = b[6] | 0; + var bl6 = b6 & 0x1fff; + var bh6 = b6 >>> 13; + var b7 = b[7] | 0; + var bl7 = b7 & 0x1fff; + var bh7 = b7 >>> 13; + var b8 = b[8] | 0; + var bl8 = b8 & 0x1fff; + var bh8 = b8 >>> 13; + var b9 = b[9] | 0; + var bl9 = b9 & 0x1fff; + var bh9 = b9 >>> 13; - // the anchor animations require that the from and to elements both have at least - // one shared CSS class which effectively marries the two elements together to use - // the same animation driver and to properly sequence the anchor animation. - if (group.classes.length) { - preparedAnimations.push(group); - } else { - preparedAnimations.push(fromAnimation); - preparedAnimations.push(toAnimation); - } - } + out.negative = self.negative ^ num.negative; + out.length = 19; + /* k = 0 */ + lo = Math.imul(al0, bl0); + mid = Math.imul(al0, bh0); + mid = (mid + Math.imul(ah0, bl0)) | 0; + hi = Math.imul(ah0, bh0); + var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0; + w0 &= 0x3ffffff; + /* k = 1 */ + lo = Math.imul(al1, bl0); + mid = Math.imul(al1, bh0); + mid = (mid + Math.imul(ah1, bl0)) | 0; + hi = Math.imul(ah1, bh0); + lo = (lo + Math.imul(al0, bl1)) | 0; + mid = (mid + Math.imul(al0, bh1)) | 0; + mid = (mid + Math.imul(ah0, bl1)) | 0; + hi = (hi + Math.imul(ah0, bh1)) | 0; + var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0; + w1 &= 0x3ffffff; + /* k = 2 */ + lo = Math.imul(al2, bl0); + mid = Math.imul(al2, bh0); + mid = (mid + Math.imul(ah2, bl0)) | 0; + hi = Math.imul(ah2, bh0); + lo = (lo + Math.imul(al1, bl1)) | 0; + mid = (mid + Math.imul(al1, bh1)) | 0; + mid = (mid + Math.imul(ah1, bl1)) | 0; + hi = (hi + Math.imul(ah1, bh1)) | 0; + lo = (lo + Math.imul(al0, bl2)) | 0; + mid = (mid + Math.imul(al0, bh2)) | 0; + mid = (mid + Math.imul(ah0, bl2)) | 0; + hi = (hi + Math.imul(ah0, bh2)) | 0; + var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0; + w2 &= 0x3ffffff; + /* k = 3 */ + lo = Math.imul(al3, bl0); + mid = Math.imul(al3, bh0); + mid = (mid + Math.imul(ah3, bl0)) | 0; + hi = Math.imul(ah3, bh0); + lo = (lo + Math.imul(al2, bl1)) | 0; + mid = (mid + Math.imul(al2, bh1)) | 0; + mid = (mid + Math.imul(ah2, bl1)) | 0; + hi = (hi + Math.imul(ah2, bh1)) | 0; + lo = (lo + Math.imul(al1, bl2)) | 0; + mid = (mid + Math.imul(al1, bh2)) | 0; + mid = (mid + Math.imul(ah1, bl2)) | 0; + hi = (hi + Math.imul(ah1, bh2)) | 0; + lo = (lo + Math.imul(al0, bl3)) | 0; + mid = (mid + Math.imul(al0, bh3)) | 0; + mid = (mid + Math.imul(ah0, bl3)) | 0; + hi = (hi + Math.imul(ah0, bh3)) | 0; + var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0; + w3 &= 0x3ffffff; + /* k = 4 */ + lo = Math.imul(al4, bl0); + mid = Math.imul(al4, bh0); + mid = (mid + Math.imul(ah4, bl0)) | 0; + hi = Math.imul(ah4, bh0); + lo = (lo + Math.imul(al3, bl1)) | 0; + mid = (mid + Math.imul(al3, bh1)) | 0; + mid = (mid + Math.imul(ah3, bl1)) | 0; + hi = (hi + Math.imul(ah3, bh1)) | 0; + lo = (lo + Math.imul(al2, bl2)) | 0; + mid = (mid + Math.imul(al2, bh2)) | 0; + mid = (mid + Math.imul(ah2, bl2)) | 0; + hi = (hi + Math.imul(ah2, bh2)) | 0; + lo = (lo + Math.imul(al1, bl3)) | 0; + mid = (mid + Math.imul(al1, bh3)) | 0; + mid = (mid + Math.imul(ah1, bl3)) | 0; + hi = (hi + Math.imul(ah1, bh3)) | 0; + lo = (lo + Math.imul(al0, bl4)) | 0; + mid = (mid + Math.imul(al0, bh4)) | 0; + mid = (mid + Math.imul(ah0, bl4)) | 0; + hi = (hi + Math.imul(ah0, bh4)) | 0; + var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0; + w4 &= 0x3ffffff; + /* k = 5 */ + lo = Math.imul(al5, bl0); + mid = Math.imul(al5, bh0); + mid = (mid + Math.imul(ah5, bl0)) | 0; + hi = Math.imul(ah5, bh0); + lo = (lo + Math.imul(al4, bl1)) | 0; + mid = (mid + Math.imul(al4, bh1)) | 0; + mid = (mid + Math.imul(ah4, bl1)) | 0; + hi = (hi + Math.imul(ah4, bh1)) | 0; + lo = (lo + Math.imul(al3, bl2)) | 0; + mid = (mid + Math.imul(al3, bh2)) | 0; + mid = (mid + Math.imul(ah3, bl2)) | 0; + hi = (hi + Math.imul(ah3, bh2)) | 0; + lo = (lo + Math.imul(al2, bl3)) | 0; + mid = (mid + Math.imul(al2, bh3)) | 0; + mid = (mid + Math.imul(ah2, bl3)) | 0; + hi = (hi + Math.imul(ah2, bh3)) | 0; + lo = (lo + Math.imul(al1, bl4)) | 0; + mid = (mid + Math.imul(al1, bh4)) | 0; + mid = (mid + Math.imul(ah1, bl4)) | 0; + hi = (hi + Math.imul(ah1, bh4)) | 0; + lo = (lo + Math.imul(al0, bl5)) | 0; + mid = (mid + Math.imul(al0, bh5)) | 0; + mid = (mid + Math.imul(ah0, bl5)) | 0; + hi = (hi + Math.imul(ah0, bh5)) | 0; + var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0; + w5 &= 0x3ffffff; + /* k = 6 */ + lo = Math.imul(al6, bl0); + mid = Math.imul(al6, bh0); + mid = (mid + Math.imul(ah6, bl0)) | 0; + hi = Math.imul(ah6, bh0); + lo = (lo + Math.imul(al5, bl1)) | 0; + mid = (mid + Math.imul(al5, bh1)) | 0; + mid = (mid + Math.imul(ah5, bl1)) | 0; + hi = (hi + Math.imul(ah5, bh1)) | 0; + lo = (lo + Math.imul(al4, bl2)) | 0; + mid = (mid + Math.imul(al4, bh2)) | 0; + mid = (mid + Math.imul(ah4, bl2)) | 0; + hi = (hi + Math.imul(ah4, bh2)) | 0; + lo = (lo + Math.imul(al3, bl3)) | 0; + mid = (mid + Math.imul(al3, bh3)) | 0; + mid = (mid + Math.imul(ah3, bl3)) | 0; + hi = (hi + Math.imul(ah3, bh3)) | 0; + lo = (lo + Math.imul(al2, bl4)) | 0; + mid = (mid + Math.imul(al2, bh4)) | 0; + mid = (mid + Math.imul(ah2, bl4)) | 0; + hi = (hi + Math.imul(ah2, bh4)) | 0; + lo = (lo + Math.imul(al1, bl5)) | 0; + mid = (mid + Math.imul(al1, bh5)) | 0; + mid = (mid + Math.imul(ah1, bl5)) | 0; + hi = (hi + Math.imul(ah1, bh5)) | 0; + lo = (lo + Math.imul(al0, bl6)) | 0; + mid = (mid + Math.imul(al0, bh6)) | 0; + mid = (mid + Math.imul(ah0, bl6)) | 0; + hi = (hi + Math.imul(ah0, bh6)) | 0; + var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0; + w6 &= 0x3ffffff; + /* k = 7 */ + lo = Math.imul(al7, bl0); + mid = Math.imul(al7, bh0); + mid = (mid + Math.imul(ah7, bl0)) | 0; + hi = Math.imul(ah7, bh0); + lo = (lo + Math.imul(al6, bl1)) | 0; + mid = (mid + Math.imul(al6, bh1)) | 0; + mid = (mid + Math.imul(ah6, bl1)) | 0; + hi = (hi + Math.imul(ah6, bh1)) | 0; + lo = (lo + Math.imul(al5, bl2)) | 0; + mid = (mid + Math.imul(al5, bh2)) | 0; + mid = (mid + Math.imul(ah5, bl2)) | 0; + hi = (hi + Math.imul(ah5, bh2)) | 0; + lo = (lo + Math.imul(al4, bl3)) | 0; + mid = (mid + Math.imul(al4, bh3)) | 0; + mid = (mid + Math.imul(ah4, bl3)) | 0; + hi = (hi + Math.imul(ah4, bh3)) | 0; + lo = (lo + Math.imul(al3, bl4)) | 0; + mid = (mid + Math.imul(al3, bh4)) | 0; + mid = (mid + Math.imul(ah3, bl4)) | 0; + hi = (hi + Math.imul(ah3, bh4)) | 0; + lo = (lo + Math.imul(al2, bl5)) | 0; + mid = (mid + Math.imul(al2, bh5)) | 0; + mid = (mid + Math.imul(ah2, bl5)) | 0; + hi = (hi + Math.imul(ah2, bh5)) | 0; + lo = (lo + Math.imul(al1, bl6)) | 0; + mid = (mid + Math.imul(al1, bh6)) | 0; + mid = (mid + Math.imul(ah1, bl6)) | 0; + hi = (hi + Math.imul(ah1, bh6)) | 0; + lo = (lo + Math.imul(al0, bl7)) | 0; + mid = (mid + Math.imul(al0, bh7)) | 0; + mid = (mid + Math.imul(ah0, bl7)) | 0; + hi = (hi + Math.imul(ah0, bh7)) | 0; + var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0; + w7 &= 0x3ffffff; + /* k = 8 */ + lo = Math.imul(al8, bl0); + mid = Math.imul(al8, bh0); + mid = (mid + Math.imul(ah8, bl0)) | 0; + hi = Math.imul(ah8, bh0); + lo = (lo + Math.imul(al7, bl1)) | 0; + mid = (mid + Math.imul(al7, bh1)) | 0; + mid = (mid + Math.imul(ah7, bl1)) | 0; + hi = (hi + Math.imul(ah7, bh1)) | 0; + lo = (lo + Math.imul(al6, bl2)) | 0; + mid = (mid + Math.imul(al6, bh2)) | 0; + mid = (mid + Math.imul(ah6, bl2)) | 0; + hi = (hi + Math.imul(ah6, bh2)) | 0; + lo = (lo + Math.imul(al5, bl3)) | 0; + mid = (mid + Math.imul(al5, bh3)) | 0; + mid = (mid + Math.imul(ah5, bl3)) | 0; + hi = (hi + Math.imul(ah5, bh3)) | 0; + lo = (lo + Math.imul(al4, bl4)) | 0; + mid = (mid + Math.imul(al4, bh4)) | 0; + mid = (mid + Math.imul(ah4, bl4)) | 0; + hi = (hi + Math.imul(ah4, bh4)) | 0; + lo = (lo + Math.imul(al3, bl5)) | 0; + mid = (mid + Math.imul(al3, bh5)) | 0; + mid = (mid + Math.imul(ah3, bl5)) | 0; + hi = (hi + Math.imul(ah3, bh5)) | 0; + lo = (lo + Math.imul(al2, bl6)) | 0; + mid = (mid + Math.imul(al2, bh6)) | 0; + mid = (mid + Math.imul(ah2, bl6)) | 0; + hi = (hi + Math.imul(ah2, bh6)) | 0; + lo = (lo + Math.imul(al1, bl7)) | 0; + mid = (mid + Math.imul(al1, bh7)) | 0; + mid = (mid + Math.imul(ah1, bl7)) | 0; + hi = (hi + Math.imul(ah1, bh7)) | 0; + lo = (lo + Math.imul(al0, bl8)) | 0; + mid = (mid + Math.imul(al0, bh8)) | 0; + mid = (mid + Math.imul(ah0, bl8)) | 0; + hi = (hi + Math.imul(ah0, bh8)) | 0; + var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0; + w8 &= 0x3ffffff; + /* k = 9 */ + lo = Math.imul(al9, bl0); + mid = Math.imul(al9, bh0); + mid = (mid + Math.imul(ah9, bl0)) | 0; + hi = Math.imul(ah9, bh0); + lo = (lo + Math.imul(al8, bl1)) | 0; + mid = (mid + Math.imul(al8, bh1)) | 0; + mid = (mid + Math.imul(ah8, bl1)) | 0; + hi = (hi + Math.imul(ah8, bh1)) | 0; + lo = (lo + Math.imul(al7, bl2)) | 0; + mid = (mid + Math.imul(al7, bh2)) | 0; + mid = (mid + Math.imul(ah7, bl2)) | 0; + hi = (hi + Math.imul(ah7, bh2)) | 0; + lo = (lo + Math.imul(al6, bl3)) | 0; + mid = (mid + Math.imul(al6, bh3)) | 0; + mid = (mid + Math.imul(ah6, bl3)) | 0; + hi = (hi + Math.imul(ah6, bh3)) | 0; + lo = (lo + Math.imul(al5, bl4)) | 0; + mid = (mid + Math.imul(al5, bh4)) | 0; + mid = (mid + Math.imul(ah5, bl4)) | 0; + hi = (hi + Math.imul(ah5, bh4)) | 0; + lo = (lo + Math.imul(al4, bl5)) | 0; + mid = (mid + Math.imul(al4, bh5)) | 0; + mid = (mid + Math.imul(ah4, bl5)) | 0; + hi = (hi + Math.imul(ah4, bh5)) | 0; + lo = (lo + Math.imul(al3, bl6)) | 0; + mid = (mid + Math.imul(al3, bh6)) | 0; + mid = (mid + Math.imul(ah3, bl6)) | 0; + hi = (hi + Math.imul(ah3, bh6)) | 0; + lo = (lo + Math.imul(al2, bl7)) | 0; + mid = (mid + Math.imul(al2, bh7)) | 0; + mid = (mid + Math.imul(ah2, bl7)) | 0; + hi = (hi + Math.imul(ah2, bh7)) | 0; + lo = (lo + Math.imul(al1, bl8)) | 0; + mid = (mid + Math.imul(al1, bh8)) | 0; + mid = (mid + Math.imul(ah1, bl8)) | 0; + hi = (hi + Math.imul(ah1, bh8)) | 0; + lo = (lo + Math.imul(al0, bl9)) | 0; + mid = (mid + Math.imul(al0, bh9)) | 0; + mid = (mid + Math.imul(ah0, bl9)) | 0; + hi = (hi + Math.imul(ah0, bh9)) | 0; + var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0; + w9 &= 0x3ffffff; + /* k = 10 */ + lo = Math.imul(al9, bl1); + mid = Math.imul(al9, bh1); + mid = (mid + Math.imul(ah9, bl1)) | 0; + hi = Math.imul(ah9, bh1); + lo = (lo + Math.imul(al8, bl2)) | 0; + mid = (mid + Math.imul(al8, bh2)) | 0; + mid = (mid + Math.imul(ah8, bl2)) | 0; + hi = (hi + Math.imul(ah8, bh2)) | 0; + lo = (lo + Math.imul(al7, bl3)) | 0; + mid = (mid + Math.imul(al7, bh3)) | 0; + mid = (mid + Math.imul(ah7, bl3)) | 0; + hi = (hi + Math.imul(ah7, bh3)) | 0; + lo = (lo + Math.imul(al6, bl4)) | 0; + mid = (mid + Math.imul(al6, bh4)) | 0; + mid = (mid + Math.imul(ah6, bl4)) | 0; + hi = (hi + Math.imul(ah6, bh4)) | 0; + lo = (lo + Math.imul(al5, bl5)) | 0; + mid = (mid + Math.imul(al5, bh5)) | 0; + mid = (mid + Math.imul(ah5, bl5)) | 0; + hi = (hi + Math.imul(ah5, bh5)) | 0; + lo = (lo + Math.imul(al4, bl6)) | 0; + mid = (mid + Math.imul(al4, bh6)) | 0; + mid = (mid + Math.imul(ah4, bl6)) | 0; + hi = (hi + Math.imul(ah4, bh6)) | 0; + lo = (lo + Math.imul(al3, bl7)) | 0; + mid = (mid + Math.imul(al3, bh7)) | 0; + mid = (mid + Math.imul(ah3, bl7)) | 0; + hi = (hi + Math.imul(ah3, bh7)) | 0; + lo = (lo + Math.imul(al2, bl8)) | 0; + mid = (mid + Math.imul(al2, bh8)) | 0; + mid = (mid + Math.imul(ah2, bl8)) | 0; + hi = (hi + Math.imul(ah2, bh8)) | 0; + lo = (lo + Math.imul(al1, bl9)) | 0; + mid = (mid + Math.imul(al1, bh9)) | 0; + mid = (mid + Math.imul(ah1, bl9)) | 0; + hi = (hi + Math.imul(ah1, bh9)) | 0; + var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0; + w10 &= 0x3ffffff; + /* k = 11 */ + lo = Math.imul(al9, bl2); + mid = Math.imul(al9, bh2); + mid = (mid + Math.imul(ah9, bl2)) | 0; + hi = Math.imul(ah9, bh2); + lo = (lo + Math.imul(al8, bl3)) | 0; + mid = (mid + Math.imul(al8, bh3)) | 0; + mid = (mid + Math.imul(ah8, bl3)) | 0; + hi = (hi + Math.imul(ah8, bh3)) | 0; + lo = (lo + Math.imul(al7, bl4)) | 0; + mid = (mid + Math.imul(al7, bh4)) | 0; + mid = (mid + Math.imul(ah7, bl4)) | 0; + hi = (hi + Math.imul(ah7, bh4)) | 0; + lo = (lo + Math.imul(al6, bl5)) | 0; + mid = (mid + Math.imul(al6, bh5)) | 0; + mid = (mid + Math.imul(ah6, bl5)) | 0; + hi = (hi + Math.imul(ah6, bh5)) | 0; + lo = (lo + Math.imul(al5, bl6)) | 0; + mid = (mid + Math.imul(al5, bh6)) | 0; + mid = (mid + Math.imul(ah5, bl6)) | 0; + hi = (hi + Math.imul(ah5, bh6)) | 0; + lo = (lo + Math.imul(al4, bl7)) | 0; + mid = (mid + Math.imul(al4, bh7)) | 0; + mid = (mid + Math.imul(ah4, bl7)) | 0; + hi = (hi + Math.imul(ah4, bh7)) | 0; + lo = (lo + Math.imul(al3, bl8)) | 0; + mid = (mid + Math.imul(al3, bh8)) | 0; + mid = (mid + Math.imul(ah3, bl8)) | 0; + hi = (hi + Math.imul(ah3, bh8)) | 0; + lo = (lo + Math.imul(al2, bl9)) | 0; + mid = (mid + Math.imul(al2, bh9)) | 0; + mid = (mid + Math.imul(ah2, bl9)) | 0; + hi = (hi + Math.imul(ah2, bh9)) | 0; + var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0; + w11 &= 0x3ffffff; + /* k = 12 */ + lo = Math.imul(al9, bl3); + mid = Math.imul(al9, bh3); + mid = (mid + Math.imul(ah9, bl3)) | 0; + hi = Math.imul(ah9, bh3); + lo = (lo + Math.imul(al8, bl4)) | 0; + mid = (mid + Math.imul(al8, bh4)) | 0; + mid = (mid + Math.imul(ah8, bl4)) | 0; + hi = (hi + Math.imul(ah8, bh4)) | 0; + lo = (lo + Math.imul(al7, bl5)) | 0; + mid = (mid + Math.imul(al7, bh5)) | 0; + mid = (mid + Math.imul(ah7, bl5)) | 0; + hi = (hi + Math.imul(ah7, bh5)) | 0; + lo = (lo + Math.imul(al6, bl6)) | 0; + mid = (mid + Math.imul(al6, bh6)) | 0; + mid = (mid + Math.imul(ah6, bl6)) | 0; + hi = (hi + Math.imul(ah6, bh6)) | 0; + lo = (lo + Math.imul(al5, bl7)) | 0; + mid = (mid + Math.imul(al5, bh7)) | 0; + mid = (mid + Math.imul(ah5, bl7)) | 0; + hi = (hi + Math.imul(ah5, bh7)) | 0; + lo = (lo + Math.imul(al4, bl8)) | 0; + mid = (mid + Math.imul(al4, bh8)) | 0; + mid = (mid + Math.imul(ah4, bl8)) | 0; + hi = (hi + Math.imul(ah4, bh8)) | 0; + lo = (lo + Math.imul(al3, bl9)) | 0; + mid = (mid + Math.imul(al3, bh9)) | 0; + mid = (mid + Math.imul(ah3, bl9)) | 0; + hi = (hi + Math.imul(ah3, bh9)) | 0; + var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0; + w12 &= 0x3ffffff; + /* k = 13 */ + lo = Math.imul(al9, bl4); + mid = Math.imul(al9, bh4); + mid = (mid + Math.imul(ah9, bl4)) | 0; + hi = Math.imul(ah9, bh4); + lo = (lo + Math.imul(al8, bl5)) | 0; + mid = (mid + Math.imul(al8, bh5)) | 0; + mid = (mid + Math.imul(ah8, bl5)) | 0; + hi = (hi + Math.imul(ah8, bh5)) | 0; + lo = (lo + Math.imul(al7, bl6)) | 0; + mid = (mid + Math.imul(al7, bh6)) | 0; + mid = (mid + Math.imul(ah7, bl6)) | 0; + hi = (hi + Math.imul(ah7, bh6)) | 0; + lo = (lo + Math.imul(al6, bl7)) | 0; + mid = (mid + Math.imul(al6, bh7)) | 0; + mid = (mid + Math.imul(ah6, bl7)) | 0; + hi = (hi + Math.imul(ah6, bh7)) | 0; + lo = (lo + Math.imul(al5, bl8)) | 0; + mid = (mid + Math.imul(al5, bh8)) | 0; + mid = (mid + Math.imul(ah5, bl8)) | 0; + hi = (hi + Math.imul(ah5, bh8)) | 0; + lo = (lo + Math.imul(al4, bl9)) | 0; + mid = (mid + Math.imul(al4, bh9)) | 0; + mid = (mid + Math.imul(ah4, bl9)) | 0; + hi = (hi + Math.imul(ah4, bh9)) | 0; + var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0; + w13 &= 0x3ffffff; + /* k = 14 */ + lo = Math.imul(al9, bl5); + mid = Math.imul(al9, bh5); + mid = (mid + Math.imul(ah9, bl5)) | 0; + hi = Math.imul(ah9, bh5); + lo = (lo + Math.imul(al8, bl6)) | 0; + mid = (mid + Math.imul(al8, bh6)) | 0; + mid = (mid + Math.imul(ah8, bl6)) | 0; + hi = (hi + Math.imul(ah8, bh6)) | 0; + lo = (lo + Math.imul(al7, bl7)) | 0; + mid = (mid + Math.imul(al7, bh7)) | 0; + mid = (mid + Math.imul(ah7, bl7)) | 0; + hi = (hi + Math.imul(ah7, bh7)) | 0; + lo = (lo + Math.imul(al6, bl8)) | 0; + mid = (mid + Math.imul(al6, bh8)) | 0; + mid = (mid + Math.imul(ah6, bl8)) | 0; + hi = (hi + Math.imul(ah6, bh8)) | 0; + lo = (lo + Math.imul(al5, bl9)) | 0; + mid = (mid + Math.imul(al5, bh9)) | 0; + mid = (mid + Math.imul(ah5, bl9)) | 0; + hi = (hi + Math.imul(ah5, bh9)) | 0; + var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0; + w14 &= 0x3ffffff; + /* k = 15 */ + lo = Math.imul(al9, bl6); + mid = Math.imul(al9, bh6); + mid = (mid + Math.imul(ah9, bl6)) | 0; + hi = Math.imul(ah9, bh6); + lo = (lo + Math.imul(al8, bl7)) | 0; + mid = (mid + Math.imul(al8, bh7)) | 0; + mid = (mid + Math.imul(ah8, bl7)) | 0; + hi = (hi + Math.imul(ah8, bh7)) | 0; + lo = (lo + Math.imul(al7, bl8)) | 0; + mid = (mid + Math.imul(al7, bh8)) | 0; + mid = (mid + Math.imul(ah7, bl8)) | 0; + hi = (hi + Math.imul(ah7, bh8)) | 0; + lo = (lo + Math.imul(al6, bl9)) | 0; + mid = (mid + Math.imul(al6, bh9)) | 0; + mid = (mid + Math.imul(ah6, bl9)) | 0; + hi = (hi + Math.imul(ah6, bh9)) | 0; + var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0; + w15 &= 0x3ffffff; + /* k = 16 */ + lo = Math.imul(al9, bl7); + mid = Math.imul(al9, bh7); + mid = (mid + Math.imul(ah9, bl7)) | 0; + hi = Math.imul(ah9, bh7); + lo = (lo + Math.imul(al8, bl8)) | 0; + mid = (mid + Math.imul(al8, bh8)) | 0; + mid = (mid + Math.imul(ah8, bl8)) | 0; + hi = (hi + Math.imul(ah8, bh8)) | 0; + lo = (lo + Math.imul(al7, bl9)) | 0; + mid = (mid + Math.imul(al7, bh9)) | 0; + mid = (mid + Math.imul(ah7, bl9)) | 0; + hi = (hi + Math.imul(ah7, bh9)) | 0; + var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0; + w16 &= 0x3ffffff; + /* k = 17 */ + lo = Math.imul(al9, bl8); + mid = Math.imul(al9, bh8); + mid = (mid + Math.imul(ah9, bl8)) | 0; + hi = Math.imul(ah9, bh8); + lo = (lo + Math.imul(al8, bl9)) | 0; + mid = (mid + Math.imul(al8, bh9)) | 0; + mid = (mid + Math.imul(ah8, bl9)) | 0; + hi = (hi + Math.imul(ah8, bh9)) | 0; + var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0; + w17 &= 0x3ffffff; + /* k = 18 */ + lo = Math.imul(al9, bl9); + mid = Math.imul(al9, bh9); + mid = (mid + Math.imul(ah9, bl9)) | 0; + hi = Math.imul(ah9, bh9); + var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0; + c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0; + w18 &= 0x3ffffff; + o[0] = w0; + o[1] = w1; + o[2] = w2; + o[3] = w3; + o[4] = w4; + o[5] = w5; + o[6] = w6; + o[7] = w7; + o[8] = w8; + o[9] = w9; + o[10] = w10; + o[11] = w11; + o[12] = w12; + o[13] = w13; + o[14] = w14; + o[15] = w15; + o[16] = w16; + o[17] = w17; + o[18] = w18; + if (c !== 0) { + o[19] = c; + out.length++; + } + return out; + }; - anchorGroups[lookupKey].anchors.push({ - 'out': from.element, 'in': to.element - }); - }); + // Polyfill comb + if (!Math.imul) { + comb10MulTo = smallMulTo; + } - return preparedAnimations; + function bigMulTo (self, num, out) { + out.negative = num.negative ^ self.negative; + out.length = self.length + num.length; + + var carry = 0; + var hncarry = 0; + for (var k = 0; k < out.length - 1; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = hncarry; + hncarry = 0; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = self.words[i] | 0; + var b = num.words[j] | 0; + var r = a * b; + + var lo = r & 0x3ffffff; + ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; + lo = (lo + rword) | 0; + rword = lo & 0x3ffffff; + ncarry = (ncarry + (lo >>> 26)) | 0; + + hncarry += ncarry >>> 26; + ncarry &= 0x3ffffff; } + out.words[k] = rword; + carry = ncarry; + ncarry = hncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } - function cssClassesIntersection(a,b) { - a = a.split(' '); - b = b.split(' '); - var matches = []; + return out.strip(); + } - for (var i = 0; i < a.length; i++) { - var aa = a[i]; - if (aa.substring(0,3) === 'ng-') continue; + function jumboMulTo (self, num, out) { + var fftm = new FFTM(); + return fftm.mulp(self, num, out); + } - for (var j = 0; j < b.length; j++) { - if (aa === b[j]) { - matches.push(aa); - break; - } - } - } + BN.prototype.mulTo = function mulTo (num, out) { + var res; + var len = this.length + num.length; + if (this.length === 10 && num.length === 10) { + res = comb10MulTo(this, num, out); + } else if (len < 63) { + res = smallMulTo(this, num, out); + } else if (len < 1024) { + res = bigMulTo(this, num, out); + } else { + res = jumboMulTo(this, num, out); + } - return matches.join(' '); - } + return res; + }; - function invokeFirstDriver(animationDetails) { - // we loop in reverse order since the more general drivers (like CSS and JS) - // may attempt more elements, but custom drivers are more particular - for (var i = drivers.length - 1; i >= 0; i--) { - var driverName = drivers[i]; - var factory = $injector.get(driverName); - var driver = factory(animationDetails); - if (driver) { - return driver; + // Cooley-Tukey algorithm for FFT + // slightly revisited to rely on looping instead of recursion + + function FFTM (x, y) { + this.x = x; + this.y = y; + } + + FFTM.prototype.makeRBT = function makeRBT (N) { + var t = new Array(N); + var l = BN.prototype._countBits(N) - 1; + for (var i = 0; i < N; i++) { + t[i] = this.revBin(i, l, N); + } + + return t; + }; + + // Returns binary-reversed representation of `x` + FFTM.prototype.revBin = function revBin (x, l, N) { + if (x === 0 || x === N - 1) return x; + + var rb = 0; + for (var i = 0; i < l; i++) { + rb |= (x & 1) << (l - i - 1); + x >>= 1; + } + + return rb; + }; + + // Performs "tweedling" phase, therefore 'emulating' + // behaviour of the recursive algorithm + FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) { + for (var i = 0; i < N; i++) { + rtws[i] = rws[rbt[i]]; + itws[i] = iws[rbt[i]]; + } + }; + + FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) { + this.permute(rbt, rws, iws, rtws, itws, N); + + for (var s = 1; s < N; s <<= 1) { + var l = s << 1; + + var rtwdf = Math.cos(2 * Math.PI / l); + var itwdf = Math.sin(2 * Math.PI / l); + + for (var p = 0; p < N; p += l) { + var rtwdf_ = rtwdf; + var itwdf_ = itwdf; + + for (var j = 0; j < s; j++) { + var re = rtws[p + j]; + var ie = itws[p + j]; + + var ro = rtws[p + j + s]; + var io = itws[p + j + s]; + + var rx = rtwdf_ * ro - itwdf_ * io; + + io = rtwdf_ * io + itwdf_ * ro; + ro = rx; + + rtws[p + j] = re + ro; + itws[p + j] = ie + io; + + rtws[p + j + s] = re - ro; + itws[p + j + s] = ie - io; + + /* jshint maxdepth : false */ + if (j !== l) { + rx = rtwdf * rtwdf_ - itwdf * itwdf_; + + itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_; + rtwdf_ = rx; } } } + } + }; - function beforeStart() { - tempClasses = (tempClasses ? (tempClasses + ' ') : '') + NG_ANIMATE_CLASSNAME; - $$jqLite.addClass(element, tempClasses); + FFTM.prototype.guessLen13b = function guessLen13b (n, m) { + var N = Math.max(m, n) | 1; + var odd = N & 1; + var i = 0; + for (N = N / 2 | 0; N; N = N >>> 1) { + i++; + } - var prepareClassName = element.data(PREPARE_CLASSES_KEY); - if (prepareClassName) { - $$jqLite.removeClass(element, prepareClassName); - prepareClassName = null; - } - } + return 1 << i + 1 + odd; + }; - function updateAnimationRunners(animation, newRunner) { - if (animation.from && animation.to) { - update(animation.from.element); - update(animation.to.element); - } else { - update(animation.element); - } + FFTM.prototype.conjugate = function conjugate (rws, iws, N) { + if (N <= 1) return; - function update(element) { - var runner = getRunner(element); - if (runner) runner.setHost(newRunner); - } - } + for (var i = 0; i < N / 2; i++) { + var t = rws[i]; - function handleDestroyedElement() { - var runner = getRunner(element); - if (runner && (event !== 'leave' || !options.$$domOperationFired)) { - runner.end(); - } - } + rws[i] = rws[N - i - 1]; + rws[N - i - 1] = t; - function close(rejected) { - element.off('$destroy', handleDestroyedElement); - removeRunner(element); + t = iws[i]; - applyAnimationClasses(element, options); - applyAnimationStyles(element, options); - options.domOperation(); + iws[i] = -iws[N - i - 1]; + iws[N - i - 1] = -t; + } + }; - if (tempClasses) { - $$jqLite.removeClass(element, tempClasses); - } + FFTM.prototype.normalize13b = function normalize13b (ws, N) { + var carry = 0; + for (var i = 0; i < N / 2; i++) { + var w = Math.round(ws[2 * i + 1] / N) * 0x2000 + + Math.round(ws[2 * i] / N) + + carry; - runner.complete(!rejected); + ws[i] = w & 0x3ffffff; + + if (w < 0x4000000) { + carry = 0; + } else { + carry = w / 0x4000000 | 0; } - }; - }]; -}]; + } -/** - * @ngdoc directive - * @name ngAnimateSwap - * @restrict A - * @scope - * - * @description - * - * ngAnimateSwap is a animation-oriented directive that allows for the container to - * be removed and entered in whenever the associated expression changes. A - * common usecase for this directive is a rotating banner or slider component which - * contains one image being present at a time. When the active image changes - * then the old image will perform a `leave` animation and the new element - * will be inserted via an `enter` animation. - * - * @animations - * | Animation | Occurs | - * |----------------------------------|--------------------------------------| - * | {@link ng.$animate#enter enter} | when the new element is inserted to the DOM | - * | {@link ng.$animate#leave leave} | when the old element is removed from the DOM | - * - * @example - * - * - *
- *
- * {{ number }} - *
- *
- *
- * - * angular.module('ngAnimateSwapExample', ['ngAnimate']) - * .controller('AppCtrl', ['$scope', '$interval', function($scope, $interval) { - * $scope.number = 0; - * $interval(function() { - * $scope.number++; - * }, 1000); - * - * var colors = ['red','blue','green','yellow','orange']; - * $scope.colorClass = function(number) { - * return colors[number % colors.length]; - * }; - * }]); - * - * - * .container { - * height:250px; - * width:250px; - * position:relative; - * overflow:hidden; - * border:2px solid black; - * } - * .container .cell { - * font-size:150px; - * text-align:center; - * line-height:250px; - * position:absolute; - * top:0; - * left:0; - * right:0; - * border-bottom:2px solid black; - * } - * .swap-animation.ng-enter, .swap-animation.ng-leave { - * transition:0.5s linear all; - * } - * .swap-animation.ng-enter { - * top:-250px; - * } - * .swap-animation.ng-enter-active { - * top:0px; - * } - * .swap-animation.ng-leave { - * top:0px; - * } - * .swap-animation.ng-leave-active { - * top:250px; - * } - * .red { background:red; } - * .green { background:green; } - * .blue { background:blue; } - * .yellow { background:yellow; } - * .orange { background:orange; } - * - *
- */ -var ngAnimateSwapDirective = ['$animate', function($animate) { - return { - restrict: 'A', - transclude: 'element', - terminal: true, - priority: 600, // we use 600 here to ensure that the directive is caught before others - link: function(scope, $element, attrs, ctrl, $transclude) { - var previousElement, previousScope; - scope.$watchCollection(attrs.ngAnimateSwap || attrs['for'], function(value) { - if (previousElement) { - $animate.leave(previousElement); - } - if (previousScope) { - previousScope.$destroy(); - previousScope = null; - } - if (value || value === 0) { - $transclude(function(clone, childScope) { - previousElement = clone; - previousScope = childScope; - $animate.enter(clone, null, $element); - }); - } - }); + return ws; + }; + + FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) { + var carry = 0; + for (var i = 0; i < len; i++) { + carry = carry + (ws[i] | 0); + + rws[2 * i] = carry & 0x1fff; carry = carry >>> 13; + rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13; + } + + // Pad with zeroes + for (i = 2 * len; i < N; ++i) { + rws[i] = 0; } + + assert(carry === 0); + assert((carry & ~0x1fff) === 0); }; -}]; -/** - * @ngdoc module - * @name ngAnimate - * @description - * - * The `ngAnimate` module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via - * callback hooks. Animations are not enabled by default, however, by including `ngAnimate` the animation hooks are enabled for an AngularJS app. - * - * ## Usage - * Simply put, there are two ways to make use of animations when ngAnimate is used: by using **CSS** and **JavaScript**. The former works purely based - * using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via `module.animation()`. For - * both CSS and JS animations the sole requirement is to have a matching `CSS class` that exists both in the registered animation and within - * the HTML element that the animation will be triggered on. - * - * ## Directive Support - * The following directives are "animation aware": - * - * | Directive | Supported Animations | - * |-------------------------------------------------------------------------------|---------------------------------------------------------------------------| - * | {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) | - * | {@link ngAnimate.directive:ngAnimateSwap#animations ngAnimateSwap} | enter and leave | - * | {@link ng.directive:ngClass#animations ngClass / {{class}​}} | add and remove | - * | {@link ng.directive:ngClassEven#animations ngClassEven} | add and remove | - * | {@link ng.directive:ngClassOdd#animations ngClassOdd} | add and remove | - * | {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) | - * | {@link ng.directive:ngIf#animations ngIf} | enter and leave | - * | {@link ng.directive:ngInclude#animations ngInclude} | enter and leave | - * | {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave | - * | {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) | - * | {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) | - * | {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move | - * | {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) | - * | {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave | - * | {@link ngRoute.directive:ngView#animations ngView} | enter and leave | - * - * (More information can be found by visiting the documentation associated with each directive.) - * - * For a full breakdown of the steps involved during each animation event, refer to the - * {@link ng.$animate `$animate` API docs}. - * - * ## CSS-based Animations - * - * CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML - * and CSS code we can create an animation that will be picked up by AngularJS when an underlying directive performs an operation. - * - * The example below shows how an `enter` animation can be made possible on an element using `ng-if`: - * - * ```html - *
- * Fade me in out - *
- * - * - * ``` - * - * Notice the CSS class **fade**? We can now create the CSS transition code that references this class: - * - * ```css - * /* The starting CSS styles for the enter animation */ - * .fade.ng-enter { - * transition:0.5s linear all; - * opacity:0; - * } - * - * /* The finishing CSS styles for the enter animation */ - * .fade.ng-enter.ng-enter-active { - * opacity:1; - * } - * ``` - * - * The key thing to remember here is that, depending on the animation event (which each of the directives above trigger depending on what's going on) two - * generated CSS classes will be applied to the element; in the example above we have `.ng-enter` and `.ng-enter-active`. For CSS transitions, the transition - * code **must** be defined within the starting CSS class (in this case `.ng-enter`). The destination class is what the transition will animate towards. - * - * If for example we wanted to create animations for `leave` and `move` (ngRepeat triggers move) then we can do so using the same CSS naming conventions: - * - * ```css - * /* now the element will fade out before it is removed from the DOM */ - * .fade.ng-leave { - * transition:0.5s linear all; - * opacity:1; - * } - * .fade.ng-leave.ng-leave-active { - * opacity:0; - * } - * ``` - * - * We can also make use of **CSS Keyframes** by referencing the keyframe animation within the starting CSS class: - * - * ```css - * /* there is no need to define anything inside of the destination - * CSS class since the keyframe will take charge of the animation */ - * .fade.ng-leave { - * animation: my_fade_animation 0.5s linear; - * -webkit-animation: my_fade_animation 0.5s linear; - * } - * - * @keyframes my_fade_animation { - * from { opacity:1; } - * to { opacity:0; } - * } - * - * @-webkit-keyframes my_fade_animation { - * from { opacity:1; } - * to { opacity:0; } - * } - * ``` - * - * Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element. - * - * ### CSS Class-based Animations - * - * Class-based animations (animations that are triggered via `ngClass`, `ngShow`, `ngHide` and some other directives) have a slightly different - * naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added - * and removed. - * - * For example if we wanted to do a CSS animation for `ngHide` then we place an animation on the `.ng-hide` CSS class: - * - * ```html - *
- * Show and hide me - *
- * - * - * - * ``` - * - * All that is going on here with ngShow/ngHide behind the scenes is the `.ng-hide` class is added/removed (when the hidden state is valid). Since - * ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest. - * - * In addition the addition and removal of the CSS class, ngAnimate also provides two helper methods that we can use to further decorate the animation - * with CSS styles. - * - * ```html - *
- * Highlight this box - *
- * - * - * - * ``` - * - * We can also make use of CSS keyframes by placing them within the CSS classes. - * - * - * ### CSS Staggering Animations - * A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a - * curtain-like effect. The ngAnimate module (versions >=1.2) supports staggering animations and the stagger effect can be - * performed by creating a **ng-EVENT-stagger** CSS class and attaching that class to the base CSS class used for - * the animation. The style property expected within the stagger class can either be a **transition-delay** or an - * **animation-delay** property (or both if your animation contains both transitions and keyframe animations). - * - * ```css - * .my-animation.ng-enter { - * /* standard transition code */ - * transition: 1s linear all; - * opacity:0; - * } - * .my-animation.ng-enter-stagger { - * /* this will have a 100ms delay between each successive leave animation */ - * transition-delay: 0.1s; - * - * /* As of 1.4.4, this must always be set: it signals ngAnimate - * to not accidentally inherit a delay property from another CSS class */ - * transition-duration: 0s; - * - * /* if you are using animations instead of transitions you should configure as follows: - * animation-delay: 0.1s; - * animation-duration: 0s; */ - * } - * .my-animation.ng-enter.ng-enter-active { - * /* standard transition styles */ - * opacity:1; - * } - * ``` - * - * Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations - * on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this - * are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation - * will also be reset if one or more animation frames have passed since the multiple calls to `$animate` were fired. - * - * The following code will issue the **ng-leave-stagger** event on the element provided: - * - * ```js - * var kids = parent.children(); - * - * $animate.leave(kids[0]); //stagger index=0 - * $animate.leave(kids[1]); //stagger index=1 - * $animate.leave(kids[2]); //stagger index=2 - * $animate.leave(kids[3]); //stagger index=3 - * $animate.leave(kids[4]); //stagger index=4 - * - * window.requestAnimationFrame(function() { - * //stagger has reset itself - * $animate.leave(kids[5]); //stagger index=0 - * $animate.leave(kids[6]); //stagger index=1 - * - * $scope.$digest(); - * }); - * ``` - * - * Stagger animations are currently only supported within CSS-defined animations. - * - * ### The `ng-animate` CSS class - * - * When ngAnimate is animating an element it will apply the `ng-animate` CSS class to the element for the duration of the animation. - * This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations). - * - * Therefore, animations can be applied to an element using this temporary class directly via CSS. - * - * ```css - * .zipper.ng-animate { - * transition:0.5s linear all; - * } - * .zipper.ng-enter { - * opacity:0; - * } - * .zipper.ng-enter.ng-enter-active { - * opacity:1; - * } - * .zipper.ng-leave { - * opacity:1; - * } - * .zipper.ng-leave.ng-leave-active { - * opacity:0; - * } - * ``` - * - * (Note that the `ng-animate` CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove - * the CSS class once an animation has completed.) - * - * - * ### The `ng-[event]-prepare` class - * - * This is a special class that can be used to prevent unwanted flickering / flash of content before - * the actual animation starts. The class is added as soon as an animation is initialized, but removed - * before the actual animation starts (after waiting for a $digest). - * It is also only added for *structural* animations (`enter`, `move`, and `leave`). - * - * In practice, flickering can appear when nesting elements with structural animations such as `ngIf` - * into elements that have class-based animations such as `ngClass`. - * - * ```html - *
- *
- *
- *
- *
- * ``` - * - * It is possible that during the `enter` animation, the `.message` div will be briefly visible before it starts animating. - * In that case, you can add styles to the CSS that make sure the element stays hidden before the animation starts: - * - * ```css - * .message.ng-enter-prepare { - * opacity: 0; - * } - * ``` - * - * ### Animating between value changes - * - * Sometimes you need to animate between different expression states, whose values - * don't necessary need to be known or referenced in CSS styles. - * Unless possible with another {@link ngAnimate#directive-support "animation aware" directive}, - * that specific use case can always be covered with {@link ngAnimate.directive:ngAnimateSwap} as - * can be seen in {@link ngAnimate.directive:ngAnimateSwap#examples this example}. - * - * Note that {@link ngAnimate.directive:ngAnimateSwap} is a *structural directive*, which means it - * creates a new instance of the element (including any other/child directives it may have) and - * links it to a new scope every time *swap* happens. In some cases this might not be desirable - * (e.g. for performance reasons, or when you wish to retain internal state on the original - * element instance). - * - * ## JavaScript-based Animations - * - * ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared - * CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the - * `module.animation()` module function we can register the animation. - * - * Let's see an example of a enter/leave animation using `ngRepeat`: - * - * ```html - *
- * {{ item }} - *
- * ``` - * - * See the **slide** CSS class? Let's use that class to define an animation that we'll structure in our module code by using `module.animation`: - * - * ```js - * myModule.animation('.slide', [function() { - * return { - * // make note that other events (like addClass/removeClass) - * // have different function input parameters - * enter: function(element, doneFn) { - * jQuery(element).fadeIn(1000, doneFn); - * - * // remember to call doneFn so that AngularJS - * // knows that the animation has concluded - * }, - * - * move: function(element, doneFn) { - * jQuery(element).fadeIn(1000, doneFn); - * }, - * - * leave: function(element, doneFn) { - * jQuery(element).fadeOut(1000, doneFn); - * } - * } - * }]); - * ``` - * - * The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as - * greensock.js and velocity.js. - * - * If our animation code class-based (meaning that something like `ngClass`, `ngHide` and `ngShow` triggers it) then we can still define - * our animations inside of the same registered animation, however, the function input arguments are a bit different: - * - * ```html - *
- * this box is moody - *
- * - * - * - * ``` - * - * ```js - * myModule.animation('.colorful', [function() { - * return { - * addClass: function(element, className, doneFn) { - * // do some cool animation and call the doneFn - * }, - * removeClass: function(element, className, doneFn) { - * // do some cool animation and call the doneFn - * }, - * setClass: function(element, addedClass, removedClass, doneFn) { - * // do some cool animation and call the doneFn - * } - * } - * }]); - * ``` - * - * ## CSS + JS Animations Together - * - * AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of AngularJS, - * defining CSS and JS animations to work off of the same CSS class will not work anymore. Therefore the example below will only result in **JS animations taking - * charge of the animation**: - * - * ```html - *
- * Slide in and out - *
- * ``` - * - * ```js - * myModule.animation('.slide', [function() { - * return { - * enter: function(element, doneFn) { - * jQuery(element).slideIn(1000, doneFn); - * } - * } - * }]); - * ``` - * - * ```css - * .slide.ng-enter { - * transition:0.5s linear all; - * transform:translateY(-100px); - * } - * .slide.ng-enter.ng-enter-active { - * transform:translateY(0); - * } - * ``` - * - * Does this mean that CSS and JS animations cannot be used together? Do JS-based animations always have higher priority? We can make up for the - * lack of CSS animations by using the `$animateCss` service to trigger our own tweaked-out, CSS-based animations directly from - * our own JS-based animation code: - * - * ```js - * myModule.animation('.slide', ['$animateCss', function($animateCss) { - * return { - * enter: function(element) { -* // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`. - * return $animateCss(element, { - * event: 'enter', - * structural: true - * }); - * } - * } - * }]); - * ``` - * - * The nice thing here is that we can save bandwidth by sticking to our CSS-based animation code and we don't need to rely on a 3rd-party animation framework. - * - * The `$animateCss` service is very powerful since we can feed in all kinds of extra properties that will be evaluated and fed into a CSS transition or - * keyframe animation. For example if we wanted to animate the height of an element while adding and removing classes then we can do so by providing that - * data into `$animateCss` directly: - * - * ```js - * myModule.animation('.slide', ['$animateCss', function($animateCss) { - * return { - * enter: function(element) { - * return $animateCss(element, { - * event: 'enter', - * structural: true, - * addClass: 'maroon-setting', - * from: { height:0 }, - * to: { height: 200 } - * }); - * } - * } - * }]); - * ``` - * - * Now we can fill in the rest via our transition CSS code: - * - * ```css - * /* the transition tells ngAnimate to make the animation happen */ - * .slide.ng-enter { transition:0.5s linear all; } - * - * /* this extra CSS class will be absorbed into the transition - * since the $animateCss code is adding the class */ - * .maroon-setting { background:red; } - * ``` - * - * And `$animateCss` will figure out the rest. Just make sure to have the `done()` callback fire the `doneFn` function to signal when the animation is over. - * - * To learn more about what's possible be sure to visit the {@link ngAnimate.$animateCss $animateCss service}. - * - * ## Animation Anchoring (via `ng-animate-ref`) - * - * ngAnimate in AngularJS 1.4 comes packed with the ability to cross-animate elements between - * structural areas of an application (like views) by pairing up elements using an attribute - * called `ng-animate-ref`. - * - * Let's say for example we have two views that are managed by `ng-view` and we want to show - * that there is a relationship between two components situated in within these views. By using the - * `ng-animate-ref` attribute we can identify that the two components are paired together and we - * can then attach an animation, which is triggered when the view changes. - * - * Say for example we have the following template code: - * - * ```html - * - *
- *
- * - * - * - * - * - * - * - * - * ``` - * - * Now, when the view changes (once the link is clicked), ngAnimate will examine the - * HTML contents to see if there is a match reference between any components in the view - * that is leaving and the view that is entering. It will scan both the view which is being - * removed (leave) and inserted (enter) to see if there are any paired DOM elements that - * contain a matching ref value. - * - * The two images match since they share the same ref value. ngAnimate will now create a - * transport element (which is a clone of the first image element) and it will then attempt - * to animate to the position of the second image element in the next view. For the animation to - * work a special CSS class called `ng-anchor` will be added to the transported element. - * - * We can now attach a transition onto the `.banner.ng-anchor` CSS class and then - * ngAnimate will handle the entire transition for us as well as the addition and removal of - * any changes of CSS classes between the elements: - * - * ```css - * .banner.ng-anchor { - * /* this animation will last for 1 second since there are - * two phases to the animation (an `in` and an `out` phase) */ - * transition:0.5s linear all; - * } - * ``` - * - * We also **must** include animations for the views that are being entered and removed - * (otherwise anchoring wouldn't be possible since the new view would be inserted right away). - * - * ```css - * .view-animation.ng-enter, .view-animation.ng-leave { - * transition:0.5s linear all; - * position:fixed; - * left:0; - * top:0; - * width:100%; - * } - * .view-animation.ng-enter { - * transform:translateX(100%); - * } - * .view-animation.ng-leave, - * .view-animation.ng-enter.ng-enter-active { - * transform:translateX(0%); - * } - * .view-animation.ng-leave.ng-leave-active { - * transform:translateX(-100%); - * } - * ``` - * - * Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur: - * an `out` and an `in` stage. The `out` stage happens first and that is when the element is animated away - * from its origin. Once that animation is over then the `in` stage occurs which animates the - * element to its destination. The reason why there are two animations is to give enough time - * for the enter animation on the new element to be ready. - * - * The example above sets up a transition for both the in and out phases, but we can also target the out or - * in phases directly via `ng-anchor-out` and `ng-anchor-in`. - * - * ```css - * .banner.ng-anchor-out { - * transition: 0.5s linear all; - * - * /* the scale will be applied during the out animation, - * but will be animated away when the in animation runs */ - * transform: scale(1.2); - * } - * - * .banner.ng-anchor-in { - * transition: 1s linear all; - * } - * ``` - * - * - * - * - * ### Anchoring Demo - * - - - Home -
-
-
-
-
- - angular.module('anchoringExample', ['ngAnimate', 'ngRoute']) - .config(['$routeProvider', function($routeProvider) { - $routeProvider.when('/', { - templateUrl: 'home.html', - controller: 'HomeController as home' - }); - $routeProvider.when('/profile/:id', { - templateUrl: 'profile.html', - controller: 'ProfileController as profile' - }); - }]) - .run(['$rootScope', function($rootScope) { - $rootScope.records = [ - { id: 1, title: 'Miss Beulah Roob' }, - { id: 2, title: 'Trent Morissette' }, - { id: 3, title: 'Miss Ava Pouros' }, - { id: 4, title: 'Rod Pouros' }, - { id: 5, title: 'Abdul Rice' }, - { id: 6, title: 'Laurie Rutherford Sr.' }, - { id: 7, title: 'Nakia McLaughlin' }, - { id: 8, title: 'Jordon Blanda DVM' }, - { id: 9, title: 'Rhoda Hand' }, - { id: 10, title: 'Alexandrea Sauer' } - ]; - }]) - .controller('HomeController', [function() { - //empty - }]) - .controller('ProfileController', ['$rootScope', '$routeParams', - function ProfileController($rootScope, $routeParams) { - var index = parseInt($routeParams.id, 10); - var record = $rootScope.records[index - 1]; + FFTM.prototype.stub = function stub (N) { + var ph = new Array(N); + for (var i = 0; i < N; i++) { + ph[i] = 0; + } - this.title = record.title; - this.id = record.id; - }]); - - -

Welcome to the home page

-

Please click on an element

- - {{ record.title }} - -
- -
- {{ profile.title }} -
-
- - .record { - display:block; - font-size:20px; - } - .profile { - background:black; - color:white; - font-size:100px; - } - .view-container { - position:relative; - } - .view-container > .view.ng-animate { - position:absolute; - top:0; - left:0; - width:100%; - min-height:500px; - } - .view.ng-enter, .view.ng-leave, - .record.ng-anchor { - transition:0.5s linear all; - } - .view.ng-enter { - transform:translateX(100%); - } - .view.ng-enter.ng-enter-active, .view.ng-leave { - transform:translateX(0%); - } - .view.ng-leave.ng-leave-active { - transform:translateX(-100%); - } - .record.ng-anchor-out { - background:red; - } - -
- * - * ### How is the element transported? - * - * When an anchor animation occurs, ngAnimate will clone the starting element and position it exactly where the starting - * element is located on screen via absolute positioning. The cloned element will be placed inside of the root element - * of the application (where ng-app was defined) and all of the CSS classes of the starting element will be applied. The - * element will then animate into the `out` and `in` animations and will eventually reach the coordinates and match - * the dimensions of the destination element. During the entire animation a CSS class of `.ng-animate-shim` will be applied - * to both the starting and destination elements in order to hide them from being visible (the CSS styling for the class - * is: `visibility:hidden`). Once the anchor reaches its destination then it will be removed and the destination element - * will become visible since the shim class will be removed. - * - * ### How is the morphing handled? - * - * CSS Anchoring relies on transitions and keyframes and the internal code is intelligent enough to figure out - * what CSS classes differ between the starting element and the destination element. These different CSS classes - * will be added/removed on the anchor element and a transition will be applied (the transition that is provided - * in the anchor class). Long story short, ngAnimate will figure out what classes to add and remove which will - * make the transition of the element as smooth and automatic as possible. Be sure to use simple CSS classes that - * do not rely on DOM nesting structure so that the anchor element appears the same as the starting element (since - * the cloned element is placed inside of root element which is likely close to the body element). - * - * Note that if the root element is on the `` element then the cloned node will be placed inside of body. - * - * - * ## Using $animate in your directive code - * - * So far we've explored how to feed in animations into an AngularJS application, but how do we trigger animations within our own directives in our application? - * By injecting the `$animate` service into our directive code, we can trigger structural and class-based hooks which can then be consumed by animations. Let's - * imagine we have a greeting box that shows and hides itself when the data changes - * - * ```html - * Hi there - * ``` - * - * ```js - * ngModule.directive('greetingBox', ['$animate', function($animate) { - * return function(scope, element, attrs) { - * attrs.$observe('active', function(value) { - * value ? $animate.addClass(element, 'on') : $animate.removeClass(element, 'on'); - * }); - * }); - * }]); - * ``` - * - * Now the `on` CSS class is added and removed on the greeting box component. Now if we add a CSS class on top of the greeting box element - * in our HTML code then we can trigger a CSS or JS animation to happen. - * - * ```css - * /* normally we would create a CSS class to reference on the element */ - * greeting-box.on { transition:0.5s linear all; background:green; color:white; } - * ``` - * - * The `$animate` service contains a variety of other methods like `enter`, `leave`, `animate` and `setClass`. To learn more about what's - * possible be sure to visit the {@link ng.$animate $animate service API page}. - * - * - * ## Callbacks and Promises - * - * When `$animate` is called it returns a promise that can be used to capture when the animation has ended. Therefore if we were to trigger - * an animation (within our directive code) then we can continue performing directive and scope related activities after the animation has - * ended by chaining onto the returned promise that animation method returns. - * - * ```js - * // somewhere within the depths of the directive - * $animate.enter(element, parent).then(function() { - * //the animation has completed - * }); - * ``` - * - * (Note that earlier versions of AngularJS prior to v1.4 required the promise code to be wrapped using `$scope.$apply(...)`. This is not the case - * anymore.) - * - * In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering - * an event listener using the `$animate` service. Let's say for example that an animation was triggered on our view - * routing controller to hook into that: - * - * ```js - * ngModule.controller('HomePageController', ['$animate', function($animate) { - * $animate.on('enter', ngViewElement, function(element) { - * // the animation for this route has completed - * }]); - * }]) - * ``` - * - * (Note that you will need to trigger a digest within the callback to get AngularJS to notice any scope-related changes.) - */ + return ph; + }; -var copy; -var extend; -var forEach; -var isArray; -var isDefined; -var isElement; -var isFunction; -var isObject; -var isString; -var isUndefined; -var jqLite; -var noop; + FFTM.prototype.mulp = function mulp (x, y, out) { + var N = 2 * this.guessLen13b(x.length, y.length); -/** - * @ngdoc service - * @name $animate - * @kind object - * - * @description - * The ngAnimate `$animate` service documentation is the same for the core `$animate` service. - * - * Click here {@link ng.$animate to learn more about animations with `$animate`}. - */ -angular.module('ngAnimate', [], function initAngularHelpers() { - // Access helpers from AngularJS core. - // Do it inside a `config` block to ensure `window.angular` is available. - noop = angular.noop; - copy = angular.copy; - extend = angular.extend; - jqLite = angular.element; - forEach = angular.forEach; - isArray = angular.isArray; - isString = angular.isString; - isObject = angular.isObject; - isUndefined = angular.isUndefined; - isDefined = angular.isDefined; - isFunction = angular.isFunction; - isElement = angular.isElement; -}) - .info({ angularVersion: '1.7.5' }) - .directive('ngAnimateSwap', ngAnimateSwapDirective) + var rbt = this.makeRBT(N); - .directive('ngAnimateChildren', $$AnimateChildrenDirective) - .factory('$$rAFScheduler', $$rAFSchedulerFactory) + var _ = this.stub(N); - .provider('$$animateQueue', $$AnimateQueueProvider) - .provider('$$animateCache', $$AnimateCacheProvider) - .provider('$$animation', $$AnimationProvider) + var rws = new Array(N); + var rwst = new Array(N); + var iwst = new Array(N); - .provider('$animateCss', $AnimateCssProvider) - .provider('$$animateCssDriver', $$AnimateCssDriverProvider) + var nrws = new Array(N); + var nrwst = new Array(N); + var niwst = new Array(N); - .provider('$$animateJs', $$AnimateJsProvider) - .provider('$$animateJsDriver', $$AnimateJsDriverProvider); + var rmws = out.words; + rmws.length = N; + this.convert13b(x.words, x.length, rws, N); + this.convert13b(y.words, y.length, nrws, N); -})(window, window.angular); + this.transform(rws, _, rwst, iwst, N, rbt); + this.transform(nrws, _, nrwst, niwst, N, rbt); -},{}],175:[function(require,module,exports){ -require('./angular-animate'); -module.exports = 'ngAnimate'; + for (var i = 0; i < N; i++) { + var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i]; + iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i]; + rwst[i] = rx; + } -},{"./angular-animate":174}],176:[function(require,module,exports){ -/** - * @license AngularJS v1.7.5 - * (c) 2010-2018 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, angular) {'use strict'; + this.conjugate(rwst, iwst, N); + this.transform(rwst, iwst, rmws, _, N, rbt); + this.conjugate(rmws, _, N); + this.normalize13b(rmws, N); -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Any commits to this file should be reviewed with security in mind. * - * Changes to this file can potentially create security vulnerabilities. * - * An approval from 2 Core members with history of modifying * - * this file is required. * - * * - * Does the change somehow allow for arbitrary javascript to be executed? * - * Or allows for someone to change the prototype of built-in objects? * - * Or gives undesired access to variables likes document or window? * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + out.negative = x.negative ^ y.negative; + out.length = x.length + y.length; + return out.strip(); + }; -var $sanitizeMinErr = angular.$$minErr('$sanitize'); -var bind; -var extend; -var forEach; -var isArray; -var isDefined; -var lowercase; -var noop; -var nodeContains; -var htmlParser; -var htmlSanitizeWriter; + // Multiply `this` by `num` + BN.prototype.mul = function mul (num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return this.mulTo(num, out); + }; -/** - * @ngdoc module - * @name ngSanitize - * @description - * - * The `ngSanitize` module provides functionality to sanitize HTML. - * - * See {@link ngSanitize.$sanitize `$sanitize`} for usage. - */ + // Multiply employing FFT + BN.prototype.mulf = function mulf (num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return jumboMulTo(this, num, out); + }; -/** - * @ngdoc service - * @name $sanitize - * @kind function - * - * @description - * Sanitizes an html string by stripping all potentially dangerous tokens. - * - * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are - * then serialized back to a properly escaped HTML string. This means that no unsafe input can make - * it into the returned string. - * - * The whitelist for URL sanitization of attribute values is configured using the functions - * `aHrefSanitizationWhitelist` and `imgSrcSanitizationWhitelist` of {@link $compileProvider}. - * - * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}. - * - * @param {string} html HTML input. - * @returns {string} Sanitized HTML. - * - * @example - - - -
- Snippet: - - - - - - - - - - - - - - - - - - - - - - - - - -
DirectiveHowSourceRendered
ng-bind-htmlAutomatically uses $sanitize
<div ng-bind-html="snippet">
</div>
ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value -
<div ng-bind-html="deliberatelyTrustDangerousSnippet()">
-</div>
-
ng-bindAutomatically escapes
<div ng-bind="snippet">
</div>
-
-
- - it('should sanitize the html snippet by default', function() { - expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')). - toBe('

an html\nclick here\nsnippet

'); - }); + // In-place Multiplication + BN.prototype.imul = function imul (num) { + return this.clone().mulTo(num, this); + }; - it('should inline raw snippet if bound to a trusted value', function() { - expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')). - toBe("

an html\n" + - "click here\n" + - "snippet

"); - }); + BN.prototype.imuln = function imuln (num) { + assert(typeof num === 'number'); + assert(num < 0x4000000); - it('should escape snippet without any filter', function() { - expect(element(by.css('#bind-default div')).getAttribute('innerHTML')). - toBe("<p style=\"color:blue\">an html\n" + - "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + - "snippet</p>"); - }); + // Carry + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = (this.words[i] | 0) * num; + var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); + carry >>= 26; + carry += (w / 0x4000000) | 0; + // NOTE: lo is 27bit maximum + carry += lo >>> 26; + this.words[i] = lo & 0x3ffffff; + } - it('should update', function() { - element(by.model('snippet')).clear(); - element(by.model('snippet')).sendKeys('new text'); - expect(element(by.css('#bind-html-with-sanitize div')).getAttribute('innerHTML')). - toBe('new text'); - expect(element(by.css('#bind-html-with-trust div')).getAttribute('innerHTML')).toBe( - 'new text'); - expect(element(by.css('#bind-default div')).getAttribute('innerHTML')).toBe( - "new <b onclick=\"alert(1)\">text</b>"); - }); -
-
- */ + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + return this; + }; -/** - * @ngdoc provider - * @name $sanitizeProvider - * @this - * - * @description - * Creates and configures {@link $sanitize} instance. - */ -function $SanitizeProvider() { - var hasBeenInstantiated = false; - var svgEnabled = false; + BN.prototype.muln = function muln (num) { + return this.clone().imuln(num); + }; - this.$get = ['$$sanitizeUri', function($$sanitizeUri) { - hasBeenInstantiated = true; - if (svgEnabled) { - extend(validElements, svgElements); - } - return function(html) { - var buf = []; - htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { - return !/^unsafe:/.test($$sanitizeUri(uri, isImage)); - })); - return buf.join(''); - }; - }]; + // `this` * `this` + BN.prototype.sqr = function sqr () { + return this.mul(this); + }; + // `this` * `this` in-place + BN.prototype.isqr = function isqr () { + return this.imul(this.clone()); + }; - /** - * @ngdoc method - * @name $sanitizeProvider#enableSvg - * @kind function - * - * @description - * Enables a subset of svg to be supported by the sanitizer. - * - *
- *

By enabling this setting without taking other precautions, you might expose your - * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned - * outside of the containing element and be rendered over other elements on the page (e.g. a login - * link). Such behavior can then result in phishing incidents.

- * - *

To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg - * tags within the sanitized content:

- * - *
- * - *

-   *   .rootOfTheIncludedContent svg {
-   *     overflow: hidden !important;
-   *   }
-   *   
- *
- * - * @param {boolean=} flag Enable or disable SVG support in the sanitizer. - * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called - * without an argument or self for chaining otherwise. - */ - this.enableSvg = function(enableSvg) { - if (isDefined(enableSvg)) { - svgEnabled = enableSvg; - return this; - } else { - return svgEnabled; + // Math.pow(`this`, `num`) + BN.prototype.pow = function pow (num) { + var w = toBitArray(num); + if (w.length === 0) return new BN(1); + + // Skip leading zeroes + var res = this; + for (var i = 0; i < w.length; i++, res = res.sqr()) { + if (w[i] !== 0) break; } - }; + if (++i < w.length) { + for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) { + if (w[i] === 0) continue; - /** - * @ngdoc method - * @name $sanitizeProvider#addValidElements - * @kind function - * - * @description - * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe - * and are not stripped off during sanitization. You can extend the following lists of elements: - * - * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML - * elements. HTML elements considered safe will not be removed during sanitization. All other - * elements will be stripped off. - * - * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as - * "void elements" (similar to HTML - * [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These - * elements have no end tag and cannot have content. - * - * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only - * taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for - * `$sanitize`. - * - *
- * This method must be called during the {@link angular.Module#config config} phase. Once the - * `$sanitize` service has been instantiated, this method has no effect. - *
- * - *
- * Keep in mind that extending the built-in lists of elements may expose your app to XSS or - * other vulnerabilities. Be very mindful of the elements you add. - *
- * - * @param {Array|Object} elements - A list of valid HTML elements or an object with one or - * more of the following properties: - * - **htmlElements** - `{Array}` - A list of elements to extend the current list of - * HTML elements. - * - **htmlVoidElements** - `{Array}` - A list of elements to extend the current list of - * void HTML elements; i.e. elements that do not have an end tag. - * - **svgElements** - `{Array}` - A list of elements to extend the current list of SVG - * elements. The list of SVG elements is only taken into account if SVG is - * {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`. - * - * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`. - * - * @return {$sanitizeProvider} Returns self for chaining. - */ - this.addValidElements = function(elements) { - if (!hasBeenInstantiated) { - if (isArray(elements)) { - elements = {htmlElements: elements}; + res = res.mul(q); } - - addElementsTo(svgElements, elements.svgElements); - addElementsTo(voidElements, elements.htmlVoidElements); - addElementsTo(validElements, elements.htmlVoidElements); - addElementsTo(validElements, elements.htmlElements); } - return this; + return res; }; + // Shift-left in-place + BN.prototype.iushln = function iushln (bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); + var i; + + if (r !== 0) { + var carry = 0; - /** - * @ngdoc method - * @name $sanitizeProvider#addValidAttrs - * @kind function - * - * @description - * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are - * not stripped off during sanitization. - * - * **Note**: - * The new attributes will not be treated as URI attributes, which means their values will not be - * sanitized as URIs using `$compileProvider`'s - * {@link ng.$compileProvider#aHrefSanitizationWhitelist aHrefSanitizationWhitelist} and - * {@link ng.$compileProvider#imgSrcSanitizationWhitelist imgSrcSanitizationWhitelist}. - * - *
- * This method must be called during the {@link angular.Module#config config} phase. Once the - * `$sanitize` service has been instantiated, this method has no effect. - *
- * - *
- * Keep in mind that extending the built-in list of attributes may expose your app to XSS or - * other vulnerabilities. Be very mindful of the attributes you add. - *
- * - * @param {Array} attrs - A list of valid attributes. - * - * @returns {$sanitizeProvider} Returns self for chaining. - */ - this.addValidAttrs = function(attrs) { - if (!hasBeenInstantiated) { - extend(validAttrs, arrayToMap(attrs, true)); + for (i = 0; i < this.length; i++) { + var newCarry = this.words[i] & carryMask; + var c = ((this.words[i] | 0) - newCarry) << r; + this.words[i] = c | carry; + carry = newCarry >>> (26 - r); + } + + if (carry) { + this.words[i] = carry; + this.length++; + } } - return this; - }; - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Private stuff - ////////////////////////////////////////////////////////////////////////////////////////////////// + if (s !== 0) { + for (i = this.length - 1; i >= 0; i--) { + this.words[i + s] = this.words[i]; + } - bind = angular.bind; - extend = angular.extend; - forEach = angular.forEach; - isArray = angular.isArray; - isDefined = angular.isDefined; - lowercase = angular.$$lowercase; - noop = angular.noop; + for (i = 0; i < s; i++) { + this.words[i] = 0; + } - htmlParser = htmlParserImpl; - htmlSanitizeWriter = htmlSanitizeWriterImpl; + this.length += s; + } - nodeContains = window.Node.prototype.contains || /** @this */ function(arg) { - // eslint-disable-next-line no-bitwise - return !!(this.compareDocumentPosition(arg) & 16); + return this.strip(); }; - // Regular Expressions for parsing tags and attributes - var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, - // Match everything outside of normal chars and " (quote character) - NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g; + BN.prototype.ishln = function ishln (bits) { + // TODO(indutny): implement me + assert(this.negative === 0); + return this.iushln(bits); + }; + // Shift-right in-place + // NOTE: `hint` is a lowest bit before trailing zeroes + // NOTE: if `extended` is present - it will be filled with destroyed bits + BN.prototype.iushrn = function iushrn (bits, hint, extended) { + assert(typeof bits === 'number' && bits >= 0); + var h; + if (hint) { + h = (hint - (hint % 26)) / 26; + } else { + h = 0; + } - // Good source of info about elements and attributes - // http://dev.w3.org/html5/spec/Overview.html#semantics - // http://simon.html5.org/html-elements + var r = bits % 26; + var s = Math.min((bits - r) / 26, this.length); + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + var maskedWords = extended; - // Safe Void Elements - HTML5 - // http://dev.w3.org/html5/spec/Overview.html#void-elements - var voidElements = stringToMap('area,br,col,hr,img,wbr'); + h -= s; + h = Math.max(0, h); - // Elements that you can, intentionally, leave open (and which close themselves) - // http://dev.w3.org/html5/spec/Overview.html#optional-tags - var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'), - optionalEndTagInlineElements = stringToMap('rp,rt'), - optionalEndTagElements = extend({}, - optionalEndTagInlineElements, - optionalEndTagBlockElements); + // Extended mode, copy masked part + if (maskedWords) { + for (var i = 0; i < s; i++) { + maskedWords.words[i] = this.words[i]; + } + maskedWords.length = s; + } - // Safe Block Elements - HTML5 - var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' + - 'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' + - 'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul')); + if (s === 0) { + // No-op, we should not move anything at all + } else if (this.length > s) { + this.length -= s; + for (i = 0; i < this.length; i++) { + this.words[i] = this.words[i + s]; + } + } else { + this.words[0] = 0; + this.length = 1; + } - // Inline Elements - HTML5 - var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' + - 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' + - 'samp,small,span,strike,strong,sub,sup,time,tt,u,var')); + var carry = 0; + for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { + var word = this.words[i] | 0; + this.words[i] = (carry << (26 - r)) | (word >>> r); + carry = word & mask; + } - // SVG Elements - // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements - // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted. - // They can potentially allow for arbitrary javascript to be executed. See #11290 - var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' + - 'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' + - 'radialGradient,rect,stop,svg,switch,text,title,tspan'); + // Push carried bits as a mask + if (maskedWords && carry !== 0) { + maskedWords.words[maskedWords.length++] = carry; + } - // Blocked Elements (will be stripped) - var blockedElements = stringToMap('script,style'); + if (this.length === 0) { + this.words[0] = 0; + this.length = 1; + } - var validElements = extend({}, - voidElements, - blockElements, - inlineElements, - optionalEndTagElements); + return this.strip(); + }; - //Attributes that have href and hence need to be sanitized - var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base'); + BN.prototype.ishrn = function ishrn (bits, hint, extended) { + // TODO(indutny): implement me + assert(this.negative === 0); + return this.iushrn(bits, hint, extended); + }; - var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' + - 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' + - 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' + - 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' + - 'valign,value,vspace,width'); + // Shift-left + BN.prototype.shln = function shln (bits) { + return this.clone().ishln(bits); + }; - // SVG attributes (without "id" and "name" attributes) - // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes - var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' + - 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' + - 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' + - 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' + - 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' + - 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' + - 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' + - 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' + - 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' + - 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' + - 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' + - 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' + - 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' + - 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' + - 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true); + BN.prototype.ushln = function ushln (bits) { + return this.clone().iushln(bits); + }; - var validAttrs = extend({}, - uriAttrs, - svgAttrs, - htmlAttrs); + // Shift-right + BN.prototype.shrn = function shrn (bits) { + return this.clone().ishrn(bits); + }; - function stringToMap(str, lowercaseKeys) { - return arrayToMap(str.split(','), lowercaseKeys); - } + BN.prototype.ushrn = function ushrn (bits) { + return this.clone().iushrn(bits); + }; - function arrayToMap(items, lowercaseKeys) { - var obj = {}, i; - for (i = 0; i < items.length; i++) { - obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true; - } - return obj; - } + // Test if n bit is set + BN.prototype.testn = function testn (bit) { + assert(typeof bit === 'number' && bit >= 0); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; - function addElementsTo(elementsMap, newElements) { - if (newElements && newElements.length) { - extend(elementsMap, arrayToMap(newElements)); + // Fast case: bit is much higher than all existing words + if (this.length <= s) return false; + + // Check bit and return + var w = this.words[s]; + + return !!(w & q); + }; + + // Return only lowers bits of number (in-place) + BN.prototype.imaskn = function imaskn (bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + + assert(this.negative === 0, 'imaskn works only with positive numbers'); + + if (this.length <= s) { + return this; } - } - /** - * Create an inert document that contains the dirty HTML that needs sanitizing - * Depending upon browser support we use one of three strategies for doing this. - * Support: Safari 10.x -> XHR strategy - * Support: Firefox -> DomParser strategy - */ - var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) { - var inertDocument; - if (document && document.implementation) { - inertDocument = document.implementation.createHTMLDocument('inert'); - } else { - throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document'); + if (r !== 0) { + s++; } - var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body'); + this.length = Math.min(s, this.length); - // Check for the Safari 10.1 bug - which allows JS to run inside the SVG G element - inertBodyElement.innerHTML = ''; - if (!inertBodyElement.querySelector('svg')) { - return getInertBodyElement_XHR; - } else { - // Check for the Firefox bug - which prevents the inner img JS from being sanitized - inertBodyElement.innerHTML = '

'; - if (inertBodyElement.querySelector('svg img')) { - return getInertBodyElement_DOMParser; - } else { - return getInertBodyElement_InertDocument; - } + if (r !== 0) { + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + this.words[this.length - 1] &= mask; } - function getInertBodyElement_XHR(html) { - // We add this dummy element to ensure that the rest of the content is parsed as expected - // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag. - html = '' + html; - try { - html = encodeURI(html); - } catch (e) { - return undefined; + return this.strip(); + }; + + // Return only lowers bits of number + BN.prototype.maskn = function maskn (bits) { + return this.clone().imaskn(bits); + }; + + // Add plain number `num` to `this` + BN.prototype.iaddn = function iaddn (num) { + assert(typeof num === 'number'); + assert(num < 0x4000000); + if (num < 0) return this.isubn(-num); + + // Possible sign change + if (this.negative !== 0) { + if (this.length === 1 && (this.words[0] | 0) < num) { + this.words[0] = num - (this.words[0] | 0); + this.negative = 0; + return this; } - var xhr = new window.XMLHttpRequest(); - xhr.responseType = 'document'; - xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false); - xhr.send(null); - var body = xhr.response.body; - body.firstChild.remove(); - return body; + + this.negative = 0; + this.isubn(num); + this.negative = 1; + return this; } - function getInertBodyElement_DOMParser(html) { - // We add this dummy element to ensure that the rest of the content is parsed as expected - // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag. - html = '' + html; - try { - var body = new window.DOMParser().parseFromString(html, 'text/html').body; - body.firstChild.remove(); - return body; - } catch (e) { - return undefined; + // Add without checks + return this._iaddn(num); + }; + + BN.prototype._iaddn = function _iaddn (num) { + this.words[0] += num; + + // Carry + for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { + this.words[i] -= 0x4000000; + if (i === this.length - 1) { + this.words[i + 1] = 1; + } else { + this.words[i + 1]++; } } + this.length = Math.max(this.length, i + 1); - function getInertBodyElement_InertDocument(html) { - inertBodyElement.innerHTML = html; + return this; + }; - // Support: IE 9-11 only - // strip custom-namespaced attributes on IE<=11 - if (document.documentMode) { - stripCustomNsAttrs(inertBodyElement); - } + // Subtract plain number `num` from `this` + BN.prototype.isubn = function isubn (num) { + assert(typeof num === 'number'); + assert(num < 0x4000000); + if (num < 0) return this.iaddn(-num); - return inertBodyElement; + if (this.negative !== 0) { + this.negative = 0; + this.iaddn(num); + this.negative = 1; + return this; } - })(window, window.document); - /** - * @example - * htmlParser(htmlString, { - * start: function(tag, attrs) {}, - * end: function(tag) {}, - * chars: function(text) {}, - * comment: function(text) {} - * }); - * - * @param {string} html string - * @param {object} handler - */ - function htmlParserImpl(html, handler) { - if (html === null || html === undefined) { - html = ''; - } else if (typeof html !== 'string') { - html = '' + html; + this.words[0] -= num; + + if (this.length === 1 && this.words[0] < 0) { + this.words[0] = -this.words[0]; + this.negative = 1; + } else { + // Carry + for (var i = 0; i < this.length && this.words[i] < 0; i++) { + this.words[i] += 0x4000000; + this.words[i + 1] -= 1; + } } - var inertBodyElement = getInertBodyElement(html); - if (!inertBodyElement) return ''; + return this.strip(); + }; - //mXSS protection - var mXSSAttempts = 5; - do { - if (mXSSAttempts === 0) { - throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable'); - } - mXSSAttempts--; + BN.prototype.addn = function addn (num) { + return this.clone().iaddn(num); + }; - // trigger mXSS if it is going to happen by reading and writing the innerHTML - html = inertBodyElement.innerHTML; - inertBodyElement = getInertBodyElement(html); - } while (html !== inertBodyElement.innerHTML); + BN.prototype.subn = function subn (num) { + return this.clone().isubn(num); + }; - var node = inertBodyElement.firstChild; - while (node) { - switch (node.nodeType) { - case 1: // ELEMENT_NODE - handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes)); - break; - case 3: // TEXT NODE - handler.chars(node.textContent); - break; - } + BN.prototype.iabs = function iabs () { + this.negative = 0; - var nextNode; - if (!(nextNode = node.firstChild)) { - if (node.nodeType === 1) { - handler.end(node.nodeName.toLowerCase()); - } - nextNode = getNonDescendant('nextSibling', node); - if (!nextNode) { - while (nextNode == null) { - node = getNonDescendant('parentNode', node); - if (node === inertBodyElement) break; - nextNode = getNonDescendant('nextSibling', node); - if (node.nodeType === 1) { - handler.end(node.nodeName.toLowerCase()); - } - } - } - } - node = nextNode; + return this; + }; + + BN.prototype.abs = function abs () { + return this.clone().iabs(); + }; + + BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) { + var len = num.length + shift; + var i; + + this._expand(len); + + var w; + var carry = 0; + for (i = 0; i < num.length; i++) { + w = (this.words[i + shift] | 0) + carry; + var right = (num.words[i] | 0) * mul; + w -= right & 0x3ffffff; + carry = (w >> 26) - ((right / 0x4000000) | 0); + this.words[i + shift] = w & 0x3ffffff; + } + for (; i < this.length - shift; i++) { + w = (this.words[i + shift] | 0) + carry; + carry = w >> 26; + this.words[i + shift] = w & 0x3ffffff; } - while ((node = inertBodyElement.firstChild)) { - inertBodyElement.removeChild(node); + if (carry === 0) return this.strip(); + + // Subtraction overflow + assert(carry === -1); + carry = 0; + for (i = 0; i < this.length; i++) { + w = -(this.words[i] | 0) + carry; + carry = w >> 26; + this.words[i] = w & 0x3ffffff; } - } + this.negative = 1; - function attrToMap(attrs) { - var map = {}; - for (var i = 0, ii = attrs.length; i < ii; i++) { - var attr = attrs[i]; - map[attr.name] = attr.value; + return this.strip(); + }; + + BN.prototype._wordDiv = function _wordDiv (num, mode) { + var shift = this.length - num.length; + + var a = this.clone(); + var b = num; + + // Normalize + var bhi = b.words[b.length - 1] | 0; + var bhiBits = this._countBits(bhi); + shift = 26 - bhiBits; + if (shift !== 0) { + b = b.ushln(shift); + a.iushln(shift); + bhi = b.words[b.length - 1] | 0; } - return map; - } + // Initialize quotient + var m = a.length - b.length; + var q; - /** - * Escapes all potentially dangerous characters, so that the - * resulting string can be safely inserted into attribute or - * element text. - * @param value - * @returns {string} escaped text - */ - function encodeEntities(value) { - return value. - replace(/&/g, '&'). - replace(SURROGATE_PAIR_REGEXP, function(value) { - var hi = value.charCodeAt(0); - var low = value.charCodeAt(1); - return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';'; - }). - replace(NON_ALPHANUMERIC_REGEXP, function(value) { - return '&#' + value.charCodeAt(0) + ';'; - }). - replace(//g, '>'); - } + if (mode !== 'mod') { + q = new BN(null); + q.length = m + 1; + q.words = new Array(q.length); + for (var i = 0; i < q.length; i++) { + q.words[i] = 0; + } + } - /** - * create an HTML/XML writer which writes to buffer - * @param {Array} buf use buf.join('') to get out sanitized html string - * @returns {object} in the form of { - * start: function(tag, attrs) {}, - * end: function(tag) {}, - * chars: function(text) {}, - * comment: function(text) {} - * } - */ - function htmlSanitizeWriterImpl(buf, uriValidator) { - var ignoreCurrentElement = false; - var out = bind(buf, buf.push); - return { - start: function(tag, attrs) { - tag = lowercase(tag); - if (!ignoreCurrentElement && blockedElements[tag]) { - ignoreCurrentElement = tag; - } - if (!ignoreCurrentElement && validElements[tag] === true) { - out('<'); - out(tag); - forEach(attrs, function(value, key) { - var lkey = lowercase(key); - var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); - if (validAttrs[lkey] === true && - (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { - out(' '); - out(key); - out('="'); - out(encodeEntities(value)); - out('"'); - } - }); - out('>'); - } - }, - end: function(tag) { - tag = lowercase(tag); - if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) { - out(''); - } - // eslint-disable-next-line eqeqeq - if (tag == ignoreCurrentElement) { - ignoreCurrentElement = false; - } - }, - chars: function(chars) { - if (!ignoreCurrentElement) { - out(encodeEntities(chars)); - } + var diff = a.clone()._ishlnsubmul(b, 1, m); + if (diff.negative === 0) { + a = diff; + if (q) { + q.words[m] = 1; } - }; - } + } + + for (var j = m - 1; j >= 0; j--) { + var qj = (a.words[b.length + j] | 0) * 0x4000000 + + (a.words[b.length + j - 1] | 0); + // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max + // (0x7ffffff) + qj = Math.min((qj / bhi) | 0, 0x3ffffff); - /** - * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare - * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want - * to allow any of these custom attributes. This method strips them all. - * - * @param node Root element to process - */ - function stripCustomNsAttrs(node) { - while (node) { - if (node.nodeType === window.Node.ELEMENT_NODE) { - var attrs = node.attributes; - for (var i = 0, l = attrs.length; i < l; i++) { - var attrNode = attrs[i]; - var attrName = attrNode.name.toLowerCase(); - if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) { - node.removeAttributeNode(attrNode); - i--; - l--; - } + a._ishlnsubmul(b, qj, j); + while (a.negative !== 0) { + qj--; + a.negative = 0; + a._ishlnsubmul(b, 1, j); + if (!a.isZero()) { + a.negative ^= 1; } } - - var nextNode = node.firstChild; - if (nextNode) { - stripCustomNsAttrs(nextNode); + if (q) { + q.words[j] = qj; } - - node = getNonDescendant('nextSibling', node); } - } + if (q) { + q.strip(); + } + a.strip(); - function getNonDescendant(propName, node) { - // An element is clobbered if its `propName` property points to one of its descendants - var nextNode = node[propName]; - if (nextNode && nodeContains.call(node, nextNode)) { - throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText); + // Denormalize + if (mode !== 'div' && shift !== 0) { + a.iushrn(shift); } - return nextNode; - } -} -function sanitizeText(chars) { - var buf = []; - var writer = htmlSanitizeWriter(buf, noop); - writer.chars(chars); - return buf.join(''); -} + return { + div: q || null, + mod: a + }; + }; + // NOTE: 1) `mode` can be set to `mod` to request mod only, + // to `div` to request div only, or be absent to + // request both div & mod + // 2) `positive` is true if unsigned mod is requested + BN.prototype.divmod = function divmod (num, mode, positive) { + assert(!num.isZero()); -// define ngSanitize module and register $sanitize service -angular.module('ngSanitize', []) - .provider('$sanitize', $SanitizeProvider) - .info({ angularVersion: '1.7.5' }); + if (this.isZero()) { + return { + div: new BN(0), + mod: new BN(0) + }; + } -/** - * @ngdoc filter - * @name linky - * @kind function - * - * @description - * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and - * plain email address links. - * - * Requires the {@link ngSanitize `ngSanitize`} module to be installed. - * - * @param {string} text Input text. - * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in. - * @param {object|function(url)} [attributes] Add custom attributes to the link element. - * - * Can be one of: - * - * - `object`: A map of attributes - * - `function`: Takes the url as a parameter and returns a map of attributes - * - * If the map of attributes contains a value for `target`, it overrides the value of - * the target parameter. - * - * - * @returns {string} Html-linkified and {@link $sanitize sanitized} text. - * - * @usage - - * - * @example - - -

- Snippet: - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilterSourceRendered
linky filter -
<div ng-bind-html="snippet | linky">
</div>
-
-
-
linky target -
<div ng-bind-html="snippetWithSingleURL | linky:'_blank'">
</div>
-
-
-
linky custom attributes -
<div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}">
</div>
-
-
-
no filter
<div ng-bind="snippet">
</div>
- - - angular.module('linkyExample', ['ngSanitize']) - .controller('ExampleController', ['$scope', function($scope) { - $scope.snippet = - 'Pretty text with some links:\n' + - 'http://angularjs.org/,\n' + - 'mailto:us@somewhere.org,\n' + - 'another@somewhere.org,\n' + - 'and one more: ftp://127.0.0.1/.'; - $scope.snippetWithSingleURL = 'http://angularjs.org/'; - }]); - - - it('should linkify the snippet with urls', function() { - expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). - toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + - 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); - expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); - }); + var div, mod, res; + if (this.negative !== 0 && num.negative === 0) { + res = this.neg().divmod(num, mode); - it('should not linkify snippet without the linky filter', function() { - expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). - toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + - 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); - expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); - }); + if (mode !== 'mod') { + div = res.div.neg(); + } - it('should update', function() { - element(by.model('snippet')).clear(); - element(by.model('snippet')).sendKeys('new http://link.'); - expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). - toBe('new http://link.'); - expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); - expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) - .toBe('new http://link.'); - }); + if (mode !== 'div') { + mod = res.mod.neg(); + if (positive && mod.negative !== 0) { + mod.iadd(num); + } + } - it('should work with the target property', function() { - expect(element(by.id('linky-target')). - element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()). - toBe('http://angularjs.org/'); - expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); - }); + return { + div: div, + mod: mod + }; + } - it('should optionally add custom attributes', function() { - expect(element(by.id('linky-custom-attributes')). - element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()). - toBe('http://angularjs.org/'); - expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow'); - }); - - - */ -angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { - var LINKY_URL_REGEXP = - /((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i, - MAILTO_REGEXP = /^mailto:/i; + if (this.negative === 0 && num.negative !== 0) { + res = this.divmod(num.neg(), mode); - var linkyMinErr = angular.$$minErr('linky'); - var isDefined = angular.isDefined; - var isFunction = angular.isFunction; - var isObject = angular.isObject; - var isString = angular.isString; + if (mode !== 'mod') { + div = res.div.neg(); + } - return function(text, target, attributes) { - if (text == null || text === '') return text; - if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text); + return { + div: div, + mod: res.mod + }; + } - var attributesFn = - isFunction(attributes) ? attributes : - isObject(attributes) ? function getAttributesObject() {return attributes;} : - function getEmptyAttributesObject() {return {};}; + if ((this.negative & num.negative) !== 0) { + res = this.neg().divmod(num.neg(), mode); - var match; - var raw = text; - var html = []; - var url; - var i; - while ((match = raw.match(LINKY_URL_REGEXP))) { - // We can not end in these as they are sometimes found at the end of the sentence - url = match[0]; - // if we did not match ftp/http/www/mailto then assume mailto - if (!match[2] && !match[4]) { - url = (match[3] ? 'http://' : 'mailto:') + url; + if (mode !== 'div') { + mod = res.mod.neg(); + if (positive && mod.negative !== 0) { + mod.isub(num); + } } - i = match.index; - addText(raw.substr(0, i)); - addLink(url, match[0].replace(MAILTO_REGEXP, '')); - raw = raw.substring(i + match[0].length); - } - addText(raw); - return $sanitize(html.join('')); - function addText(text) { - if (!text) { - return; - } - html.push(sanitizeText(text)); + return { + div: res.div, + mod: mod + }; } - function addLink(url, text) { - var key, linkAttributes = attributesFn(url); - html.push(' this.length || this.cmp(num) < 0) { + return { + div: new BN(0), + mod: this + }; + } + + // Very short reduction + if (num.length === 1) { + if (mode === 'div') { + return { + div: this.divn(num.words[0]), + mod: null + }; } - if (isDefined(target) && !('target' in linkAttributes)) { - html.push('target="', - target, - '" '); + if (mode === 'mod') { + return { + div: null, + mod: new BN(this.modn(num.words[0])) + }; } - html.push('href="', - url.replace(/"/g, '"'), - '">'); - addText(text); - html.push(''); + + return { + div: this.divn(num.words[0]), + mod: new BN(this.modn(num.words[0])) + }; } + + return this._wordDiv(num, mode); }; -}]); + // Find `this` / `num` + BN.prototype.div = function div (num) { + return this.divmod(num, 'div', false).div; + }; -})(window, window.angular); + // Find `this` % `num` + BN.prototype.mod = function mod (num) { + return this.divmod(num, 'mod', false).mod; + }; -},{}],177:[function(require,module,exports){ -require('./angular-sanitize'); -module.exports = 'ngSanitize'; + BN.prototype.umod = function umod (num) { + return this.divmod(num, 'mod', true).mod; + }; -},{"./angular-sanitize":176}],178:[function(require,module,exports){ -/*! - * angular-translate - v2.18.1 - 2018-05-19 - * - * Copyright (c) 2018 The angular-translate team, Pascal Precht; Licensed MIT - */ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module unless amdModuleId is set - define([], function () { - return (factory()); - }); - } else if (typeof module === 'object' && module.exports) { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - factory(); - } -}(this, function () { + // Find Round(`this` / `num`) + BN.prototype.divRound = function divRound (num) { + var dm = this.divmod(num); -$translateMissingTranslationHandlerLog.$inject = ['$log']; -angular.module('pascalprecht.translate') + // Fast case - exact division + if (dm.mod.isZero()) return dm.div; -/** - * @ngdoc object - * @name pascalprecht.translate.$translateMissingTranslationHandlerLog - * @requires $log - * - * @description - * Uses angular's `$log` service to give a warning when trying to translate a - * translation id which doesn't exist. - * - * @returns {function} Handler function - */ -.factory('$translateMissingTranslationHandlerLog', $translateMissingTranslationHandlerLog); + var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod; -function $translateMissingTranslationHandlerLog ($log) { + var half = num.ushrn(1); + var r2 = num.andln(1); + var cmp = mod.cmp(half); - 'use strict'; + // Round down + if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div; - return function (translationId) { - $log.warn('Translation for ' + translationId + ' doesn\'t exist'); + // Round up + return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); }; -} - -$translateMissingTranslationHandlerLog.displayName = '$translateMissingTranslationHandlerLog'; -return 'pascalprecht.translate'; -})); + BN.prototype.modn = function modn (num) { + assert(num <= 0x3ffffff); + var p = (1 << 26) % num; -},{}],179:[function(require,module,exports){ -/*! - * angular-translate - v2.18.1 - 2018-05-19 - * - * Copyright (c) 2018 The angular-translate team, Pascal Precht; Licensed MIT - */ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module unless amdModuleId is set - define([], function () { - return (factory()); - }); - } else if (typeof module === 'object' && module.exports) { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - factory(); - } -}(this, function () { + var acc = 0; + for (var i = this.length - 1; i >= 0; i--) { + acc = (p * acc + (this.words[i] | 0)) % num; + } -/** - * @ngdoc overview - * @name pascalprecht.translate - * - * @description - * The main module which holds everything together. - */ -runTranslate.$inject = ['$translate']; -$translate.$inject = ['$STORAGE_KEY', '$windowProvider', '$translateSanitizationProvider', 'pascalprechtTranslateOverrider']; -$translateDefaultInterpolation.$inject = ['$interpolate', '$translateSanitization']; -translateDirective.$inject = ['$translate', '$interpolate', '$compile', '$parse', '$rootScope']; -translateAttrDirective.$inject = ['$translate', '$rootScope']; -translateCloakDirective.$inject = ['$translate', '$rootScope']; -translateFilterFactory.$inject = ['$parse', '$translate']; -$translationCache.$inject = ['$cacheFactory']; -angular.module('pascalprecht.translate', ['ng']) - .run(runTranslate); + return acc; + }; -function runTranslate($translate) { + // In-place division by number + BN.prototype.idivn = function idivn (num) { + assert(num <= 0x3ffffff); - 'use strict'; + var carry = 0; + for (var i = this.length - 1; i >= 0; i--) { + var w = (this.words[i] | 0) + carry * 0x4000000; + this.words[i] = (w / num) | 0; + carry = w % num; + } - var key = $translate.storageKey(), - storage = $translate.storage(); + return this.strip(); + }; - var fallbackFromIncorrectStorageValue = function () { - var preferred = $translate.preferredLanguage(); - if (angular.isString(preferred)) { - $translate.use(preferred); - // $translate.use() will also remember the language. - // So, we don't need to call storage.put() here. - } else { - storage.put(key, $translate.use()); - } + BN.prototype.divn = function divn (num) { + return this.clone().idivn(num); }; - fallbackFromIncorrectStorageValue.displayName = 'fallbackFromIncorrectStorageValue'; + BN.prototype.egcd = function egcd (p) { + assert(p.negative === 0); + assert(!p.isZero()); - if (storage) { - if (!storage.get(key)) { - fallbackFromIncorrectStorageValue(); + var x = this; + var y = p.clone(); + + if (x.negative !== 0) { + x = x.umod(p); } else { - $translate.use(storage.get(key))['catch'](fallbackFromIncorrectStorageValue); + x = x.clone(); } - } else if (angular.isString($translate.preferredLanguage())) { - $translate.use($translate.preferredLanguage()); - } -} -runTranslate.displayName = 'runTranslate'; - -/** - * @ngdoc object - * @name pascalprecht.translate.$translateSanitizationProvider - * - * @description - * - * Configurations for $translateSanitization - */ -angular.module('pascalprecht.translate').provider('$translateSanitization', $translateSanitizationProvider); + // A * x + B * y = x + var A = new BN(1); + var B = new BN(0); -function $translateSanitizationProvider () { + // C * x + D * y = y + var C = new BN(0); + var D = new BN(1); - 'use strict'; + var g = 0; - var $sanitize, - $sce, - currentStrategy = null, // TODO change to either 'sanitize', 'escape' or ['sanitize', 'escapeParameters'] in 3.0. - hasConfiguredStrategy = false, - hasShownNoStrategyConfiguredWarning = false, - strategies; + while (x.isEven() && y.isEven()) { + x.iushrn(1); + y.iushrn(1); + ++g; + } - /** - * Definition of a sanitization strategy function - * @callback StrategyFunction - * @param {string|object} value - value to be sanitized (either a string or an interpolated value map) - * @param {string} mode - either 'text' for a string (translation) or 'params' for the interpolated params - * @return {string|object} - */ + var yp = y.clone(); + var xp = x.clone(); - /** - * @ngdoc property - * @name strategies - * @propertyOf pascalprecht.translate.$translateSanitizationProvider - * - * @description - * Following strategies are built-in: - *
- *
sanitize
- *
Sanitizes HTML in the translation text using $sanitize
- *
escape
- *
Escapes HTML in the translation
- *
sanitizeParameters
- *
Sanitizes HTML in the values of the interpolation parameters using $sanitize
- *
escapeParameters
- *
Escapes HTML in the values of the interpolation parameters
- *
escaped
- *
Support legacy strategy name 'escaped' for backwards compatibility (will be removed in 3.0)
- *
- * - */ + while (!x.isZero()) { + for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1); + if (i > 0) { + x.iushrn(i); + while (i-- > 0) { + if (A.isOdd() || B.isOdd()) { + A.iadd(yp); + B.isub(xp); + } - strategies = { - sanitize: function (value, mode/*, context*/) { - if (mode === 'text') { - value = htmlSanitizeValue(value); - } - return value; - }, - escape: function (value, mode/*, context*/) { - if (mode === 'text') { - value = htmlEscapeValue(value); - } - return value; - }, - sanitizeParameters: function (value, mode/*, context*/) { - if (mode === 'params') { - value = mapInterpolationParameters(value, htmlSanitizeValue); - } - return value; - }, - escapeParameters: function (value, mode/*, context*/) { - if (mode === 'params') { - value = mapInterpolationParameters(value, htmlEscapeValue); + A.iushrn(1); + B.iushrn(1); + } } - return value; - }, - sce: function (value, mode, context) { - if (mode === 'text') { - value = htmlTrustValue(value); - } else if (mode === 'params') { - if (context !== 'filter') { - // do html escape in filter context #1101 - value = mapInterpolationParameters(value, htmlEscapeValue); + + for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); + if (j > 0) { + y.iushrn(j); + while (j-- > 0) { + if (C.isOdd() || D.isOdd()) { + C.iadd(yp); + D.isub(xp); + } + + C.iushrn(1); + D.iushrn(1); } } - return value; - }, - sceParameters: function (value, mode/*, context*/) { - if (mode === 'params') { - value = mapInterpolationParameters(value, htmlTrustValue); + + if (x.cmp(y) >= 0) { + x.isub(y); + A.isub(C); + B.isub(D); + } else { + y.isub(x); + C.isub(A); + D.isub(B); } - return value; } - }; - // Support legacy strategy name 'escaped' for backwards compatibility. - // TODO should be removed in 3.0 - strategies.escaped = strategies.escapeParameters; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateSanitizationProvider#addStrategy - * @methodOf pascalprecht.translate.$translateSanitizationProvider - * - * @description - * Adds a sanitization strategy to the list of known strategies. - * - * @param {string} strategyName - unique key for a strategy - * @param {StrategyFunction} strategyFunction - strategy function - * @returns {object} this - */ - this.addStrategy = function (strategyName, strategyFunction) { - strategies[strategyName] = strategyFunction; - return this; + return { + a: C, + b: D, + gcd: y.iushln(g) + }; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateSanitizationProvider#removeStrategy - * @methodOf pascalprecht.translate.$translateSanitizationProvider - * - * @description - * Removes a sanitization strategy from the list of known strategies. - * - * @param {string} strategyName - unique key for a strategy - * @returns {object} this - */ - this.removeStrategy = function (strategyName) { - delete strategies[strategyName]; - return this; - }; + // This is reduced incarnation of the binary EEA + // above, designated to invert members of the + // _prime_ fields F(p) at a maximal speed + BN.prototype._invmp = function _invmp (p) { + assert(p.negative === 0); + assert(!p.isZero()); - /** - * @ngdoc function - * @name pascalprecht.translate.$translateSanitizationProvider#useStrategy - * @methodOf pascalprecht.translate.$translateSanitizationProvider - * - * @description - * Selects a sanitization strategy. When an array is provided the strategies will be executed in order. - * - * @param {string|StrategyFunction|array} strategy The sanitization strategy / strategies which should be used. Either a name of an existing strategy, a custom strategy function, or an array consisting of multiple names and / or custom functions. - * @returns {object} this - */ - this.useStrategy = function (strategy) { - hasConfiguredStrategy = true; - currentStrategy = strategy; - return this; - }; + var a = this; + var b = p.clone(); - /** - * @ngdoc object - * @name pascalprecht.translate.$translateSanitization - * @requires $injector - * @requires $log - * - * @description - * Sanitizes interpolation parameters and translated texts. - * - */ - this.$get = ['$injector', '$log', function ($injector, $log) { + if (a.negative !== 0) { + a = a.umod(p); + } else { + a = a.clone(); + } - var cachedStrategyMap = {}; + var x1 = new BN(1); + var x2 = new BN(0); - var applyStrategies = function (value, mode, context, selectedStrategies) { - angular.forEach(selectedStrategies, function (selectedStrategy) { - if (angular.isFunction(selectedStrategy)) { - value = selectedStrategy(value, mode, context); - } else if (angular.isFunction(strategies[selectedStrategy])) { - value = strategies[selectedStrategy](value, mode, context); - } else if (angular.isString(strategies[selectedStrategy])) { - if (!cachedStrategyMap[strategies[selectedStrategy]]) { - try { - cachedStrategyMap[strategies[selectedStrategy]] = $injector.get(strategies[selectedStrategy]); - } catch (e) { - cachedStrategyMap[strategies[selectedStrategy]] = function() {}; - throw new Error('pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: \'' + selectedStrategy + '\''); - } + var delta = b.clone(); + + while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { + for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1); + if (i > 0) { + a.iushrn(i); + while (i-- > 0) { + if (x1.isOdd()) { + x1.iadd(delta); } - value = cachedStrategyMap[strategies[selectedStrategy]](value, mode, context); - } else { - throw new Error('pascalprecht.translate.$translateSanitization: Unknown sanitization strategy: \'' + selectedStrategy + '\''); + + x1.iushrn(1); } - }); - return value; - }; + } - // TODO: should be removed in 3.0 - var showNoStrategyConfiguredWarning = function () { - if (!hasConfiguredStrategy && !hasShownNoStrategyConfiguredWarning) { - $log.warn('pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details.'); - hasShownNoStrategyConfiguredWarning = true; + for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1); + if (j > 0) { + b.iushrn(j); + while (j-- > 0) { + if (x2.isOdd()) { + x2.iadd(delta); + } + + x2.iushrn(1); + } } - }; - if ($injector.has('$sanitize')) { - $sanitize = $injector.get('$sanitize'); + if (a.cmp(b) >= 0) { + a.isub(b); + x1.isub(x2); + } else { + b.isub(a); + x2.isub(x1); + } } - if ($injector.has('$sce')) { - $sce = $injector.get('$sce'); + + var res; + if (a.cmpn(1) === 0) { + res = x1; + } else { + res = x2; } - return { - /** - * @ngdoc function - * @name pascalprecht.translate.$translateSanitization#useStrategy - * @methodOf pascalprecht.translate.$translateSanitization - * - * @description - * Selects a sanitization strategy. When an array is provided the strategies will be executed in order. - * - * @param {string|StrategyFunction|array} strategy The sanitization strategy / strategies which should be used. Either a name of an existing strategy, a custom strategy function, or an array consisting of multiple names and / or custom functions. - */ - useStrategy: (function (self) { - return function (strategy) { - self.useStrategy(strategy); - }; - })(this), + if (res.cmpn(0) < 0) { + res.iadd(p); + } - /** - * @ngdoc function - * @name pascalprecht.translate.$translateSanitization#sanitize - * @methodOf pascalprecht.translate.$translateSanitization - * - * @description - * Sanitizes a value. - * - * @param {string|object} value The value which should be sanitized. - * @param {string} mode The current sanitization mode, either 'params' or 'text'. - * @param {string|StrategyFunction|array} [strategy] Optional custom strategy which should be used instead of the currently selected strategy. - * @param {string} [context] The context of this call: filter, service. Default is service - * @returns {string|object} sanitized value - */ - sanitize: function (value, mode, strategy, context) { - if (!currentStrategy) { - showNoStrategyConfiguredWarning(); - } + return res; + }; - if (!strategy && strategy !== null) { - strategy = currentStrategy; - } + BN.prototype.gcd = function gcd (num) { + if (this.isZero()) return num.abs(); + if (num.isZero()) return this.abs(); - if (!strategy) { - return value; - } + var a = this.clone(); + var b = num.clone(); + a.negative = 0; + b.negative = 0; - if (!context) { - context = 'service'; - } + // Remove common factor of two + for (var shift = 0; a.isEven() && b.isEven(); shift++) { + a.iushrn(1); + b.iushrn(1); + } - var selectedStrategies = angular.isArray(strategy) ? strategy : [strategy]; - return applyStrategies(value, mode, context, selectedStrategies); + do { + while (a.isEven()) { + a.iushrn(1); + } + while (b.isEven()) { + b.iushrn(1); } - }; - }]; - var htmlEscapeValue = function (value) { - var element = angular.element('
'); - element.text(value); // not chainable, see #1044 - return element.html(); - }; + var r = a.cmp(b); + if (r < 0) { + // Swap `a` and `b` to make `a` always bigger than `b` + var t = a; + a = b; + b = t; + } else if (r === 0 || b.cmpn(1) === 0) { + break; + } - var htmlSanitizeValue = function (value) { - if (!$sanitize) { - throw new Error('pascalprecht.translate.$translateSanitization: Error cannot find $sanitize service. Either include the ngSanitize module (https://docs.angularjs.org/api/ngSanitize) or use a sanitization strategy which does not depend on $sanitize, such as \'escape\'.'); - } - return $sanitize(value); + a.isub(b); + } while (true); + + return b.iushln(shift); }; - var htmlTrustValue = function (value) { - if (!$sce) { - throw new Error('pascalprecht.translate.$translateSanitization: Error cannot find $sce service.'); - } - return $sce.trustAsHtml(value); + // Invert number in the field F(num) + BN.prototype.invm = function invm (num) { + return this.egcd(num).a.umod(num); }; - var mapInterpolationParameters = function (value, iteratee, stack) { - if (angular.isDate(value)) { - return value; - } else if (angular.isObject(value)) { - var result = angular.isArray(value) ? [] : {}; + BN.prototype.isEven = function isEven () { + return (this.words[0] & 1) === 0; + }; - if (!stack) { - stack = []; - } else { - if (stack.indexOf(value) > -1) { - throw new Error('pascalprecht.translate.$translateSanitization: Error cannot interpolate parameter due recursive object'); - } - } + BN.prototype.isOdd = function isOdd () { + return (this.words[0] & 1) === 1; + }; - stack.push(value); - angular.forEach(value, function (propertyValue, propertyKey) { + // And first word and num + BN.prototype.andln = function andln (num) { + return this.words[0] & num; + }; - /* Skipping function properties. */ - if (angular.isFunction(propertyValue)) { - return; - } + // Increment at the bit position in-line + BN.prototype.bincn = function bincn (bit) { + assert(typeof bit === 'number'); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; - result[propertyKey] = mapInterpolationParameters(propertyValue, iteratee, stack); - }); - stack.splice(-1, 1); // remove last + // Fast case: bit is much higher than all existing words + if (this.length <= s) { + this._expand(s + 1); + this.words[s] |= q; + return this; + } - return result; - } else if (angular.isNumber(value)) { - return value; - } else if (value === true || value === false) { - return value; - } else if (!angular.isUndefined(value) && value !== null) { - return iteratee(value); - } else { - return value; + // Add bit and propagate, if needed + var carry = q; + for (var i = s; carry !== 0 && i < this.length; i++) { + var w = this.words[i] | 0; + w += carry; + carry = w >>> 26; + w &= 0x3ffffff; + this.words[i] = w; + } + if (carry !== 0) { + this.words[i] = carry; + this.length++; } + return this; }; -} - -/** - * @ngdoc object - * @name pascalprecht.translate.$translateProvider - * @description - * - * $translateProvider allows developers to register translation-tables, asynchronous loaders - * and similar to configure translation behavior directly inside of a module. - * - */ -angular.module('pascalprecht.translate') - .constant('pascalprechtTranslateOverrider', {}) - .provider('$translate', $translate); -function $translate($STORAGE_KEY, $windowProvider, $translateSanitizationProvider, pascalprechtTranslateOverrider) { + BN.prototype.isZero = function isZero () { + return this.length === 1 && this.words[0] === 0; + }; - 'use strict'; + BN.prototype.cmpn = function cmpn (num) { + var negative = num < 0; - var $translationTable = {}, - $preferredLanguage, - $availableLanguageKeys = [], - $languageKeyAliases, - $fallbackLanguage, - $fallbackWasString, - $uses, - $nextLang, - $storageFactory, - $storageKey = $STORAGE_KEY, - $storagePrefix, - $missingTranslationHandlerFactory, - $interpolationFactory, - $interpolatorFactories = [], - $loaderFactory, - $cloakClassName = 'translate-cloak', - $loaderOptions, - $notFoundIndicatorLeft, - $notFoundIndicatorRight, - $postCompilingEnabled = false, - $forceAsyncReloadEnabled = false, - $nestedObjectDelimeter = '.', - $isReady = false, - $keepContent = false, - loaderCache, - directivePriority = 0, - statefulFilter = true, - postProcessFn, - uniformLanguageTagResolver = 'default', - languageTagResolver = { - 'default' : function (tag) { - return (tag || '').split('-').join('_'); - }, - java : function (tag) { - var temp = (tag || '').split('-').join('_'); - var parts = temp.split('_'); - return parts.length > 1 ? (parts[0].toLowerCase() + '_' + parts[1].toUpperCase()) : temp; - }, - bcp47 : function (tag) { - var temp = (tag || '').split('_').join('-'); - var parts = temp.split('-'); + if (this.negative !== 0 && !negative) return -1; + if (this.negative === 0 && negative) return 1; - switch (parts.length) { - case 1: // language only - parts[0] = parts[0].toLowerCase(); - break; - case 2: // language-script or language-region - parts[0] = parts[0].toLowerCase(); - if (parts[1].length === 4) { // parts[1] is script - parts[1] = parts[1].charAt(0).toUpperCase() + parts[1].slice(1).toLowerCase(); - } else { // parts[1] is region - parts[1] = parts[1].toUpperCase(); - } - break; - case 3: // language-script-region - parts[0] = parts[0].toLowerCase(); - parts[1] = parts[1].charAt(0).toUpperCase() + parts[1].slice(1).toLowerCase(); - parts[2] = parts[2].toUpperCase(); - break; - default: - return temp; - } + this.strip(); - return parts.join('-'); - }, - 'iso639-1' : function (tag) { - var temp = (tag || '').split('_').join('-'); - var parts = temp.split('-'); - return parts[0].toLowerCase(); + var res; + if (this.length > 1) { + res = 1; + } else { + if (negative) { + num = -num; } - }; - - var version = '2.18.1'; - - // tries to determine the browsers language - var getFirstBrowserLanguage = function () { - - // internal purpose only - if (angular.isFunction(pascalprechtTranslateOverrider.getLocale)) { - return pascalprechtTranslateOverrider.getLocale(); - } - var nav = $windowProvider.$get().navigator, - browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'], - i, - language; + assert(num <= 0x3ffffff, 'Number is too big'); - // support for HTML 5.1 "navigator.languages" - if (angular.isArray(nav.languages)) { - for (i = 0; i < nav.languages.length; i++) { - language = nav.languages[i]; - if (language && language.length) { - return language; - } - } + var w = this.words[0] | 0; + res = w === num ? 0 : w < num ? -1 : 1; } + if (this.negative !== 0) return -res | 0; + return res; + }; - // support for other well known properties in browsers - for (i = 0; i < browserLanguagePropertyKeys.length; i++) { - language = nav[browserLanguagePropertyKeys[i]]; - if (language && language.length) { - return language; - } - } + // Compare two numbers and return: + // 1 - if `this` > `num` + // 0 - if `this` == `num` + // -1 - if `this` < `num` + BN.prototype.cmp = function cmp (num) { + if (this.negative !== 0 && num.negative === 0) return -1; + if (this.negative === 0 && num.negative !== 0) return 1; - return null; + var res = this.ucmp(num); + if (this.negative !== 0) return -res | 0; + return res; }; - getFirstBrowserLanguage.displayName = 'angular-translate/service: getFirstBrowserLanguage'; - // tries to determine the browsers locale - var getLocale = function () { - var locale = getFirstBrowserLanguage() || ''; - if (languageTagResolver[uniformLanguageTagResolver]) { - locale = languageTagResolver[uniformLanguageTagResolver](locale); - } - return locale; - }; - getLocale.displayName = 'angular-translate/service: getLocale'; + // Unsigned comparison + BN.prototype.ucmp = function ucmp (num) { + // At this point both numbers have the same sign + if (this.length > num.length) return 1; + if (this.length < num.length) return -1; - /** - * @name indexOf - * @private - * - * @description - * indexOf polyfill. Kinda sorta. - * - * @param {array} array Array to search in. - * @param {string} searchElement Element to search for. - * - * @returns {int} Index of search element. - */ - var indexOf = function (array, searchElement) { - for (var i = 0, len = array.length; i < len; i++) { - if (array[i] === searchElement) { - return i; + var res = 0; + for (var i = this.length - 1; i >= 0; i--) { + var a = this.words[i] | 0; + var b = num.words[i] | 0; + + if (a === b) continue; + if (a < b) { + res = -1; + } else if (a > b) { + res = 1; } + break; } - return -1; + return res; }; - /** - * @name trim - * @private - * - * @description - * trim polyfill - * - * @returns {string} The string stripped of whitespace from both ends - */ - var trim = function () { - return this.toString().replace(/^\s+|\s+$/g, ''); + BN.prototype.gtn = function gtn (num) { + return this.cmpn(num) === 1; }; - /** - * @name lowercase - * @private - * - * @description - * Return the lowercase string only if the type is string - * - * @returns {string} The string all in lowercase - */ - var lowercase = function (string) { - return angular.isString(string) ? string.toLowerCase() : string; + BN.prototype.gt = function gt (num) { + return this.cmp(num) === 1; }; - var negotiateLocale = function (preferred) { - if (!preferred) { - return; - } + BN.prototype.gten = function gten (num) { + return this.cmpn(num) >= 0; + }; - var avail = [], - locale = lowercase(preferred), - i = 0, - n = $availableLanguageKeys.length; + BN.prototype.gte = function gte (num) { + return this.cmp(num) >= 0; + }; - for (; i < n; i++) { - avail.push(lowercase($availableLanguageKeys[i])); - } + BN.prototype.ltn = function ltn (num) { + return this.cmpn(num) === -1; + }; - // Check for an exact match in our list of available keys - i = indexOf(avail, locale); - if (i > -1) { - return $availableLanguageKeys[i]; - } + BN.prototype.lt = function lt (num) { + return this.cmp(num) === -1; + }; - if ($languageKeyAliases) { - var alias; - for (var langKeyAlias in $languageKeyAliases) { - if ($languageKeyAliases.hasOwnProperty(langKeyAlias)) { - var hasWildcardKey = false; - var hasExactKey = Object.prototype.hasOwnProperty.call($languageKeyAliases, langKeyAlias) && - lowercase(langKeyAlias) === lowercase(preferred); + BN.prototype.lten = function lten (num) { + return this.cmpn(num) <= 0; + }; - if (langKeyAlias.slice(-1) === '*') { - hasWildcardKey = lowercase(langKeyAlias.slice(0, -1)) === lowercase(preferred.slice(0, langKeyAlias.length - 1)); - } - if (hasExactKey || hasWildcardKey) { - alias = $languageKeyAliases[langKeyAlias]; - if (indexOf(avail, lowercase(alias)) > -1) { - return alias; - } - } - } - } - } + BN.prototype.lte = function lte (num) { + return this.cmp(num) <= 0; + }; - // Check for a language code without region - var parts = preferred.split('_'); + BN.prototype.eqn = function eqn (num) { + return this.cmpn(num) === 0; + }; - if (parts.length > 1 && indexOf(avail, lowercase(parts[0])) > -1) { - return parts[0]; - } + BN.prototype.eq = function eq (num) { + return this.cmp(num) === 0; + }; - // If everything fails, return undefined. - return; + // + // A reduce context, could be using montgomery or something better, depending + // on the `m` itself. + // + BN.red = function red (num) { + return new Red(num); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#translations - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Registers a new translation table for specific language key. - * - * To register a translation table for specific language, pass a defined language - * key as first parameter. - * - *
-   *  // register translation table for language: 'de_DE'
-   *  $translateProvider.translations('de_DE', {
-   *    'GREETING': 'Hallo Welt!'
-   *  });
-   *
-   *  // register another one
-   *  $translateProvider.translations('en_US', {
-   *    'GREETING': 'Hello world!'
-   *  });
-   * 
- * - * When registering multiple translation tables for for the same language key, - * the actual translation table gets extended. This allows you to define module - * specific translation which only get added, once a specific module is loaded in - * your app. - * - * Invoking this method with no arguments returns the translation table which was - * registered with no language key. Invoking it with a language key returns the - * related translation table. - * - * @param {string} langKey A language key. - * @param {object} translationTable A plain old JavaScript object that represents a translation table. - * - */ - var translations = function (langKey, translationTable) { + BN.prototype.toRed = function toRed (ctx) { + assert(!this.red, 'Already a number in reduction context'); + assert(this.negative === 0, 'red works only with positives'); + return ctx.convertTo(this)._forceRed(ctx); + }; - if (!langKey && !translationTable) { - return $translationTable; - } + BN.prototype.fromRed = function fromRed () { + assert(this.red, 'fromRed works only with numbers in reduction context'); + return this.red.convertFrom(this); + }; - if (langKey && !translationTable) { - if (angular.isString(langKey)) { - return $translationTable[langKey]; - } - } else { - if (!angular.isObject($translationTable[langKey])) { - $translationTable[langKey] = {}; - } - angular.extend($translationTable[langKey], flatObject(translationTable)); - } + BN.prototype._forceRed = function _forceRed (ctx) { + this.red = ctx; return this; }; - this.translations = translations; + BN.prototype.forceRed = function forceRed (ctx) { + assert(!this.red, 'Already a number in reduction context'); + return this._forceRed(ctx); + }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#cloakClassName - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * - * Let's you change the class name for `translate-cloak` directive. - * Default class name is `translate-cloak`. - * - * @param {string} name translate-cloak class name - */ - this.cloakClassName = function (name) { - if (!name) { - return $cloakClassName; - } - $cloakClassName = name; - return this; + BN.prototype.redAdd = function redAdd (num) { + assert(this.red, 'redAdd works only with red numbers'); + return this.red.add(this, num); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#nestedObjectDelimeter - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * - * Let's you change the delimiter for namespaced translations. - * Default delimiter is `.`. - * - * @param {string} delimiter namespace separator - */ - this.nestedObjectDelimeter = function (delimiter) { - if (!delimiter) { - return $nestedObjectDelimeter; - } - $nestedObjectDelimeter = delimiter; - return this; + BN.prototype.redIAdd = function redIAdd (num) { + assert(this.red, 'redIAdd works only with red numbers'); + return this.red.iadd(this, num); }; - /** - * @name flatObject - * @private - * - * @description - * Flats an object. This function is used to flatten given translation data with - * namespaces, so they are later accessible via dot notation. - */ - var flatObject = function (data, path, result, prevKey) { - var key, keyWithPath, keyWithShortPath, val; + BN.prototype.redSub = function redSub (num) { + assert(this.red, 'redSub works only with red numbers'); + return this.red.sub(this, num); + }; - if (!path) { - path = []; - } - if (!result) { - result = {}; - } - for (key in data) { - if (!Object.prototype.hasOwnProperty.call(data, key)) { - continue; - } - val = data[key]; - if (angular.isObject(val)) { - flatObject(val, path.concat(key), result, key); - } else { - keyWithPath = path.length ? ('' + path.join($nestedObjectDelimeter) + $nestedObjectDelimeter + key) : key; - if (path.length && key === prevKey) { - // Create shortcut path (foo.bar == foo.bar.bar) - keyWithShortPath = '' + path.join($nestedObjectDelimeter); - // Link it to original path - result[keyWithShortPath] = '@:' + keyWithPath; - } - result[keyWithPath] = val; - } - } - return result; + BN.prototype.redISub = function redISub (num) { + assert(this.red, 'redISub works only with red numbers'); + return this.red.isub(this, num); }; - flatObject.displayName = 'flatObject'; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#addInterpolation - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Adds interpolation services to angular-translate, so it can manage them. - * - * @param {object} factory Interpolation service factory - */ - this.addInterpolation = function (factory) { - $interpolatorFactories.push(factory); - return this; + BN.prototype.redShl = function redShl (num) { + assert(this.red, 'redShl works only with red numbers'); + return this.red.shl(this, num); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useMessageFormatInterpolation - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use interpolation functionality of messageformat.js. - * This is useful when having high level pluralization and gender selection. - */ - this.useMessageFormatInterpolation = function () { - return this.useInterpolation('$translateMessageFormatInterpolation'); + BN.prototype.redMul = function redMul (num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.mul(this, num); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useInterpolation - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate which interpolation style to use as default, application-wide. - * Simply pass a factory/service name. The interpolation service has to implement - * the correct interface. - * - * @param {string} factory Interpolation service name. - */ - this.useInterpolation = function (factory) { - $interpolationFactory = factory; - return this; + BN.prototype.redIMul = function redIMul (num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.imul(this, num); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useSanitizeStrategy - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Simply sets a sanitation strategy type. - * - * @param {string} value Strategy type. - */ - this.useSanitizeValueStrategy = function (value) { - $translateSanitizationProvider.useStrategy(value); - return this; + BN.prototype.redSqr = function redSqr () { + assert(this.red, 'redSqr works only with red numbers'); + this.red._verify1(this); + return this.red.sqr(this); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#preferredLanguage - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells the module which of the registered translation tables to use for translation - * at initial startup by passing a language key. Similar to `$translateProvider#use` - * only that it says which language to **prefer**. - * It is recommended to call this after {@link pascalprecht.translate.$translate#fallbackLanguage fallbackLanguage()}. - * - * @param {string} langKey A language key. - */ - this.preferredLanguage = function (langKey) { - if (langKey) { - setupPreferredLanguage(langKey); - return this; - } - return $preferredLanguage; + BN.prototype.redISqr = function redISqr () { + assert(this.red, 'redISqr works only with red numbers'); + this.red._verify1(this); + return this.red.isqr(this); }; - var setupPreferredLanguage = function (langKey) { - if (langKey) { - $preferredLanguage = langKey; - } - return $preferredLanguage; + + // Square root over p + BN.prototype.redSqrt = function redSqrt () { + assert(this.red, 'redSqrt works only with red numbers'); + this.red._verify1(this); + return this.red.sqrt(this); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#translationNotFoundIndicator - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Sets an indicator which is used when a translation isn't found. E.g. when - * setting the indicator as 'X' and one tries to translate a translation id - * called `NOT_FOUND`, this will result in `X NOT_FOUND X`. - * - * Internally this methods sets a left indicator and a right indicator using - * `$translateProvider.translationNotFoundIndicatorLeft()` and - * `$translateProvider.translationNotFoundIndicatorRight()`. - * - * **Note**: These methods automatically add a whitespace between the indicators - * and the translation id. - * - * @param {string} indicator An indicator, could be any string. - */ - this.translationNotFoundIndicator = function (indicator) { - this.translationNotFoundIndicatorLeft(indicator); - this.translationNotFoundIndicatorRight(indicator); - return this; + + BN.prototype.redInvm = function redInvm () { + assert(this.red, 'redInvm works only with red numbers'); + this.red._verify1(this); + return this.red.invm(this); }; - /** - * ngdoc function - * @name pascalprecht.translate.$translateProvider#translationNotFoundIndicatorLeft - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Sets an indicator which is used when a translation isn't found left to the - * translation id. - * - * @param {string} indicator An indicator. - */ - this.translationNotFoundIndicatorLeft = function (indicator) { - if (!indicator) { - return $notFoundIndicatorLeft; - } - $notFoundIndicatorLeft = indicator; - return this; + // Return negative clone of `this` % `red modulo` + BN.prototype.redNeg = function redNeg () { + assert(this.red, 'redNeg works only with red numbers'); + this.red._verify1(this); + return this.red.neg(this); }; - /** - * ngdoc function - * @name pascalprecht.translate.$translateProvider#translationNotFoundIndicatorLeft - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Sets an indicator which is used when a translation isn't found right to the - * translation id. - * - * @param {string} indicator An indicator. - */ - this.translationNotFoundIndicatorRight = function (indicator) { - if (!indicator) { - return $notFoundIndicatorRight; - } - $notFoundIndicatorRight = indicator; - return this; + BN.prototype.redPow = function redPow (num) { + assert(this.red && !num.red, 'redPow(normalNum)'); + this.red._verify1(this); + return this.red.pow(this, num); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#fallbackLanguage - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells the module which of the registered translation tables to use when missing translations - * at initial startup by passing a language key. Similar to `$translateProvider#use` - * only that it says which language to **fallback**. - * - * @param {string||array} langKey A language key. - * - */ - this.fallbackLanguage = function (langKey) { - fallbackStack(langKey); - return this; + // Prime numbers with efficient reduction + var primes = { + k256: null, + p224: null, + p192: null, + p25519: null }; - var fallbackStack = function (langKey) { - if (langKey) { - if (angular.isString(langKey)) { - $fallbackWasString = true; - $fallbackLanguage = [langKey]; - } else if (angular.isArray(langKey)) { - $fallbackWasString = false; - $fallbackLanguage = langKey; - } - if (angular.isString($preferredLanguage) && indexOf($fallbackLanguage, $preferredLanguage) < 0) { - $fallbackLanguage.push($preferredLanguage); - } + // Pseudo-Mersenne prime + function MPrime (name, p) { + // P = 2 ^ N - K + this.name = name; + this.p = new BN(p, 16); + this.n = this.p.bitLength(); + this.k = new BN(1).iushln(this.n).isub(this.p); - return this; - } else { - if ($fallbackWasString) { - return $fallbackLanguage[0]; - } else { - return $fallbackLanguage; - } - } + this.tmp = this._tmp(); + } + + MPrime.prototype._tmp = function _tmp () { + var tmp = new BN(null); + tmp.words = new Array(Math.ceil(this.n / 13)); + return tmp; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#use - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Set which translation table to use for translation by given language key. When - * trying to 'use' a language which isn't provided, it'll throw an error. - * - * You actually don't have to use this method since `$translateProvider#preferredLanguage` - * does the job too. - * - * @param {string} langKey A language key. - */ - this.use = function (langKey) { - if (langKey) { - if (!$translationTable[langKey] && (!$loaderFactory)) { - // only throw an error, when not loading translation data asynchronously - throw new Error('$translateProvider couldn\'t find translationTable for langKey: \'' + langKey + '\''); - } - $uses = langKey; - return this; + MPrime.prototype.ireduce = function ireduce (num) { + // Assumes that `num` is less than `P^2` + // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) + var r = num; + var rlen; + + do { + this.split(r, this.tmp); + r = this.imulK(r); + r = r.iadd(this.tmp); + rlen = r.bitLength(); + } while (rlen > this.n); + + var cmp = rlen < this.n ? -1 : r.ucmp(this.p); + if (cmp === 0) { + r.words[0] = 0; + r.length = 1; + } else if (cmp > 0) { + r.isub(this.p); + } else { + r.strip(); } - return $uses; + + return r; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#resolveClientLocale - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * This returns the current browser/client's language key. The result is processed with the configured uniform tag resolver. - * - * @returns {string} the current client/browser language key - */ - this.resolveClientLocale = function () { - return getLocale(); + MPrime.prototype.split = function split (input, out) { + input.iushrn(this.n, 0, out); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#storageKey - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells the module which key must represent the choosed language by a user in the storage. - * - * @param {string} key A key for the storage. - */ - var storageKey = function (key) { - if (!key) { - if ($storagePrefix) { - return $storagePrefix + $storageKey; - } - return $storageKey; - } - $storageKey = key; - return this; + MPrime.prototype.imulK = function imulK (num) { + return num.imul(this.k); }; - this.storageKey = storageKey; + function K256 () { + MPrime.call( + this, + 'k256', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); + } + inherits(K256, MPrime); - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useUrlLoader - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use `$translateUrlLoader` extension service as loader. - * - * @param {string} url Url - * @param {Object=} options Optional configuration object - */ - this.useUrlLoader = function (url, options) { - return this.useLoader('$translateUrlLoader', angular.extend({url : url}, options)); - }; + K256.prototype.split = function split (input, output) { + // 256 = 9 * 26 + 22 + var mask = 0x3fffff; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useStaticFilesLoader - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use `$translateStaticFilesLoader` extension service as loader. - * - * @param {Object=} options Optional configuration object - */ - this.useStaticFilesLoader = function (options) { - return this.useLoader('$translateStaticFilesLoader', options); - }; + var outLen = Math.min(input.length, 9); + for (var i = 0; i < outLen; i++) { + output.words[i] = input.words[i]; + } + output.length = outLen; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useLoader - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use any other service as loader. - * - * @param {string} loaderFactory Factory name to use - * @param {Object=} options Optional configuration object - */ - this.useLoader = function (loaderFactory, options) { - $loaderFactory = loaderFactory; - $loaderOptions = options || {}; - return this; - }; + if (input.length <= 9) { + input.words[0] = 0; + input.length = 1; + return; + } - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useLocalStorage - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use `$translateLocalStorage` service as storage layer. - * - */ - this.useLocalStorage = function () { - return this.useStorage('$translateLocalStorage'); - }; + // Shift by 9 limbs + var prev = input.words[9]; + output.words[output.length++] = prev & mask; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useCookieStorage - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use `$translateCookieStorage` service as storage layer. - */ - this.useCookieStorage = function () { - return this.useStorage('$translateCookieStorage'); + for (i = 10; i < input.length; i++) { + var next = input.words[i] | 0; + input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); + prev = next; + } + prev >>>= 22; + input.words[i - 10] = prev; + if (prev === 0 && input.length > 10) { + input.length -= 10; + } else { + input.length -= 9; + } }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useStorage - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use custom service as storage layer. - */ - this.useStorage = function (storageFactory) { - $storageFactory = storageFactory; - return this; - }; + K256.prototype.imulK = function imulK (num) { + // K = 0x1000003d1 = [ 0x40, 0x3d1 ] + num.words[num.length] = 0; + num.words[num.length + 1] = 0; + num.length += 2; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#storagePrefix - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Sets prefix for storage key. - * - * @param {string} prefix Storage key prefix - */ - this.storagePrefix = function (prefix) { - if (!prefix) { - return prefix; + // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 + var lo = 0; + for (var i = 0; i < num.length; i++) { + var w = num.words[i] | 0; + lo += w * 0x3d1; + num.words[i] = lo & 0x3ffffff; + lo = w * 0x40 + ((lo / 0x4000000) | 0); } - $storagePrefix = prefix; - return this; - }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useMissingTranslationHandlerLog - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to use built-in log handler when trying to translate - * a translation Id which doesn't exist. - * - * This is actually a shortcut method for `useMissingTranslationHandler()`. - * - */ - this.useMissingTranslationHandlerLog = function () { - return this.useMissingTranslationHandler('$translateMissingTranslationHandlerLog'); + // Fast length reduction + if (num.words[num.length - 1] === 0) { + num.length--; + if (num.words[num.length - 1] === 0) { + num.length--; + } + } + return num; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useMissingTranslationHandler - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Expects a factory name which later gets instantiated with `$injector`. - * This method can be used to tell angular-translate to use a custom - * missingTranslationHandler. Just build a factory which returns a function - * and expects a translation id as argument. - * - * Example: - *
-   *  app.config(function ($translateProvider) {
-   *    $translateProvider.useMissingTranslationHandler('customHandler');
-   *  });
-   *
-   *  app.factory('customHandler', function (dep1, dep2) {
-   *    return function (translationId) {
-   *      // something with translationId and dep1 and dep2
-   *    };
-   *  });
-   * 
- * - * @param {string} factory Factory name - */ - this.useMissingTranslationHandler = function (factory) { - $missingTranslationHandlerFactory = factory; - return this; - }; + function P224 () { + MPrime.call( + this, + 'p224', + 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); + } + inherits(P224, MPrime); - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#usePostCompiling - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * If post compiling is enabled, all translated values will be processed - * again with AngularJS' $compile. - * - * Example: - *
-   *  app.config(function ($translateProvider) {
-   *    $translateProvider.usePostCompiling(true);
-   *  });
-   * 
- * - * @param {string} factory Factory name - */ - this.usePostCompiling = function (value) { - $postCompilingEnabled = !(!value); - return this; - }; + function P192 () { + MPrime.call( + this, + 'p192', + 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); + } + inherits(P192, MPrime); - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#forceAsyncReload - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * If force async reload is enabled, async loader will always be called - * even if $translationTable already contains the language key, adding - * possible new entries to the $translationTable. - * - * Example: - *
-   *  app.config(function ($translateProvider) {
-   *    $translateProvider.forceAsyncReload(true);
-   *  });
-   * 
- * - * @param {boolean} value - valid values are true or false - */ - this.forceAsyncReload = function (value) { - $forceAsyncReloadEnabled = !(!value); - return this; + function P25519 () { + // 2 ^ 255 - 19 + MPrime.call( + this, + '25519', + '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); + } + inherits(P25519, MPrime); + + P25519.prototype.imulK = function imulK (num) { + // K = 0x13 + var carry = 0; + for (var i = 0; i < num.length; i++) { + var hi = (num.words[i] | 0) * 0x13 + carry; + var lo = hi & 0x3ffffff; + hi >>>= 26; + + num.words[i] = lo; + carry = hi; + } + if (carry !== 0) { + num.words[num.length++] = carry; + } + return num; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#uniformLanguageTag - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate which language tag should be used as a result when determining - * the current browser language. - * - * This setting must be set before invoking {@link pascalprecht.translate.$translateProvider#methods_determinePreferredLanguage determinePreferredLanguage()}. - * - *
-   * $translateProvider
-   *   .uniformLanguageTag('bcp47')
-   *   .determinePreferredLanguage()
-   * 
- * - * The resolver currently supports: - * * default - * (traditionally: hyphens will be converted into underscores, i.e. en-US => en_US) - * en-US => en_US - * en_US => en_US - * en-us => en_us - * * java - * like default, but the second part will be always in uppercase - * en-US => en_US - * en_US => en_US - * en-us => en_US - * * BCP 47 (RFC 4646 & 4647) - * EN => en - * en-US => en-US - * en_US => en-US - * en-us => en-US - * sr-latn => sr-Latn - * sr-latn-rs => sr-Latn-RS - * - * See also: - * * http://en.wikipedia.org/wiki/IETF_language_tag - * * http://www.w3.org/International/core/langtags/ - * * http://tools.ietf.org/html/bcp47 - * - * @param {string|object} options - options (or standard) - * @param {string} options.standard - valid values are 'default', 'bcp47', 'java' - */ - this.uniformLanguageTag = function (options) { + // Exported mostly for testing purposes, use plain name instead + BN._prime = function prime (name) { + // Cached version of prime + if (primes[name]) return primes[name]; - if (!options) { - options = {}; - } else if (angular.isString(options)) { - options = { - standard : options - }; + var prime; + if (name === 'k256') { + prime = new K256(); + } else if (name === 'p224') { + prime = new P224(); + } else if (name === 'p192') { + prime = new P192(); + } else if (name === 'p25519') { + prime = new P25519(); + } else { + throw new Error('Unknown prime ' + name); } + primes[name] = prime; - uniformLanguageTagResolver = options.standard; + return prime; + }; - return this; + // + // Base reduction engine + // + function Red (m) { + if (typeof m === 'string') { + var prime = BN._prime(m); + this.m = prime.p; + this.prime = prime; + } else { + assert(m.gtn(1), 'modulus must be greater than 1'); + this.m = m; + this.prime = null; + } + } + + Red.prototype._verify1 = function _verify1 (a) { + assert(a.negative === 0, 'red works only with positives'); + assert(a.red, 'red works only with red numbers'); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#determinePreferredLanguage - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Tells angular-translate to try to determine on its own which language key - * to set as preferred language. When `fn` is given, angular-translate uses it - * to determine a language key, otherwise it uses the built-in `getLocale()` - * method. - * - * The `getLocale()` returns a language key in the format `[lang]_[country]` or - * `[lang]` depending on what the browser provides. - * - * Use this method at your own risk, since not all browsers return a valid - * locale (see {@link pascalprecht.translate.$translateProvider#methods_uniformLanguageTag uniformLanguageTag()}). - * - * @param {Function=} fn Function to determine a browser's locale - */ - this.determinePreferredLanguage = function (fn) { + Red.prototype._verify2 = function _verify2 (a, b) { + assert((a.negative | b.negative) === 0, 'red works only with positives'); + assert(a.red && a.red === b.red, + 'red works only with red numbers'); + }; - var locale = (fn && angular.isFunction(fn)) ? fn() : getLocale(); + Red.prototype.imod = function imod (a) { + if (this.prime) return this.prime.ireduce(a)._forceRed(this); + return a.umod(this.m)._forceRed(this); + }; - if (!$availableLanguageKeys.length) { - $preferredLanguage = locale; - } else { - $preferredLanguage = negotiateLocale(locale) || locale; + Red.prototype.neg = function neg (a) { + if (a.isZero()) { + return a.clone(); } - return this; + return this.m.sub(a)._forceRed(this); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#registerAvailableLanguageKeys - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Registers a set of language keys the app will work with. Use this method in - * combination with - * {@link pascalprecht.translate.$translateProvider#determinePreferredLanguage determinePreferredLanguage}. - * When available languages keys are registered, angular-translate - * tries to find the best fitting language key depending on the browsers locale, - * considering your language key convention. - * - * @param {object} languageKeys Array of language keys the your app will use - * @param {object=} aliases Alias map. - */ - this.registerAvailableLanguageKeys = function (languageKeys, aliases) { - if (languageKeys) { - $availableLanguageKeys = languageKeys; - if (aliases) { - $languageKeyAliases = aliases; - } - return this; + Red.prototype.add = function add (a, b) { + this._verify2(a, b); + + var res = a.add(b); + if (res.cmp(this.m) >= 0) { + res.isub(this.m); } - return $availableLanguageKeys; + return res._forceRed(this); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#useLoaderCache - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Registers a cache for internal $http based loaders. - * {@link pascalprecht.translate.$translationCache $translationCache}. - * When false the cache will be disabled (default). When true or undefined - * the cache will be a default (see $cacheFactory). When an object it will - * be treat as a cache object itself: the usage is $http({cache: cache}) - * - * @param {object} cache boolean, string or cache-object - */ - this.useLoaderCache = function (cache) { - if (cache === false) { - // disable cache - loaderCache = undefined; - } else if (cache === true) { - // enable cache using AJS defaults - loaderCache = true; - } else if (typeof(cache) === 'undefined') { - // enable cache using default - loaderCache = '$translationCache'; - } else if (cache) { - // enable cache using given one (see $cacheFactory) - loaderCache = cache; + Red.prototype.iadd = function iadd (a, b) { + this._verify2(a, b); + + var res = a.iadd(b); + if (res.cmp(this.m) >= 0) { + res.isub(this.m); } - return this; + return res; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#directivePriority - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Sets the default priority of the translate directive. The standard value is `0`. - * Calling this function without an argument will return the current value. - * - * @param {number} priority for the translate-directive - */ - this.directivePriority = function (priority) { - if (priority === undefined) { - // getter - return directivePriority; - } else { - // setter with chaining - directivePriority = priority; - return this; + Red.prototype.sub = function sub (a, b) { + this._verify2(a, b); + + var res = a.sub(b); + if (res.cmpn(0) < 0) { + res.iadd(this.m); } + return res._forceRed(this); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#statefulFilter - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * Since AngularJS 1.3, filters which are not stateless (depending at the scope) - * have to explicit define this behavior. - * Sets whether the translate filter should be stateful or stateless. The standard value is `true` - * meaning being stateful. - * Calling this function without an argument will return the current value. - * - * @param {boolean} state - defines the state of the filter - */ - this.statefulFilter = function (state) { - if (state === undefined) { - // getter - return statefulFilter; - } else { - // setter with chaining - statefulFilter = state; - return this; + Red.prototype.isub = function isub (a, b) { + this._verify2(a, b); + + var res = a.isub(b); + if (res.cmpn(0) < 0) { + res.iadd(this.m); } + return res; }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#postProcess - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * The post processor will be intercept right after the translation result. It can modify the result. - * - * @param {object} fn Function or service name (string) to be called after the translation value has been set / resolved. The function itself will enrich every value being processed and then continue the normal resolver process - */ - this.postProcess = function (fn) { - if (fn) { - postProcessFn = fn; - } else { - postProcessFn = undefined; - } - return this; + Red.prototype.shl = function shl (a, num) { + this._verify1(a); + return this.imod(a.ushln(num)); }; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateProvider#keepContent - * @methodOf pascalprecht.translate.$translateProvider - * - * @description - * If keepContent is set to true than translate directive will always use innerHTML - * as a default translation - * - * Example: - *
-   *  app.config(function ($translateProvider) {
-   *    $translateProvider.keepContent(true);
-   *  });
-   * 
- * - * @param {boolean} value - valid values are true or false - */ - this.keepContent = function (value) { - $keepContent = !(!value); - return this; + Red.prototype.imul = function imul (a, b) { + this._verify2(a, b); + return this.imod(a.imul(b)); }; - /** - * @ngdoc object - * @name pascalprecht.translate.$translate - * @requires $interpolate - * @requires $log - * @requires $rootScope - * @requires $q - * - * @description - * The `$translate` service is the actual core of angular-translate. It expects a translation id - * and optional interpolate parameters to translate contents. - * - *
-   *  $translate('HEADLINE_TEXT').then(function (translation) {
-   *    $scope.translatedText = translation;
-   *  });
-   * 
- * - * @param {string|array} translationId A token which represents a translation id - * This can be optionally an array of translation ids which - * results that the function returns an object where each key - * is the translation id and the value the translation. - * @param {object=} [interpolateParams={}] An object hash for dynamic values - * @param {string=} [interpolationId=undefined] The id of the interpolation to use (use default unless set via useInterpolation()) - * @param {string=} [defaultTranslationText=undefined] the optional default translation text that is written as - * as default text in case it is not found in any configured language - * @param {string=} [forceLanguage=false] A language to be used instead of the current language - * @param {string=} [sanitizeStrategy=undefined] force sanitize strategy for this call instead of using the configured one (use default unless set) - * @returns {object} promise - */ - this.$get = ['$log', '$injector', '$rootScope', '$q', function ($log, $injector, $rootScope, $q) { + Red.prototype.mul = function mul (a, b) { + this._verify2(a, b); + return this.imod(a.mul(b)); + }; - var Storage, - defaultInterpolator = $injector.get($interpolationFactory || '$translateDefaultInterpolation'), - pendingLoader = false, - interpolatorHashMap = {}, - langPromises = {}, - fallbackIndex, - startFallbackIteration; + Red.prototype.isqr = function isqr (a) { + return this.imul(a, a.clone()); + }; - var $translate = function (translationId, interpolateParams, interpolationId, defaultTranslationText, forceLanguage, sanitizeStrategy) { - if (!$uses && $preferredLanguage) { - $uses = $preferredLanguage; - } - var uses = (forceLanguage && forceLanguage !== $uses) ? // we don't want to re-negotiate $uses - (negotiateLocale(forceLanguage) || forceLanguage) : $uses; + Red.prototype.sqr = function sqr (a) { + return this.mul(a, a); + }; - // Check forceLanguage is present - if (forceLanguage) { - loadTranslationsIfMissing(forceLanguage); - } + Red.prototype.sqrt = function sqrt (a) { + if (a.isZero()) return a.clone(); - // Duck detection: If the first argument is an array, a bunch of translations was requested. - // The result is an object. - if (angular.isArray(translationId)) { - // Inspired by Q.allSettled by Kris Kowal - // https://github.com/kriskowal/q/blob/b0fa72980717dc202ffc3cbf03b936e10ebbb9d7/q.js#L1553-1563 - // This transforms all promises regardless resolved or rejected - var translateAll = function (translationIds) { - var results = {}; // storing the actual results - var promises = []; // promises to wait for - // Wraps the promise a) being always resolved and b) storing the link id->value - var translate = function (translationId) { - var deferred = $q.defer(); - var regardless = function (value) { - results[translationId] = value; - deferred.resolve([translationId, value]); - }; - // we don't care whether the promise was resolved or rejected; just store the values - $translate(translationId, interpolateParams, interpolationId, defaultTranslationText, forceLanguage, sanitizeStrategy).then(regardless, regardless); - return deferred.promise; - }; - for (var i = 0, c = translationIds.length; i < c; i++) { - promises.push(translate(translationIds[i])); - } - // wait for all (including storing to results) - return $q.all(promises).then(function () { - // return the results - return results; - }); - }; - return translateAll(translationId); - } + var mod3 = this.m.andln(3); + assert(mod3 % 2 === 1); - var deferred = $q.defer(); + // Fast case + if (mod3 === 3) { + var pow = this.m.add(new BN(1)).iushrn(2); + return this.pow(a, pow); + } - // trim off any whitespace - if (translationId) { - translationId = trim.apply(translationId); - } + // Tonelli-Shanks algorithm (Totally unoptimized and slow) + // + // Find Q and S, that Q * 2 ^ S = (P - 1) + var q = this.m.subn(1); + var s = 0; + while (!q.isZero() && q.andln(1) === 0) { + s++; + q.iushrn(1); + } + assert(!q.isZero()); - var promiseToWaitFor = (function () { - var promise = langPromises[uses] || langPromises[$preferredLanguage]; + var one = new BN(1).toRed(this); + var nOne = one.redNeg(); - fallbackIndex = 0; + // Find quadratic non-residue + // NOTE: Max is such because of generalized Riemann hypothesis. + var lpow = this.m.subn(1).iushrn(1); + var z = this.m.bitLength(); + z = new BN(2 * z * z).toRed(this); - if ($storageFactory && !promise) { - // looks like there's no pending promise for $preferredLanguage or - // $uses. Maybe there's one pending for a language that comes from - // storage. - var langKey = Storage.get($storageKey); - promise = langPromises[langKey]; + while (this.pow(z, lpow).cmp(nOne) !== 0) { + z.redIAdd(nOne); + } - if ($fallbackLanguage && $fallbackLanguage.length) { - var index = indexOf($fallbackLanguage, langKey); - // maybe the language from storage is also defined as fallback language - // we increase the fallback language index to not search in that language - // as fallback, since it's probably the first used language - // in that case the index starts after the first element - fallbackIndex = (index === 0) ? 1 : 0; + var c = this.pow(z, q); + var r = this.pow(a, q.addn(1).iushrn(1)); + var t = this.pow(a, q); + var m = s; + while (t.cmp(one) !== 0) { + var tmp = t; + for (var i = 0; tmp.cmp(one) !== 0; i++) { + tmp = tmp.redSqr(); + } + assert(i < m); + var b = this.pow(c, new BN(1).iushln(m - i - 1)); - // but we can make sure to ALWAYS fallback to preferred language at least - if (indexOf($fallbackLanguage, $preferredLanguage) < 0) { - $fallbackLanguage.push($preferredLanguage); - } - } - } - return promise; - }()); - - if (!promiseToWaitFor) { - // no promise to wait for? okay. Then there's no loader registered - // nor is a one pending for language that comes from storage. - // We can just translate. - determineTranslation(translationId, interpolateParams, interpolationId, defaultTranslationText, uses, sanitizeStrategy).then(deferred.resolve, deferred.reject); - } else { - var promiseResolved = function () { - // $uses may have changed while waiting - if (!forceLanguage) { - uses = $uses; - } - determineTranslation(translationId, interpolateParams, interpolationId, defaultTranslationText, uses, sanitizeStrategy).then(deferred.resolve, deferred.reject); - }; - promiseResolved.displayName = 'promiseResolved'; + r = r.redMul(b); + c = b.redSqr(); + t = t.redMul(c); + m = i; + } - promiseToWaitFor['finally'](promiseResolved)['catch'](angular.noop); // we don't care about errors here, already handled - } - return deferred.promise; - }; + return r; + }; - /** - * @name applyNotFoundIndicators - * @private - * - * @description - * Applies not fount indicators to given translation id, if needed. - * This function gets only executed, if a translation id doesn't exist, - * which is why a translation id is expected as argument. - * - * @param {string} translationId Translation id. - * @returns {string} Same as given translation id but applied with not found - * indicators. - */ - var applyNotFoundIndicators = function (translationId) { - // applying notFoundIndicators - if ($notFoundIndicatorLeft) { - translationId = [$notFoundIndicatorLeft, translationId].join(' '); - } - if ($notFoundIndicatorRight) { - translationId = [translationId, $notFoundIndicatorRight].join(' '); - } - return translationId; - }; + Red.prototype.invm = function invm (a) { + var inv = a._invmp(this.m); + if (inv.negative !== 0) { + inv.negative = 0; + return this.imod(inv).redNeg(); + } else { + return this.imod(inv); + } + }; - /** - * @name useLanguage - * @private - * - * @description - * Makes actual use of a language by setting a given language key as used - * language and informs registered interpolators to also use the given - * key as locale. - * - * @param {string} key Locale key. - */ - var useLanguage = function (key) { - $uses = key; + Red.prototype.pow = function pow (a, num) { + if (num.isZero()) return new BN(1).toRed(this); + if (num.cmpn(1) === 0) return a.clone(); - // make sure to store new language key before triggering success event - if ($storageFactory) { - Storage.put($translate.storageKey(), $uses); - } + var windowSize = 4; + var wnd = new Array(1 << windowSize); + wnd[0] = new BN(1).toRed(this); + wnd[1] = a; + for (var i = 2; i < wnd.length; i++) { + wnd[i] = this.mul(wnd[i - 1], a); + } - $rootScope.$emit('$translateChangeSuccess', {language : key}); + var res = wnd[0]; + var current = 0; + var currentLen = 0; + var start = num.bitLength() % 26; + if (start === 0) { + start = 26; + } - // inform default interpolator - defaultInterpolator.setLocale($uses); + for (i = num.length - 1; i >= 0; i--) { + var word = num.words[i]; + for (var j = start - 1; j >= 0; j--) { + var bit = (word >> j) & 1; + if (res !== wnd[0]) { + res = this.sqr(res); + } - var eachInterpolator = function (interpolator, id) { - interpolatorHashMap[id].setLocale($uses); - }; - eachInterpolator.displayName = 'eachInterpolatorLocaleSetter'; + if (bit === 0 && current === 0) { + currentLen = 0; + continue; + } - // inform all others too! - angular.forEach(interpolatorHashMap, eachInterpolator); - $rootScope.$emit('$translateChangeEnd', {language : key}); - }; + current <<= 1; + current |= bit; + currentLen++; + if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue; - /** - * @name loadAsync - * @private - * - * @description - * Kicks off registered async loader using `$injector` and applies existing - * loader options. When resolved, it updates translation tables accordingly - * or rejects with given language key. - * - * @param {string} key Language key. - * @return {Promise} A promise. - */ - var loadAsync = function (key) { - if (!key) { - throw 'No language key specified for loading.'; + res = this.mul(res, wnd[current]); + currentLen = 0; + current = 0; } + start = 26; + } - var deferred = $q.defer(); + return res; + }; - $rootScope.$emit('$translateLoadingStart', {language : key}); - pendingLoader = true; + Red.prototype.convertTo = function convertTo (num) { + var r = num.umod(this.m); - var cache = loaderCache; - if (typeof(cache) === 'string') { - // getting on-demand instance of loader - cache = $injector.get(cache); - } + return r === num ? r.clone() : r; + }; - var loaderOptions = angular.extend({}, $loaderOptions, { - key : key, - $http : angular.extend({}, { - cache : cache - }, $loaderOptions.$http) - }); + Red.prototype.convertFrom = function convertFrom (num) { + var res = num.clone(); + res.red = null; + return res; + }; - var onLoaderSuccess = function (data) { - var translationTable = {}; - $rootScope.$emit('$translateLoadingSuccess', {language : key}); + // + // Montgomery method engine + // - if (angular.isArray(data)) { - angular.forEach(data, function (table) { - angular.extend(translationTable, flatObject(table)); - }); - } else { - angular.extend(translationTable, flatObject(data)); - } - pendingLoader = false; - deferred.resolve({ - key : key, - table : translationTable - }); - $rootScope.$emit('$translateLoadingEnd', {language : key}); - }; - onLoaderSuccess.displayName = 'onLoaderSuccess'; + BN.mont = function mont (num) { + return new Mont(num); + }; - var onLoaderError = function (key) { - $rootScope.$emit('$translateLoadingError', {language : key}); - deferred.reject(key); - $rootScope.$emit('$translateLoadingEnd', {language : key}); - }; - onLoaderError.displayName = 'onLoaderError'; + function Mont (m) { + Red.call(this, m); - $injector.get($loaderFactory)(loaderOptions) - .then(onLoaderSuccess, onLoaderError); + this.shift = this.m.bitLength(); + if (this.shift % 26 !== 0) { + this.shift += 26 - (this.shift % 26); + } - return deferred.promise; - }; + this.r = new BN(1).iushln(this.shift); + this.r2 = this.imod(this.r.sqr()); + this.rinv = this.r._invmp(this.m); - if ($storageFactory) { - Storage = $injector.get($storageFactory); + this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); + this.minv = this.minv.umod(this.r); + this.minv = this.r.sub(this.minv); + } + inherits(Mont, Red); - if (!Storage.get || !Storage.put) { - throw new Error('Couldn\'t use storage \'' + $storageFactory + '\', missing get() or put() method!'); - } - } + Mont.prototype.convertTo = function convertTo (num) { + return this.imod(num.ushln(this.shift)); + }; - // if we have additional interpolations that were added via - // $translateProvider.addInterpolation(), we have to map'em - if ($interpolatorFactories.length) { - var eachInterpolationFactory = function (interpolatorFactory) { - var interpolator = $injector.get(interpolatorFactory); - // setting initial locale for each interpolation service - interpolator.setLocale($preferredLanguage || $uses); - // make'em recognizable through id - interpolatorHashMap[interpolator.getInterpolationIdentifier()] = interpolator; - }; - eachInterpolationFactory.displayName = 'interpolationFactoryAdder'; + Mont.prototype.convertFrom = function convertFrom (num) { + var r = this.imod(num.mul(this.rinv)); + r.red = null; + return r; + }; - angular.forEach($interpolatorFactories, eachInterpolationFactory); + Mont.prototype.imul = function imul (a, b) { + if (a.isZero() || b.isZero()) { + a.words[0] = 0; + a.length = 1; + return a; } - /** - * @name getTranslationTable - * @private - * - * @description - * Returns a promise that resolves to the translation table - * or is rejected if an error occurred. - * - * @param langKey - * @returns {Q.promise} - */ - var getTranslationTable = function (langKey) { - var deferred = $q.defer(); - if (Object.prototype.hasOwnProperty.call($translationTable, langKey)) { - deferred.resolve($translationTable[langKey]); - } else if (langPromises[langKey]) { - var onResolve = function (data) { - translations(data.key, data.table); - deferred.resolve(data.table); - }; - onResolve.displayName = 'translationTableResolver'; - langPromises[langKey].then(onResolve, deferred.reject); - } else { - deferred.reject(); - } - return deferred.promise; - }; + var t = a.imul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).iushrn(this.shift); + var res = u; - /** - * @name getFallbackTranslation - * @private - * - * @description - * Returns a promise that will resolve to the translation - * or be rejected if no translation was found for the language. - * This function is currently only used for fallback language translation. - * - * @param langKey The language to translate to. - * @param translationId - * @param interpolateParams - * @param Interpolator - * @param sanitizeStrategy - * @returns {Q.promise} - */ - var getFallbackTranslation = function (langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy) { - var deferred = $q.defer(); + if (u.cmp(this.m) >= 0) { + res = u.isub(this.m); + } else if (u.cmpn(0) < 0) { + res = u.iadd(this.m); + } - var onResolve = function (translationTable) { - if (Object.prototype.hasOwnProperty.call(translationTable, translationId) && translationTable[translationId] !== null) { - Interpolator.setLocale(langKey); - var translation = translationTable[translationId]; - if (translation.substr(0, 2) === '@:') { - getFallbackTranslation(langKey, translation.substr(2), interpolateParams, Interpolator, sanitizeStrategy) - .then(deferred.resolve, deferred.reject); - } else { - var interpolatedValue = Interpolator.interpolate(translationTable[translationId], interpolateParams, 'service', sanitizeStrategy, translationId); - interpolatedValue = applyPostProcessing(translationId, translationTable[translationId], interpolatedValue, interpolateParams, langKey); + return res._forceRed(this); + }; - deferred.resolve(interpolatedValue); + Mont.prototype.mul = function mul (a, b) { + if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this); - } - Interpolator.setLocale($uses); - } else { - deferred.reject(); - } - }; - onResolve.displayName = 'fallbackTranslationResolver'; + var t = a.mul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).iushrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) { + res = u.isub(this.m); + } else if (u.cmpn(0) < 0) { + res = u.iadd(this.m); + } - getTranslationTable(langKey).then(onResolve, deferred.reject); + return res._forceRed(this); + }; - return deferred.promise; - }; + Mont.prototype.invm = function invm (a) { + // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R + var res = this.imod(a._invmp(this.m).mul(this.r2)); + return res._forceRed(this); + }; +})(typeof module === 'undefined' || module, this); - /** - * @name getFallbackTranslationInstant - * @private - * - * @description - * Returns a translation - * This function is currently only used for fallback language translation. - * - * @param langKey The language to translate to. - * @param translationId - * @param interpolateParams - * @param Interpolator - * @param sanitizeStrategy sanitize strategy override - * - * @returns {string} translation - */ - var getFallbackTranslationInstant = function (langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy) { - var result, translationTable = $translationTable[langKey]; +},{"buffer":382}],182:[function(require,module,exports){ +var r; - if (translationTable && Object.prototype.hasOwnProperty.call(translationTable, translationId) && translationTable[translationId] !== null) { - Interpolator.setLocale(langKey); - result = Interpolator.interpolate(translationTable[translationId], interpolateParams, 'filter', sanitizeStrategy, translationId); - result = applyPostProcessing(translationId, translationTable[translationId], result, interpolateParams, langKey, sanitizeStrategy); - // workaround for TrustedValueHolderType - if (!angular.isString(result) && angular.isFunction(result.$$unwrapTrustedValue)) { - var result2 = result.$$unwrapTrustedValue(); - if (result2.substr(0, 2) === '@:') { - return getFallbackTranslationInstant(langKey, result2.substr(2), interpolateParams, Interpolator, sanitizeStrategy); - } - } else if (result.substr(0, 2) === '@:') { - return getFallbackTranslationInstant(langKey, result.substr(2), interpolateParams, Interpolator, sanitizeStrategy); - } - Interpolator.setLocale($uses); - } +module.exports = function rand(len) { + if (!r) + r = new Rand(null); - return result; - }; + return r.generate(len); +}; +function Rand(rand) { + this.rand = rand; +} +module.exports.Rand = Rand; - /** - * @name translateByHandler - * @private - * - * Translate by missing translation handler. - * - * @param translationId - * @param interpolateParams - * @param defaultTranslationText - * @param sanitizeStrategy sanitize strategy override - * - * @returns translation created by $missingTranslationHandler or translationId is $missingTranslationHandler is - * absent - */ - var translateByHandler = function (translationId, interpolateParams, defaultTranslationText, sanitizeStrategy) { - // If we have a handler factory - we might also call it here to determine if it provides - // a default text for a translationid that can't be found anywhere in our tables - if ($missingTranslationHandlerFactory) { - return $injector.get($missingTranslationHandlerFactory)(translationId, $uses, interpolateParams, defaultTranslationText, sanitizeStrategy); - } else { - return translationId; - } - }; +Rand.prototype.generate = function generate(len) { + return this._rand(len); +}; - /** - * @name resolveForFallbackLanguage - * @private - * - * Recursive helper function for fallbackTranslation that will sequentially look - * for a translation in the fallbackLanguages starting with fallbackLanguageIndex. - * - * @param fallbackLanguageIndex - * @param translationId - * @param interpolateParams - * @param Interpolator - * @param defaultTranslationText - * @param sanitizeStrategy - * @returns {Q.promise} Promise that will resolve to the translation. - */ - var resolveForFallbackLanguage = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy) { - var deferred = $q.defer(); +// Emulate crypto API using randy +Rand.prototype._rand = function _rand(n) { + if (this.rand.getBytes) + return this.rand.getBytes(n); - if (fallbackLanguageIndex < $fallbackLanguage.length) { - var langKey = $fallbackLanguage[fallbackLanguageIndex]; - getFallbackTranslation(langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy).then( - function (data) { - deferred.resolve(data); - }, - function () { - // Look in the next fallback language for a translation. - // It delays the resolving by passing another promise to resolve. - return resolveForFallbackLanguage(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy).then(deferred.resolve, deferred.reject); - } - ); - } else { - // No translation found in any fallback language - // if a default translation text is set in the directive, then return this as a result - if (defaultTranslationText) { - deferred.resolve(defaultTranslationText); - } else { - var missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, defaultTranslationText); + var res = new Uint8Array(n); + for (var i = 0; i < res.length; i++) + res[i] = this.rand.getByte(); + return res; +}; - // if no default translation is set and an error handler is defined, send it to the handler - // and then return the result if it isn't undefined - if ($missingTranslationHandlerFactory && missingTranslationHandlerTranslation) { - deferred.resolve(missingTranslationHandlerTranslation); - } else { - deferred.reject(applyNotFoundIndicators(translationId)); - } - } - } - return deferred.promise; +if (typeof self === 'object') { + if (self.crypto && self.crypto.getRandomValues) { + // Modern browsers + Rand.prototype._rand = function _rand(n) { + var arr = new Uint8Array(n); + self.crypto.getRandomValues(arr); + return arr; }; - - /** - * @name resolveForFallbackLanguageInstant - * @private - * - * Recursive helper function for fallbackTranslation that will sequentially look - * for a translation in the fallbackLanguages starting with fallbackLanguageIndex. - * - * @param fallbackLanguageIndex - * @param translationId - * @param interpolateParams - * @param Interpolator - * @param sanitizeStrategy - * @returns {string} translation - */ - var resolveForFallbackLanguageInstant = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator, sanitizeStrategy) { - var result; - - if (fallbackLanguageIndex < $fallbackLanguage.length) { - var langKey = $fallbackLanguage[fallbackLanguageIndex]; - result = getFallbackTranslationInstant(langKey, translationId, interpolateParams, Interpolator, sanitizeStrategy); - if (!result && result !== '') { - result = resolveForFallbackLanguageInstant(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator); - } - } - return result; + } else if (self.msCrypto && self.msCrypto.getRandomValues) { + // IE + Rand.prototype._rand = function _rand(n) { + var arr = new Uint8Array(n); + self.msCrypto.getRandomValues(arr); + return arr; }; - /** - * Translates with the usage of the fallback languages. - * - * @param translationId - * @param interpolateParams - * @param Interpolator - * @param defaultTranslationText - * @param sanitizeStrategy - * @returns {Q.promise} Promise, that resolves to the translation. - */ - var fallbackTranslation = function (translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy) { - // Start with the fallbackLanguage with index 0 - return resolveForFallbackLanguage((startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex), translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy); + // Safari's WebWorkers do not have `crypto` + } else if (typeof window === 'object') { + // Old junk + Rand.prototype._rand = function() { + throw new Error('Not implemented yet'); }; + } +} else { + // Node.js or Web worker with no crypto support + try { + var crypto = require('crypto'); + if (typeof crypto.randomBytes !== 'function') + throw new Error('Not supported'); - /** - * Translates with the usage of the fallback languages. - * - * @param translationId - * @param interpolateParams - * @param Interpolator - * @param sanitizeStrategy - * @returns {String} translation - */ - var fallbackTranslationInstant = function (translationId, interpolateParams, Interpolator, sanitizeStrategy) { - // Start with the fallbackLanguage with index 0 - return resolveForFallbackLanguageInstant((startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex), translationId, interpolateParams, Interpolator, sanitizeStrategy); + Rand.prototype._rand = function _rand(n) { + return crypto.randomBytes(n); }; + } catch (e) { + } +} - var determineTranslation = function (translationId, interpolateParams, interpolationId, defaultTranslationText, uses, sanitizeStrategy) { +},{"crypto":382}],183:[function(require,module,exports){ +(function (process){ +'use strict'; - var deferred = $q.defer(); +Object.defineProperty(exports, "__esModule", { + value: true +}); +/* global window */ - var table = uses ? $translationTable[uses] : $translationTable, - Interpolator = (interpolationId) ? interpolatorHashMap[interpolationId] : defaultInterpolator; +var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; - // if the translation id exists, we can just interpolate it - if (table && Object.prototype.hasOwnProperty.call(table, translationId) && table[translationId] !== null) { - var translation = table[translationId]; +var isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null; - // If using link, rerun $translate with linked translationId and return it - if (translation.substr(0, 2) === '@:') { +exports.isBrowser = isBrowser; +exports.isNode = isNode; +}).call(this,require('_process')) +},{"_process":924}],184:[function(require,module,exports){ +var Buffer = require('safe-buffer').Buffer +var Transform = require('stream').Transform +var StringDecoder = require('string_decoder').StringDecoder +var inherits = require('inherits') - $translate(translation.substr(2), interpolateParams, interpolationId, defaultTranslationText, uses, sanitizeStrategy) - .then(deferred.resolve, deferred.reject); - } else { - // - var resolvedTranslation = Interpolator.interpolate(translation, interpolateParams, 'service', sanitizeStrategy, translationId); - resolvedTranslation = applyPostProcessing(translationId, translation, resolvedTranslation, interpolateParams, uses); - deferred.resolve(resolvedTranslation); - } - } else { - var missingTranslationHandlerTranslation; - // for logging purposes only (as in $translateMissingTranslationHandlerLog), value is not returned to promise - if ($missingTranslationHandlerFactory && !pendingLoader) { - missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, defaultTranslationText); - } +function CipherBase (hashMode) { + Transform.call(this) + this.hashMode = typeof hashMode === 'string' + if (this.hashMode) { + this[hashMode] = this._finalOrDigest + } else { + this.final = this._finalOrDigest + } + if (this._final) { + this.__final = this._final + this._final = null + } + this._decoder = null + this._encoding = null +} +inherits(CipherBase, Transform) - // since we couldn't translate the inital requested translation id, - // we try it now with one or more fallback languages, if fallback language(s) is - // configured. - if (uses && $fallbackLanguage && $fallbackLanguage.length) { - fallbackTranslation(translationId, interpolateParams, Interpolator, defaultTranslationText, sanitizeStrategy) - .then(function (translation) { - deferred.resolve(translation); - }, function (_translationId) { - deferred.reject(applyNotFoundIndicators(_translationId)); - }); - } else if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { - // looks like the requested translation id doesn't exists. - // Now, if there is a registered handler for missing translations and no - // asyncLoader is pending, we execute the handler - if (defaultTranslationText) { - deferred.resolve(defaultTranslationText); - } else { - deferred.resolve(missingTranslationHandlerTranslation); - } - } else { - if (defaultTranslationText) { - deferred.resolve(defaultTranslationText); - } else { - deferred.reject(applyNotFoundIndicators(translationId)); - } - } - } - return deferred.promise; - }; +CipherBase.prototype.update = function (data, inputEnc, outputEnc) { + if (typeof data === 'string') { + data = Buffer.from(data, inputEnc) + } - var determineTranslationInstant = function (translationId, interpolateParams, interpolationId, uses, sanitizeStrategy) { + var outData = this._update(data) + if (this.hashMode) return this - var result, table = uses ? $translationTable[uses] : $translationTable, - Interpolator = defaultInterpolator; + if (outputEnc) { + outData = this._toString(outData, outputEnc) + } - // if the interpolation id exists use custom interpolator - if (interpolatorHashMap && Object.prototype.hasOwnProperty.call(interpolatorHashMap, interpolationId)) { - Interpolator = interpolatorHashMap[interpolationId]; - } + return outData +} - // if the translation id exists, we can just interpolate it - if (table && Object.prototype.hasOwnProperty.call(table, translationId) && table[translationId] !== null) { - var translation = table[translationId]; +CipherBase.prototype.setAutoPadding = function () {} +CipherBase.prototype.getAuthTag = function () { + throw new Error('trying to get auth tag in unsupported state') +} - // If using link, rerun $translate with linked translationId and return it - if (translation.substr(0, 2) === '@:') { - result = determineTranslationInstant(translation.substr(2), interpolateParams, interpolationId, uses, sanitizeStrategy); - } else { - result = Interpolator.interpolate(translation, interpolateParams, 'filter', sanitizeStrategy, translationId); - result = applyPostProcessing(translationId, translation, result, interpolateParams, uses, sanitizeStrategy); - } - } else { - var missingTranslationHandlerTranslation; - // for logging purposes only (as in $translateMissingTranslationHandlerLog), value is not returned to promise - if ($missingTranslationHandlerFactory && !pendingLoader) { - missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, sanitizeStrategy); - } +CipherBase.prototype.setAuthTag = function () { + throw new Error('trying to set auth tag in unsupported state') +} - // since we couldn't translate the inital requested translation id, - // we try it now with one or more fallback languages, if fallback language(s) is - // configured. - if (uses && $fallbackLanguage && $fallbackLanguage.length) { - fallbackIndex = 0; - result = fallbackTranslationInstant(translationId, interpolateParams, Interpolator, sanitizeStrategy); - } else if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { - // looks like the requested translation id doesn't exists. - // Now, if there is a registered handler for missing translations and no - // asyncLoader is pending, we execute the handler - result = missingTranslationHandlerTranslation; - } else { - result = applyNotFoundIndicators(translationId); - } - } +CipherBase.prototype.setAAD = function () { + throw new Error('trying to set aad in unsupported state') +} - return result; - }; +CipherBase.prototype._transform = function (data, _, next) { + var err + try { + if (this.hashMode) { + this._update(data) + } else { + this.push(this._update(data)) + } + } catch (e) { + err = e + } finally { + next(err) + } +} +CipherBase.prototype._flush = function (done) { + var err + try { + this.push(this.__final()) + } catch (e) { + err = e + } - var clearNextLangAndPromise = function (key) { - if ($nextLang === key) { - $nextLang = undefined; - } - langPromises[key] = undefined; - }; + done(err) +} +CipherBase.prototype._finalOrDigest = function (outputEnc) { + var outData = this.__final() || Buffer.alloc(0) + if (outputEnc) { + outData = this._toString(outData, outputEnc, true) + } + return outData +} - var applyPostProcessing = function (translationId, translation, resolvedTranslation, interpolateParams, uses, sanitizeStrategy) { - var fn = postProcessFn; +CipherBase.prototype._toString = function (value, enc, fin) { + if (!this._decoder) { + this._decoder = new StringDecoder(enc) + this._encoding = enc + } - if (fn) { + if (this._encoding !== enc) throw new Error('can\'t switch encodings') - if (typeof(fn) === 'string') { - // getting on-demand instance - fn = $injector.get(fn); - } - if (fn) { - return fn(translationId, translation, resolvedTranslation, interpolateParams, uses, sanitizeStrategy); - } - } + var out = this._decoder.write(value) + if (fin) { + out += this._decoder.end() + } - return resolvedTranslation; - }; + return out +} - var loadTranslationsIfMissing = function (key) { - if (!$translationTable[key] && $loaderFactory && !langPromises[key]) { - langPromises[key] = loadAsync(key).then(function (translation) { - translations(translation.key, translation.table); - return translation; - }); - } - }; +module.exports = CipherBase - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#preferredLanguage - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the language key for the preferred language. - * - * @param {string} langKey language String or Array to be used as preferredLanguage (changing at runtime) - * - * @return {string} preferred language key - */ - $translate.preferredLanguage = function (langKey) { - if (langKey) { - setupPreferredLanguage(langKey); - } - return $preferredLanguage; - }; +},{"inherits":246,"safe-buffer":276,"stream":967,"string_decoder":411}],185:[function(require,module,exports){ +/** + * Slice reference. + */ - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#cloakClassName - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the configured class name for `translate-cloak` directive. - * - * @return {string} cloakClassName - */ - $translate.cloakClassName = function () { - return $cloakClassName; - }; +var slice = [].slice; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#nestedObjectDelimeter - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the configured delimiter for nested namespaces. - * - * @return {string} nestedObjectDelimeter - */ - $translate.nestedObjectDelimeter = function () { - return $nestedObjectDelimeter; - }; +/** + * Bind `obj` to `fn`. + * + * @param {Object} obj + * @param {Function|String} fn or string + * @return {Function} + * @api public + */ - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#fallbackLanguage - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the language key for the fallback languages or sets a new fallback stack. - * It is recommended to call this before {@link pascalprecht.translate.$translateProvider#preferredLanguage preferredLanguage()}. - * - * @param {string=} langKey language String or Array of fallback languages to be used (to change stack at runtime) - * - * @return {string||array} fallback language key - */ - $translate.fallbackLanguage = function (langKey) { - if (langKey !== undefined && langKey !== null) { - fallbackStack(langKey); +module.exports = function(obj, fn){ + if ('string' == typeof fn) fn = obj[fn]; + if ('function' != typeof fn) throw new Error('bind() requires a function'); + var args = slice.call(arguments, 2); + return function(){ + return fn.apply(obj, args.concat(slice.call(arguments))); + } +}; - // as we might have an async loader initiated and a new translation language might have been defined - // we need to add the promise to the stack also. So - iterate. - if ($loaderFactory) { - if ($fallbackLanguage && $fallbackLanguage.length) { - for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { - if (!langPromises[$fallbackLanguage[i]]) { - langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]); - } - } - } - } - $translate.use($translate.use()); - } - if ($fallbackWasString) { - return $fallbackLanguage[0]; - } else { - return $fallbackLanguage; - } +},{}],186:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +if (typeof module !== 'undefined') { + module.exports = Emitter; +} + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks['$' + event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],187:[function(require,module,exports){ - }; +module.exports = function(a, b){ + var fn = function(){}; + fn.prototype = b.prototype; + a.prototype = new fn; + a.prototype.constructor = a; +}; +},{}],188:[function(require,module,exports){ +(function (Buffer){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#useFallbackLanguage - * @methodOf pascalprecht.translate.$translate - * - * @description - * Sets the first key of the fallback language stack to be used for translation. - * Therefore all languages in the fallback array BEFORE this key will be skipped! - * - * @param {string=} langKey Contains the langKey the iteration shall start with. Set to false if you want to - * get back to the whole stack - */ - $translate.useFallbackLanguage = function (langKey) { - if (langKey !== undefined && langKey !== null) { - if (!langKey) { - startFallbackIteration = 0; - } else { - var langKeyPosition = indexOf($fallbackLanguage, langKey); - if (langKeyPosition > -1) { - startFallbackIteration = langKeyPosition; - } - } +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. - } +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; - }; +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#proposedLanguage - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the language key of language that is currently loaded asynchronously. - * - * @return {string} language key - */ - $translate.proposedLanguage = function () { - return $nextLang; - }; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#storage - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns registered storage. - * - * @return {object} Storage - */ - $translate.storage = function () { - return Storage; - }; +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#negotiateLocale - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns a language key based on available languages and language aliases. If a - * language key cannot be resolved, returns undefined. - * - * If no or a falsy key is given, returns undefined. - * - * @param {string} [key] Language key - * @return {string|undefined} Language key or undefined if no language key is found. - */ - $translate.negotiateLocale = negotiateLocale; +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#use - * @methodOf pascalprecht.translate.$translate - * - * @description - * Tells angular-translate which language to use by given language key. This method is - * used to change language at runtime. It also takes care of storing the language - * key in a configured store to let your app remember the choosed language. - * - * When trying to 'use' a language which isn't available it tries to load it - * asynchronously with registered loaders. - * - * Returns promise object with loaded language file data or string of the currently used language. - * - * If no or a falsy key is given it returns the currently used language key. - * The returned string will be ```undefined``` if setting up $translate hasn't finished. - * @example - * $translate.use("en_US").then(function(data){ - * $scope.text = $translate("HELLO"); - * }); - * - * @param {string=} key Language key - * @return {object|string} Promise with loaded language data or the language key if a falsy param was given. - */ - $translate.use = function (key) { - if (!key) { - return $uses; - } +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - var deferred = $q.defer(); - deferred.promise.then(null, angular.noop); // AJS "Possibly unhandled rejection" +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - $rootScope.$emit('$translateChangeStart', {language : key}); +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - // Try to get the aliased language key - var aliasedKey = negotiateLocale(key); - // Ensure only registered language keys will be loaded - if ($availableLanguageKeys.length > 0 && !aliasedKey) { - return $q.reject(key); - } - - if (aliasedKey) { - key = aliasedKey; - } +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - // if there isn't a translation table for the language we've requested, - // we load it asynchronously - $nextLang = key; - if (($forceAsyncReloadEnabled || !$translationTable[key]) && $loaderFactory && !langPromises[key]) { - langPromises[key] = loadAsync(key).then(function (translation) { - translations(translation.key, translation.table); - deferred.resolve(translation.key); - if ($nextLang === key) { - useLanguage(translation.key); - } - return translation; - }, function (key) { - $rootScope.$emit('$translateChangeError', {language : key}); - deferred.reject(key); - $rootScope.$emit('$translateChangeEnd', {language : key}); - return $q.reject(key); - }); - langPromises[key]['finally'](function () { - clearNextLangAndPromise(key); - })['catch'](angular.noop); // we don't care about errors (clearing) - } else if (langPromises[key]) { - // we are already loading this asynchronously - // resolve our new deferred when the old langPromise is resolved - langPromises[key].then(function (translation) { - if ($nextLang === translation.key) { - useLanguage(translation.key); - } - deferred.resolve(translation.key); - return translation; - }, function (key) { - // find first available fallback language if that request has failed - if (!$uses && $fallbackLanguage && $fallbackLanguage.length > 0 && $fallbackLanguage[0] !== key) { - return $translate.use($fallbackLanguage[0]).then(deferred.resolve, deferred.reject); - } else { - return deferred.reject(key); - } - }); - } else { - deferred.resolve(key); - useLanguage(key); - } +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; - return deferred.promise; - }; +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#resolveClientLocale - * @methodOf pascalprecht.translate.$translate - * - * @description - * This returns the current browser/client's language key. The result is processed with the configured uniform tag resolver. - * - * @returns {string} the current client/browser language key - */ - $translate.resolveClientLocale = function () { - return getLocale(); - }; +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#storageKey - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the key for the storage. - * - * @return {string} storage key - */ - $translate.storageKey = function () { - return storageKey(); - }; +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#isPostCompilingEnabled - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns whether post compiling is enabled or not - * - * @return {bool} storage key - */ - $translate.isPostCompilingEnabled = function () { - return $postCompilingEnabled; - }; +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#isForceAsyncReloadEnabled - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns whether force async reload is enabled or not - * - * @return {boolean} forceAsyncReload value - */ - $translate.isForceAsyncReloadEnabled = function () { - return $forceAsyncReloadEnabled; - }; +exports.isBuffer = Buffer.isBuffer; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#isKeepContent - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns whether keepContent or not - * - * @return {boolean} keepContent value - */ - $translate.isKeepContent = function () { - return $keepContent; - }; +function objectToString(o) { + return Object.prototype.toString.call(o); +} - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#refresh - * @methodOf pascalprecht.translate.$translate - * - * @description - * Refreshes a translation table pointed by the given langKey. If langKey is not specified, - * the module will drop all existent translation tables and load new version of those which - * are currently in use. - * - * Refresh means that the module will drop target translation table and try to load it again. - * - * In case there are no loaders registered the refresh() method will throw an Error. - * - * If the module is able to refresh translation tables refresh() method will broadcast - * $translateRefreshStart and $translateRefreshEnd events. - * - * @example - * // this will drop all currently existent translation tables and reload those which are - * // currently in use - * $translate.refresh(); - * // this will refresh a translation table for the en_US language - * $translate.refresh('en_US'); - * - * @param {string} langKey A language key of the table, which has to be refreshed - * - * @return {promise} Promise, which will be resolved in case a translation tables refreshing - * process is finished successfully, and reject if not. - */ - $translate.refresh = function (langKey) { - if (!$loaderFactory) { - throw new Error('Couldn\'t refresh translation table, no loader registered!'); - } +}).call(this,{"isBuffer":require("../../../../../is-buffer/index.js")}) +},{"../../../../../is-buffer/index.js":896}],189:[function(require,module,exports){ +'use strict' +var inherits = require('inherits') +var MD5 = require('md5.js') +var RIPEMD160 = require('ripemd160') +var sha = require('sha.js') +var Base = require('cipher-base') - $rootScope.$emit('$translateRefreshStart', {language : langKey}); +function Hash (hash) { + Base.call(this, 'digest') - var deferred = $q.defer(), updatedLanguages = {}; + this._hash = hash +} - //private helper - function loadNewData(languageKey) { - var promise = loadAsync(languageKey); - //update the load promise cache for this language - langPromises[languageKey] = promise; - //register a data handler for the promise - promise.then(function (data) { - //clear the cache for this language - $translationTable[languageKey] = {}; - //add the new data for this language - translations(languageKey, data.table); - //track that we updated this language - updatedLanguages[languageKey] = true; - }, - //handle rejection to appease the $q validation - angular.noop); - return promise; - } +inherits(Hash, Base) - //set up post-processing - deferred.promise.then( - function () { - for (var key in $translationTable) { - if ($translationTable.hasOwnProperty(key)) { - //delete cache entries that were not updated - if (!(key in updatedLanguages)) { - delete $translationTable[key]; - } - } - } - if ($uses) { - useLanguage($uses); - } - }, - //handle rejection to appease the $q validation - angular.noop - )['finally']( - function () { - $rootScope.$emit('$translateRefreshEnd', {language : langKey}); - } - ); +Hash.prototype._update = function (data) { + this._hash.update(data) +} - if (!langKey) { - // if there's no language key specified we refresh ALL THE THINGS! - var languagesToReload = $fallbackLanguage && $fallbackLanguage.slice() || []; - if ($uses && languagesToReload.indexOf($uses) === -1) { - languagesToReload.push($uses); - } - $q.all(languagesToReload.map(loadNewData)).then(deferred.resolve, deferred.reject); +Hash.prototype._final = function () { + return this._hash.digest() +} - } else if ($translationTable[langKey]) { - //just refresh the specified language cache - loadNewData(langKey).then(deferred.resolve, deferred.reject); +module.exports = function createHash (alg) { + alg = alg.toLowerCase() + if (alg === 'md5') return new MD5() + if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160() - } else { - deferred.reject(); - } + return new Hash(sha(alg)) +} - return deferred.promise; - }; +},{"cipher-base":184,"inherits":246,"md5.js":256,"ripemd160":273,"sha.js":285}],190:[function(require,module,exports){ +/** + * Helpers. + */ - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#instant - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns a translation instantly from the internal state of loaded translation. All rules - * regarding the current language, the preferred language of even fallback languages will be - * used except any promise handling. If a language was not found, an asynchronous loading - * will be invoked in the background. - * - * @param {string|array} translationId A token which represents a translation id - * This can be optionally an array of translation ids which - * results that the function's promise returns an object where - * each key is the translation id and the value the translation. - * @param {object=} [interpolateParams={}] Params - * @param {string=} [interpolationId=undefined] The id of the interpolation to use (use default unless set via useInterpolation()) - * @param {string=} [forceLanguage=false] A language to be used instead of the current language - * @param {string=} [sanitizeStrategy=undefined] force sanitize strategy for this call instead of using the configured one (use default unless set) - * - * @return {string|object} translation - */ - $translate.instant = function (translationId, interpolateParams, interpolationId, forceLanguage, sanitizeStrategy) { +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var w = d * 7; +var y = d * 365.25; - // we don't want to re-negotiate $uses - var uses = (forceLanguage && forceLanguage !== $uses) ? // we don't want to re-negotiate $uses - (negotiateLocale(forceLanguage) || forceLanguage) : $uses; +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ - // Detect undefined and null values to shorten the execution and prevent exceptions - if (translationId === null || angular.isUndefined(translationId)) { - return translationId; - } +module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; - // Check forceLanguage is present - if (forceLanguage) { - loadTranslationsIfMissing(forceLanguage); - } +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ - // Duck detection: If the first argument is an array, a bunch of translations was requested. - // The result is an object. - if (angular.isArray(translationId)) { - var results = {}; - for (var i = 0, c = translationId.length; i < c; i++) { - results[translationId[i]] = $translate.instant(translationId[i], interpolateParams, interpolationId, forceLanguage, sanitizeStrategy); - } - return results; - } +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'weeks': + case 'week': + case 'w': + return n * w; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} - // We discarded unacceptable values. So we just need to verify if translationId is empty String - if (angular.isString(translationId) && translationId.length < 1) { - return translationId; - } +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - // trim off any whitespace - if (translationId) { - translationId = trim.apply(translationId); - } +function fmtShort(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return Math.round(ms / d) + 'd'; + } + if (msAbs >= h) { + return Math.round(ms / h) + 'h'; + } + if (msAbs >= m) { + return Math.round(ms / m) + 'm'; + } + if (msAbs >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} - var result, possibleLangKeys = []; - if ($preferredLanguage) { - possibleLangKeys.push($preferredLanguage); - } - if (uses) { - possibleLangKeys.push(uses); - } - if ($fallbackLanguage && $fallbackLanguage.length) { - possibleLangKeys = possibleLangKeys.concat($fallbackLanguage); - } - for (var j = 0, d = possibleLangKeys.length; j < d; j++) { - var possibleLangKey = possibleLangKeys[j]; - if ($translationTable[possibleLangKey]) { - if (typeof $translationTable[possibleLangKey][translationId] !== 'undefined') { - result = determineTranslationInstant(translationId, interpolateParams, interpolationId, uses, sanitizeStrategy); - } - } - if (typeof result !== 'undefined') { - break; - } - } +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - if (!result && result !== '') { - if ($notFoundIndicatorLeft || $notFoundIndicatorRight) { - result = applyNotFoundIndicators(translationId); - } else { - // Return translation of default interpolator if not found anything. - result = defaultInterpolator.interpolate(translationId, interpolateParams, 'filter', sanitizeStrategy); +function fmtLong(ms) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; +} - // looks like the requested translation id doesn't exists. - // Now, if there is a registered handler for missing translations and no - // asyncLoader is pending, we execute the handler - var missingTranslationHandlerTranslation; - if ($missingTranslationHandlerFactory && !pendingLoader) { - missingTranslationHandlerTranslation = translateByHandler(translationId, interpolateParams, sanitizeStrategy); - } +/** + * Pluralization helper. + */ - if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { - result = missingTranslationHandlerTranslation; - } - } - } +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); +} - return result; - }; +},{}],191:[function(require,module,exports){ +(function (process){ +/* eslint-env browser */ - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#versionInfo - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the current version information for the angular-translate library - * - * @return {string} angular-translate version - */ - $translate.versionInfo = function () { - return version; - }; +/** + * This is the web browser implementation of `debug()`. + */ - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#loaderCache - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns the defined loaderCache. - * - * @return {boolean|string|object} current value of loaderCache - */ - $translate.loaderCache = function () { - return loaderCache; - }; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); - // internal purpose only - $translate.directivePriority = function () { - return directivePriority; - }; +/** + * Colors. + */ - // internal purpose only - $translate.statefulFilter = function () { - return statefulFilter; - }; +exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' +]; - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#isReady - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns whether the service is "ready" to translate (i.e. loading 1st language). - * - * See also {@link pascalprecht.translate.$translate#methods_onReady onReady()}. - * - * @return {boolean} current value of ready - */ - $translate.isReady = function () { - return $isReady; - }; +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ - var $onReadyDeferred = $q.defer(); - $onReadyDeferred.promise.then(function () { - $isReady = true; - }); +// eslint-disable-next-line complexity +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#onReady - * @methodOf pascalprecht.translate.$translate - * - * @description - * Calls the function provided or resolved the returned promise after the service is "ready" to translate (i.e. loading 1st language). - * - * See also {@link pascalprecht.translate.$translate#methods_isReady isReady()}. - * - * @param {Function=} fn Function to invoke when service is ready - * @return {object} Promise resolved when service is ready - */ - $translate.onReady = function (fn) { - var deferred = $q.defer(); - if (angular.isFunction(fn)) { - deferred.promise.then(fn); - } - if ($isReady) { - deferred.resolve(); - } else { - $onReadyDeferred.promise.then(deferred.resolve); - } - return deferred.promise; - }; + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#getAvailableLanguageKeys - * @methodOf pascalprecht.translate.$translate - * - * @description - * This function simply returns the registered language keys being defined before in the config phase - * With this, an application can use the array to provide a language selection dropdown or similar - * without any additional effort - * - * @returns {object} returns the list of possibly registered language keys and mapping or null if not defined - */ - $translate.getAvailableLanguageKeys = function () { - if ($availableLanguageKeys.length > 0) { - return $availableLanguageKeys; - } - return null; - }; + // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // Is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // Double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} - /** - * @ngdoc function - * @name pascalprecht.translate.$translate#getTranslationTable - * @methodOf pascalprecht.translate.$translate - * - * @description - * Returns translation table by the given language key. - * - * Unless a language is provided it returns a translation table of the current one. - * Note: If translation dictionary is currently downloading or in progress - * it will return null. - * - * @param {string} langKey A token which represents a translation id - * - * @return {object} a copy of angular-translate $translationTable - */ - $translate.getTranslationTable = function (langKey) { - langKey = langKey || $translate.use(); - if (langKey && $translationTable[langKey]) { - return angular.copy($translationTable[langKey]); - } - return null; - }; +/** + * Colorize log arguments if enabled. + * + * @api public + */ - // Whenever $translateReady is being fired, this will ensure the state of $isReady - var globalOnReadyListener = $rootScope.$on('$translateReady', function () { - $onReadyDeferred.resolve(); - globalOnReadyListener(); // one time only - globalOnReadyListener = null; - }); - var globalOnChangeListener = $rootScope.$on('$translateChangeEnd', function () { - $onReadyDeferred.resolve(); - globalOnChangeListener(); // one time only - globalOnChangeListener = null; - }); +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + + this.namespace + + (this.useColors ? ' %c' : ' ') + + args[0] + + (this.useColors ? '%c ' : ' ') + + '+' + module.exports.humanize(this.diff); - if ($loaderFactory) { + if (!this.useColors) { + return; + } - // If at least one async loader is defined and there are no - // (default) translations available we should try to load them. - if (angular.equals($translationTable, {})) { - if ($translate.use()) { - $translate.use($translate.use()); - } - } + const c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); - // Also, if there are any fallback language registered, we start - // loading them asynchronously as soon as we can. - if ($fallbackLanguage && $fallbackLanguage.length) { - var processAsyncResult = function (translation) { - translations(translation.key, translation.table); - $rootScope.$emit('$translateChangeEnd', {language : translation.key}); - return translation; - }; - for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { - var fallbackLanguageId = $fallbackLanguage[i]; - if ($forceAsyncReloadEnabled || !$translationTable[fallbackLanguageId]) { - langPromises[fallbackLanguageId] = loadAsync(fallbackLanguageId).then(processAsyncResult); - } - } - } - } else { - $rootScope.$emit('$translateReady', {language : $translate.use()}); - } + // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, match => { + if (match === '%%') { + return; + } + index++; + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); - return $translate; - }]; + args.splice(lastC, 0, c); } -$translate.displayName = 'displayName'; +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ +function log(...args) { + // This hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return typeof console === 'object' && + console.log && + console.log(...args); +} /** - * @ngdoc object - * @name pascalprecht.translate.$translateDefaultInterpolation - * @requires $interpolate + * Save `namespaces`. * - * @description - * Uses angular's `$interpolate` services to interpolate strings against some values. + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +/** + * Load `namespaces`. * - * Be aware to configure a proper sanitization strategy. + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + let r; + try { + r = exports.storage.getItem('debug'); + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Localstorage attempts to return the localstorage. * - * See also: - * * {@link pascalprecht.translate.$translateSanitization} + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. * - * @return {object} $translateDefaultInterpolation Interpolator service + * @return {LocalStorage} + * @api private */ -angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation', $translateDefaultInterpolation); -function $translateDefaultInterpolation ($interpolate, $translateSanitization) { +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} - 'use strict'; +module.exports = require('./common')(exports); - var $translateInterpolator = {}, - $locale, - $identifier = 'default'; +const {formatters} = module.exports; - /** - * @ngdoc function - * @name pascalprecht.translate.$translateDefaultInterpolation#setLocale - * @methodOf pascalprecht.translate.$translateDefaultInterpolation - * - * @description - * Sets current locale (this is currently not use in this interpolation). - * - * @param {string} locale Language key or locale. - */ - $translateInterpolator.setLocale = function (locale) { - $locale = locale; - }; +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ - /** - * @ngdoc function - * @name pascalprecht.translate.$translateDefaultInterpolation#getInterpolationIdentifier - * @methodOf pascalprecht.translate.$translateDefaultInterpolation - * - * @description - * Returns an identifier for this interpolation service. - * - * @returns {string} $identifier - */ - $translateInterpolator.getInterpolationIdentifier = function () { - return $identifier; - }; +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; - /** - * @deprecated will be removed in 3.0 - * @see {@link pascalprecht.translate.$translateSanitization} - */ - $translateInterpolator.useSanitizeValueStrategy = function (value) { - $translateSanitization.useStrategy(value); - return this; - }; +}).call(this,require('_process')) +},{"./common":192,"_process":924}],192:[function(require,module,exports){ - /** - * @ngdoc function - * @name pascalprecht.translate.$translateDefaultInterpolation#interpolate - * @methodOf pascalprecht.translate.$translateDefaultInterpolation - * - * @description - * Interpolates given value agains given interpolate params using angulars - * `$interpolate` service. - * - * Since AngularJS 1.5, `value` must not be a string but can be anything input. - * - * @param {string} value translation - * @param {object} [interpolationParams={}] interpolation params - * @param {string} [context=undefined] current context (filter, directive, service) - * @param {string} [sanitizeStrategy=undefined] sanitize strategy (use default unless set) - * @param {string} translationId current translationId - * - * @returns {string} interpolated string - */ - $translateInterpolator.interpolate = function (value, interpolationParams, context, sanitizeStrategy, translationId) { // jshint ignore:line - interpolationParams = interpolationParams || {}; - interpolationParams = $translateSanitization.sanitize(interpolationParams, 'params', sanitizeStrategy, context); +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ - var interpolatedText; - if (angular.isNumber(value)) { - // numbers are safe - interpolatedText = '' + value; - } else if (angular.isString(value)) { - // strings must be interpolated (that's the job here) - interpolatedText = $interpolate(value)(interpolationParams); - interpolatedText = $translateSanitization.sanitize(interpolatedText, 'text', sanitizeStrategy, context); - } else { - // neither a number or a string, cant interpolate => empty string - interpolatedText = ''; - } +function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require('ms'); - return interpolatedText; - }; + Object.keys(env).forEach(key => { + createDebug[key] = env[key]; + }); - return $translateInterpolator; -} + /** + * Active `debug` instances. + */ + createDebug.instances = []; -$translateDefaultInterpolation.displayName = '$translateDefaultInterpolation'; + /** + * The currently active debug mode names, and names to skip. + */ -angular.module('pascalprecht.translate').constant('$STORAGE_KEY', 'NG_TRANSLATE_LANG_KEY'); + createDebug.names = []; + createDebug.skips = []; -angular.module('pascalprecht.translate') -/** - * @ngdoc directive - * @name pascalprecht.translate.directive:translate - * @requires $interpolate, - * @requires $compile, - * @requires $parse, - * @requires $rootScope - * @restrict AE - * - * @description - * Translates given translation id either through attribute or DOM content. - * Internally it uses $translate service to translate the translation id. It possible to - * pass an optional `translate-values` object literal as string into translation id. - * - * @param {string=} translate Translation id which could be either string or interpolated string. - * @param {string=} translate-values Values to pass into translation id. Can be passed as object literal string or interpolated object. - * @param {string=} translate-attr-ATTR translate Translation id and put it into ATTR attribute. - * @param {string=} translate-default will be used unless translation was successful - * @param {string=} translate-sanitize-strategy defines locally sanitize strategy - * @param {boolean=} translate-compile (default true if present) defines locally activation of {@link pascalprecht.translate.$translateProvider#methods_usePostCompiling} - * @param {boolean=} translate-keep-content (default true if present) defines that in case a KEY could not be translated, that the existing content is left in the innerHTML} - * - * @example - - -
- -

-        
TRANSLATION_ID
-

-        

-        
{{translationId}}
-

-        
WITH_VALUES
-

-        
WITH_VALUES
-

-        

-
-      
-
- - angular.module('ngView', ['pascalprecht.translate']) - - .config(function ($translateProvider) { - - $translateProvider.translations('en',{ - 'TRANSLATION_ID': 'Hello there!', - 'WITH_VALUES': 'The following value is dynamic: {{value}}', - 'WITH_CAMEL_CASE_KEY': 'The interpolation key is camel cased: {{camelCaseKey}}' - }).preferredLanguage('en'); + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + createDebug.formatters = {}; - }); + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + function selectColor(namespace) { + let hash = 0; - angular.module('ngView').controller('TranslateCtrl', function ($scope) { - $scope.translationId = 'TRANSLATION_ID'; + for (let i = 0; i < namespace.length; i++) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } - $scope.values = { - value: 78 - }; - }); - - - it('should translate', function () { - inject(function ($rootScope, $compile) { - $rootScope.translationId = 'TRANSLATION_ID'; + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; - element = $compile('

')($rootScope); - $rootScope.$digest(); - expect(element.text()).toBe('Hello there!'); + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + function createDebug(namespace) { + let prevTime; - element = $compile('

')($rootScope); - $rootScope.$digest(); - expect(element.text()).toBe('Hello there!'); + function debug(...args) { + // Disabled? + if (!debug.enabled) { + return; + } - element = $compile('

TRANSLATION_ID

')($rootScope); - $rootScope.$digest(); - expect(element.text()).toBe('Hello there!'); + const self = debug; - element = $compile('

{{translationId}}

')($rootScope); - $rootScope.$digest(); - expect(element.text()).toBe('Hello there!'); + // Set `diff` timestamp + const curr = Number(new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; - element = $compile('

')($rootScope); - $rootScope.$digest(); - expect(element.attr('title')).toBe('Hello there!'); + args[0] = createDebug.coerce(args[0]); - element = $compile('

')($rootScope); - $rootScope.$digest(); - expect(element.text()).toBe('The interpolation key is camel cased: Hello'); - }); - }); -
-
- */ -.directive('translate', translateDirective); -function translateDirective($translate, $interpolate, $compile, $parse, $rootScope) { + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } - 'use strict'; + // Apply any `formatters` transformations + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return match; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === 'function') { + const val = args[index]; + match = formatter.call(self, val); - /** - * @name trim - * @private - * - * @description - * trim polyfill - * - * @returns {string} The string stripped of whitespace from both ends - */ - var trim = function() { - return this.toString().replace(/^\s+|\s+$/g, ''); - }; + // Now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); - /** - * @name lowercase - * @private - * - * @description - * Return the lowercase string only if the type is string - * - * @returns {string} The string all in lowercase - */ - var lowercase = function (string) { - return angular.isString(string) ? string.toLowerCase() : string; - }; + // Apply env-specific formatting (colors, etc.) + createDebug.formatArgs.call(self, args); - return { - restrict: 'AE', - scope: true, - priority: $translate.directivePriority(), - compile: function (tElement, tAttr) { + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } - var translateValuesExist = (tAttr.translateValues) ? - tAttr.translateValues : undefined; + debug.namespace = namespace; + debug.enabled = createDebug.enabled(namespace); + debug.useColors = createDebug.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; + debug.extend = extend; + // Debug.formatArgs = formatArgs; + // debug.rawLog = rawLog; - var translateInterpolation = (tAttr.translateInterpolation) ? - tAttr.translateInterpolation : undefined; + // env-specific initialization logic for debug instances + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } - var translateSanitizeStrategyExist = (tAttr.translateSanitizeStrategy) ? - tAttr.translateSanitizeStrategy : undefined; + createDebug.instances.push(debug); - var translateValueExist = tElement[0].outerHTML.match(/translate-value-+/i); + return debug; + } - var interpolateRegExp = '^(.*)(' + $interpolate.startSymbol() + '.*' + $interpolate.endSymbol() + ')(.*)', - watcherRegExp = '^(.*)' + $interpolate.startSymbol() + '(.*)' + $interpolate.endSymbol() + '(.*)'; + function destroy() { + const index = createDebug.instances.indexOf(this); + if (index !== -1) { + createDebug.instances.splice(index, 1); + return true; + } + return false; + } - return function linkFn(scope, iElement, iAttr) { + function extend(namespace, delimiter) { + return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + } - scope.interpolateParams = {}; - scope.preText = ''; - scope.postText = ''; - scope.translateNamespace = getTranslateNamespace(scope); - var translationIds = {}; + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + function enable(namespaces) { + createDebug.save(namespaces); - var initInterpolationParams = function (interpolateParams, iAttr, tAttr) { - // initial setup - if (iAttr.translateValues) { - angular.extend(interpolateParams, $parse(iAttr.translateValues)(scope.$parent)); - } - // initially fetch all attributes if existing and fill the params - if (translateValueExist) { - for (var attr in tAttr) { - if (Object.prototype.hasOwnProperty.call(iAttr, attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') { - var attributeName = lowercase(attr.substr(14, 1)) + attr.substr(15); - interpolateParams[attributeName] = tAttr[attr]; - } - } - } - }; + createDebug.names = []; + createDebug.skips = []; - // Ensures any change of the attribute "translate" containing the id will - // be re-stored to the scope's "translationId". - // If the attribute has no content, the element's text value (white spaces trimmed off) will be used. - var observeElementTranslation = function (translationId) { + let i; + const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + const len = split.length; - // Remove any old watcher - if (angular.isFunction(observeElementTranslation._unwatchOld)) { - observeElementTranslation._unwatchOld(); - observeElementTranslation._unwatchOld = undefined; - } + for (i = 0; i < len; i++) { + if (!split[i]) { + // ignore empty strings + continue; + } - if (angular.equals(translationId , '') || !angular.isDefined(translationId)) { - var iElementText = trim.apply(iElement.text()); + namespaces = split[i].replace(/\*/g, '.*?'); - // Resolve translation id by inner html if required - var interpolateMatches = iElementText.match(interpolateRegExp); - // Interpolate translation id if required - if (angular.isArray(interpolateMatches)) { - scope.preText = interpolateMatches[1]; - scope.postText = interpolateMatches[3]; - translationIds.translate = $interpolate(interpolateMatches[2])(scope.$parent); - var watcherMatches = iElementText.match(watcherRegExp); - if (angular.isArray(watcherMatches) && watcherMatches[2] && watcherMatches[2].length) { - observeElementTranslation._unwatchOld = scope.$watch(watcherMatches[2], function (newValue) { - translationIds.translate = newValue; - updateTranslations(); - }); - } - } else { - // do not assigne the translation id if it is empty. - translationIds.translate = !iElementText ? undefined : iElementText; - } - } else { - translationIds.translate = translationId; - } - updateTranslations(); - }; + if (namespaces[0] === '-') { + createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + createDebug.names.push(new RegExp('^' + namespaces + '$')); + } + } - var observeAttributeTranslation = function (translateAttr) { - iAttr.$observe(translateAttr, function (translationId) { - translationIds[translateAttr] = translationId; - updateTranslations(); - }); - }; + for (i = 0; i < createDebug.instances.length; i++) { + const instance = createDebug.instances[i]; + instance.enabled = createDebug.enabled(instance.namespace); + } + } - // initial setup with values - initInterpolationParams(scope.interpolateParams, iAttr, tAttr); + /** + * Disable debug output. + * + * @api public + */ + function disable() { + createDebug.enable(''); + } - var firstAttributeChangedEvent = true; - iAttr.$observe('translate', function (translationId) { - if (typeof translationId === 'undefined') { - // case of element "xyz" - observeElementTranslation(''); - } else { - // case of regular attribute - if (translationId !== '' || !firstAttributeChangedEvent) { - translationIds.translate = translationId; - updateTranslations(); - } - } - firstAttributeChangedEvent = false; - }); + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } - for (var translateAttr in iAttr) { - if (iAttr.hasOwnProperty(translateAttr) && translateAttr.substr(0, 13) === 'translateAttr' && translateAttr.length > 13) { - observeAttributeTranslation(translateAttr); - } - } + let i; + let len; - iAttr.$observe('translateDefault', function (value) { - scope.defaultText = value; - updateTranslations(); - }); + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } - if (translateSanitizeStrategyExist) { - iAttr.$observe('translateSanitizeStrategy', function (value) { - scope.sanitizeStrategy = $parse(value)(scope.$parent); - updateTranslations(); - }); - } + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } - if (translateValuesExist) { - iAttr.$observe('translateValues', function (interpolateParams) { - if (interpolateParams) { - scope.$parent.$watch(function () { - angular.extend(scope.interpolateParams, $parse(interpolateParams)(scope.$parent)); - }); - } - }); - } + return false; + } - if (translateValueExist) { - var observeValueAttribute = function (attrName) { - iAttr.$observe(attrName, function (value) { - var attributeName = lowercase(attrName.substr(14, 1)) + attrName.substr(15); - scope.interpolateParams[attributeName] = value; - }); - }; - for (var attr in iAttr) { - if (Object.prototype.hasOwnProperty.call(iAttr, attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') { - observeValueAttribute(attr); - } - } - } + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } - // Master update function - var updateTranslations = function () { - for (var key in translationIds) { - if (translationIds.hasOwnProperty(key) && translationIds[key] !== undefined) { - updateTranslation(key, translationIds[key], scope, scope.interpolateParams, scope.defaultText, scope.translateNamespace); - } - } - }; + createDebug.enable(createDebug.load()); - // Put translation processing function outside loop - var updateTranslation = function(translateAttr, translationId, scope, interpolateParams, defaultTranslationText, translateNamespace) { - if (translationId) { - // if translation id starts with '.' and translateNamespace given, prepend namespace - if (translateNamespace && translationId.charAt(0) === '.') { - translationId = translateNamespace + translationId; - } + return createDebug; +} - $translate(translationId, interpolateParams, translateInterpolation, defaultTranslationText, scope.translateLanguage, scope.sanitizeStrategy) - .then(function (translation) { - applyTranslation(translation, scope, true, translateAttr); - }, function (translationId) { - applyTranslation(translationId, scope, false, translateAttr); - }); - } else { - // as an empty string cannot be translated, we can solve this using successful=false - applyTranslation(translationId, scope, false, translateAttr); - } - }; +module.exports = setup; - var applyTranslation = function (value, scope, successful, translateAttr) { - if (!successful) { - if (typeof scope.defaultText !== 'undefined') { - value = scope.defaultText; - } - } - if (translateAttr === 'translate') { - // default translate into innerHTML - if (successful || (!successful && !$translate.isKeepContent() && typeof iAttr.translateKeepContent === 'undefined')) { - iElement.empty().append(scope.preText + value + scope.postText); - } - var globallyEnabled = $translate.isPostCompilingEnabled(); - var locallyDefined = typeof tAttr.translateCompile !== 'undefined'; - var locallyEnabled = locallyDefined && tAttr.translateCompile !== 'false'; - if ((globallyEnabled && !locallyDefined) || locallyEnabled) { - $compile(iElement.contents())(scope); - } - } else { - // translate attribute - var attributeName = iAttr.$attr[translateAttr]; - if (attributeName.substr(0, 5) === 'data-') { - // ensure html5 data prefix is stripped - attributeName = attributeName.substr(5); - } - attributeName = attributeName.substr(15); - iElement.attr(attributeName, value); - } - }; +},{"ms":190}],193:[function(require,module,exports){ +(function (process){ +function detect() { + if (typeof navigator !== 'undefined') { + return parseUserAgent(navigator.userAgent); + } - if (translateValuesExist || translateValueExist || iAttr.translateDefault) { - scope.$watch('interpolateParams', updateTranslations, true); - } + return getNodeVersion(); +} - // Replaced watcher on translateLanguage with event listener - scope.$on('translateLanguageChanged', updateTranslations); +function detectOS(userAgentString) { + var rules = getOperatingSystemRules(); + var detected = rules.filter(function (os) { + return os.rule && os.rule.test(userAgentString); + })[0]; - // Ensures the text will be refreshed after the current language was changed - // w/ $translate.use(...) - var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslations); + return detected ? detected.name : null; +} - // ensure translation will be looked up at least one - if (iElement.text().length) { - if (iAttr.translate) { - observeElementTranslation(iAttr.translate); - } else { - observeElementTranslation(''); - } - } else if (iAttr.translate) { - // ensure attribute will be not skipped - observeElementTranslation(iAttr.translate); - } - updateTranslations(); - scope.$on('$destroy', unbind); - }; - } +function getNodeVersion() { + var isNode = typeof process !== 'undefined' && process.version; + return isNode && { + name: 'node', + version: process.version.slice(1), + os: process.platform }; } -/** - * Returns the scope's namespace. - * @private - * @param scope - * @returns {string} - */ -function getTranslateNamespace(scope) { - 'use strict'; - if (scope.translateNamespace) { - return scope.translateNamespace; - } - if (scope.$parent) { - return getTranslateNamespace(scope.$parent); +function parseUserAgent(userAgentString) { + var browsers = getBrowserRules(); + if (!userAgentString) { + return null; } -} - -translateDirective.displayName = 'translateDirective'; - -angular.module('pascalprecht.translate') -/** - * @ngdoc directive - * @name pascalprecht.translate.directive:translate-attr - * @restrict A - * - * @description - * Translates attributes like translate-attr-ATTR, but with an object like ng-class. - * Internally it uses `translate` service to translate translation id. It possible to - * pass an optional `translate-values` object literal as string into translation id. - * - * @param {string=} translate-attr Object literal mapping attributes to translation ids. - * @param {string=} translate-values Values to pass into the translation ids. Can be passed as object literal string. - * @param {string=} translate-sanitize-strategy defines locally sanitize strategy - * - * @example - - -
- - - -
-
- - angular.module('ngView', ['pascalprecht.translate']) - .config(function ($translateProvider) { + var detected = browsers.map(function(browser) { + var match = browser.rule.exec(userAgentString); + var version = match && match[1].split(/[._]/).slice(0,3); - $translateProvider.translations('en',{ - 'TRANSLATION_ID': 'Hello there!', - 'WITH_VALUES': 'The following value is dynamic: {{value}}', - }).preferredLanguage('en'); + if (version && version.length < 3) { + version = version.concat(version.length == 1 ? [0, 0] : [0]); + } - }); + return match && { + name: browser.name, + version: version.join('.') + }; + }).filter(Boolean)[0] || null; - angular.module('ngView').controller('TranslateCtrl', function ($scope) { - $scope.translationId = 'TRANSLATION_ID'; + if (detected) { + detected.os = detectOS(userAgentString); + } - $scope.values = { - value: 78 - }; - }); - - - it('should translate', function () { - inject(function ($rootScope, $compile) { - $rootScope.translationId = 'TRANSLATION_ID'; + if (/alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/i.test(userAgentString)) { + detected = detected || {}; + detected.bot = true; + } - element = $compile('')($rootScope); - $rootScope.$digest(); - expect(element.attr('placeholder)).toBe('Hello there!'); - expect(element.attr('title)).toBe('The following value is dynamic: 5'); - }); - }); - -
- */ -.directive('translateAttr', translateAttrDirective); -function translateAttrDirective($translate, $rootScope) { + return detected; +} - 'use strict'; +function getBrowserRules() { + return buildRules([ + [ 'aol', /AOLShield\/([0-9\._]+)/ ], + [ 'edge', /Edge\/([0-9\._]+)/ ], + [ 'yandexbrowser', /YaBrowser\/([0-9\._]+)/ ], + [ 'vivaldi', /Vivaldi\/([0-9\.]+)/ ], + [ 'kakaotalk', /KAKAOTALK\s([0-9\.]+)/ ], + [ 'samsung', /SamsungBrowser\/([0-9\.]+)/ ], + [ 'chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/ ], + [ 'phantomjs', /PhantomJS\/([0-9\.]+)(:?\s|$)/ ], + [ 'crios', /CriOS\/([0-9\.]+)(:?\s|$)/ ], + [ 'firefox', /Firefox\/([0-9\.]+)(?:\s|$)/ ], + [ 'fxios', /FxiOS\/([0-9\.]+)/ ], + [ 'opera', /Opera\/([0-9\.]+)(?:\s|$)/ ], + [ 'opera', /OPR\/([0-9\.]+)(:?\s|$)$/ ], + [ 'ie', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/ ], + [ 'ie', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/ ], + [ 'ie', /MSIE\s(7\.0)/ ], + [ 'bb10', /BB10;\sTouch.*Version\/([0-9\.]+)/ ], + [ 'android', /Android\s([0-9\.]+)/ ], + [ 'ios', /Version\/([0-9\._]+).*Mobile.*Safari.*/ ], + [ 'safari', /Version\/([0-9\._]+).*Safari/ ], + [ 'facebook', /FBAV\/([0-9\.]+)/], + [ 'instagram', /Instagram\s([0-9\.]+)/], + [ 'ios-webview', /AppleWebKit\/([0-9\.]+).*Mobile/] + ]); +} - return { - restrict: 'A', - priority: $translate.directivePriority(), - link: function linkFn(scope, element, attr) { +function getOperatingSystemRules() { + return buildRules([ + [ 'iOS', /iP(hone|od|ad)/ ], + [ 'Android OS', /Android/ ], + [ 'BlackBerry OS', /BlackBerry|BB10/ ], + [ 'Windows Mobile', /IEMobile/ ], + [ 'Amazon OS', /Kindle/ ], + [ 'Windows 3.11', /Win16/ ], + [ 'Windows 95', /(Windows 95)|(Win95)|(Windows_95)/ ], + [ 'Windows 98', /(Windows 98)|(Win98)/ ], + [ 'Windows 2000', /(Windows NT 5.0)|(Windows 2000)/ ], + [ 'Windows XP', /(Windows NT 5.1)|(Windows XP)/ ], + [ 'Windows Server 2003', /(Windows NT 5.2)/ ], + [ 'Windows Vista', /(Windows NT 6.0)/ ], + [ 'Windows 7', /(Windows NT 6.1)/ ], + [ 'Windows 8', /(Windows NT 6.2)/ ], + [ 'Windows 8.1', /(Windows NT 6.3)/ ], + [ 'Windows 10', /(Windows NT 10.0)/ ], + [ 'Windows ME', /Windows ME/ ], + [ 'Open BSD', /OpenBSD/ ], + [ 'Sun OS', /SunOS/ ], + [ 'Linux', /(Linux)|(X11)/ ], + [ 'Mac OS', /(Mac_PowerPC)|(Macintosh)/ ], + [ 'QNX', /QNX/ ], + [ 'BeOS', /BeOS/ ], + [ 'OS/2', /OS\/2/ ], + [ 'Search Bot', /(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves\/Teoma)|(ia_archiver)/ ] + ]); +} - var translateAttr, - translateValues, - translateSanitizeStrategy, - previousAttributes = {}; +function buildRules(ruleTuples) { + return ruleTuples.map(function(tuple) { + return { + name: tuple[0], + rule: tuple[1] + }; + }); +} - // Main update translations function - var updateTranslations = function () { - angular.forEach(translateAttr, function (translationId, attributeName) { - if (!translationId) { - return; - } - previousAttributes[attributeName] = true; +module.exports = { + detect: detect, + detectOS: detectOS, + getNodeVersion: getNodeVersion, + parseUserAgent: parseUserAgent +}; - // if translation id starts with '.' and translateNamespace given, prepend namespace - if (scope.translateNamespace && translationId.charAt(0) === '.') { - translationId = scope.translateNamespace + translationId; - } - $translate(translationId, translateValues, attr.translateInterpolation, undefined, scope.translateLanguage, translateSanitizeStrategy) - .then(function (translation) { - element.attr(attributeName, translation); - }, function (translationId) { - element.attr(attributeName, translationId); - }); - }); +}).call(this,require('_process')) +},{"_process":924}],194:[function(require,module,exports){ +(function (global,Buffer){ +/** + * Browser eccrypto implementation. + */ - // Removing unused attributes that were previously used - angular.forEach(previousAttributes, function (flag, attributeName) { - if (!translateAttr[attributeName]) { - element.removeAttr(attributeName); - delete previousAttributes[attributeName]; - } - }); - }; +"use strict"; - // Watch for attribute changes - watchAttribute( - scope, - attr.translateAttr, - function (newValue) { translateAttr = newValue; }, - updateTranslations - ); - // Watch for value changes - watchAttribute( - scope, - attr.translateValues, - function (newValue) { translateValues = newValue; }, - updateTranslations - ); - // Watch for sanitize strategy changes - watchAttribute( - scope, - attr.translateSanitizeStrategy, - function (newValue) { translateSanitizeStrategy = newValue; }, - updateTranslations - ); +var EC = require("elliptic").ec; - if (attr.translateValues) { - scope.$watch(attr.translateValues, updateTranslations, true); - } +var ec = new EC("secp256k1"); +var cryptoObj = global.crypto || global.msCrypto || {}; +var subtle = cryptoObj.subtle || cryptoObj.webkitSubtle; - // Replaced watcher on translateLanguage with event listener - scope.$on('translateLanguageChanged', updateTranslations); +function assert(condition, message) { + if (!condition) { + throw new Error(message || "Assertion failed"); + } +} - // Ensures the text will be refreshed after the current language was changed - // w/ $translate.use(...) - var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslations); +function randomBytes(size) { + var arr = new Uint8Array(size); + global.crypto.getRandomValues(arr); + return new Buffer(arr); +} - updateTranslations(); - scope.$on('$destroy', unbind); - } - }; +function sha512(msg) { + return subtle.digest({name: "SHA-512"}, msg).then(function(hash) { + return new Buffer(new Uint8Array(hash)); + }); } -function watchAttribute(scope, attribute, valueCallback, changeCallback) { - 'use strict'; - if (!attribute) { - return; - } - if (attribute.substr(0, 2) === '::') { - attribute = attribute.substr(2); - } else { - scope.$watch(attribute, function(newValue) { - valueCallback(newValue); - changeCallback(); - }, true); - } - valueCallback(scope.$eval(attribute)); +function getAes(op) { + return function(iv, key, data) { + var importAlgorithm = {name: "AES-CBC"}; + var keyp = subtle.importKey("raw", key, importAlgorithm, false, [op]); + return keyp.then(function(cryptoKey) { + var encAlgorithm = {name: "AES-CBC", iv: iv}; + return subtle[op](encAlgorithm, cryptoKey, data); + }).then(function(result) { + return new Buffer(new Uint8Array(result)); + }); + }; } -translateAttrDirective.displayName = 'translateAttrDirective'; +var aesCbcEncrypt = getAes("encrypt"); +var aesCbcDecrypt = getAes("decrypt"); -angular.module('pascalprecht.translate') -/** - * @ngdoc directive - * @name pascalprecht.translate.directive:translateCloak - * @requires $translate - * @restrict A - * - * $description - * Adds a `translate-cloak` class name to the given element where this directive - * is applied initially and removes it, once a loader has finished loading. - * - * This directive can be used to prevent initial flickering when loading translation - * data asynchronously. - * - * The class name is defined in - * {@link pascalprecht.translate.$translateProvider#cloakClassName $translate.cloakClassName()}. - * - * @param {string=} translate-cloak If a translationId is provided, it will be used for showing - * or hiding the cloak. Basically it relies on the translation - * resolve. - */ -.directive('translateCloak', translateCloakDirective); +function hmacSha256Sign(key, msg) { + var algorithm = {name: "HMAC", hash: {name: "SHA-256"}}; + var keyp = subtle.importKey("raw", key, algorithm, false, ["sign"]); + return keyp.then(function(cryptoKey) { + return subtle.sign(algorithm, cryptoKey, msg); + }).then(function(sig) { + return new Buffer(new Uint8Array(sig)); + }); +} -function translateCloakDirective($translate, $rootScope) { +function hmacSha256Verify(key, msg, sig) { + var algorithm = {name: "HMAC", hash: {name: "SHA-256"}}; + var keyp = subtle.importKey("raw", key, algorithm, false, ["verify"]); + return keyp.then(function(cryptoKey) { + return subtle.verify(algorithm, cryptoKey, sig, msg); + }); +} - 'use strict'; +var getPublic = exports.getPublic = function(privateKey) { + // This function has sync API so we throw an error immediately. + assert(privateKey.length === 32, "Bad private key"); + // XXX(Kagami): `elliptic.utils.encode` returns array for every + // encoding except `hex`. + return new Buffer(ec.keyFromPrivate(privateKey).getPublic("arr")); +}; - return { - compile : function (tElement) { - var applyCloak = function (element) { - element.addClass($translate.cloakClassName()); - }, - removeCloak = function (element) { - element.removeClass($translate.cloakClassName()); - }; - applyCloak(tElement); +// NOTE(Kagami): We don't use promise shim in Browser implementation +// because it's supported natively in new browsers (see +// ) and we can use only new browsers +// because of the WebCryptoAPI (see +// ). +exports.sign = function(privateKey, msg) { + return new Promise(function(resolve) { + assert(privateKey.length === 32, "Bad private key"); + assert(msg.length > 0, "Message should not be empty"); + assert(msg.length <= 32, "Message is too long"); + resolve(new Buffer(ec.sign(msg, privateKey, {canonical: true}).toDER())); + }); +}; - return function linkFn(scope, iElement, iAttr) { - //Create bound functions that incorporate the active DOM element. - var iRemoveCloak = removeCloak.bind(this, iElement), iApplyCloak = applyCloak.bind(this, iElement); - if (iAttr.translateCloak && iAttr.translateCloak.length) { - // Register a watcher for the defined translation allowing a fine tuned cloak - iAttr.$observe('translateCloak', function (translationId) { - $translate(translationId).then(iRemoveCloak, iApplyCloak); - }); - $rootScope.$on('$translateChangeSuccess', function () { - $translate(iAttr.translateCloak).then(iRemoveCloak, iApplyCloak); - }); - } else { - $translate.onReady(iRemoveCloak); - } - }; +exports.verify = function(publicKey, msg, sig) { + return new Promise(function(resolve, reject) { + assert(publicKey.length === 65, "Bad public key"); + assert(publicKey[0] === 4, "Bad public key"); + assert(msg.length > 0, "Message should not be empty"); + assert(msg.length <= 32, "Message is too long"); + if (ec.verify(msg, sig, publicKey)) { + resolve(null); + } else { + reject(new Error("Bad signature")); } - }; -} + }); +}; -translateCloakDirective.displayName = 'translateCloakDirective'; +var derive = exports.derive = function(privateKeyA, publicKeyB) { + return new Promise(function(resolve) { + assert(Buffer.isBuffer(privateKeyA), "Bad input"); + assert(Buffer.isBuffer(publicKeyB), "Bad input"); + assert(privateKeyA.length === 32, "Bad private key"); + assert(publicKeyB.length === 65, "Bad public key"); + assert(publicKeyB[0] === 4, "Bad public key"); + var keyA = ec.keyFromPrivate(privateKeyA); + var keyB = ec.keyFromPublic(publicKeyB); + var Px = keyA.derive(keyB.getPublic()); // BN instance + resolve(new Buffer(Px.toArray())); + }); +}; -angular.module('pascalprecht.translate') -/** - * @ngdoc directive - * @name pascalprecht.translate.directive:translateNamespace - * @restrict A - * - * @description - * Translates given translation id either through attribute or DOM content. - * Internally it uses `translate` filter to translate translation id. It is possible to - * pass an optional `translate-values` object literal as string into translation id. - * - * @param {string=} translate namespace name which could be either string or interpolated string. - * - * @example - - -
+exports.encrypt = function(publicKeyTo, msg, opts) { + assert(subtle, "WebCryptoAPI is not available"); + opts = opts || {}; + // Tmp variables to save context from flat promises; + var iv, ephemPublicKey, ciphertext, macKey; + return new Promise(function(resolve) { + var ephemPrivateKey = opts.ephemPrivateKey || randomBytes(32); + ephemPublicKey = getPublic(ephemPrivateKey); + resolve(derive(ephemPrivateKey, publicKeyTo)); + }).then(function(Px) { + return sha512(Px); + }).then(function(hash) { + iv = opts.iv || randomBytes(16); + var encryptionKey = hash.slice(0, 32); + macKey = hash.slice(32); + return aesCbcEncrypt(iv, encryptionKey, msg); + }).then(function(data) { + ciphertext = data; + var dataToMac = Buffer.concat([iv, ephemPublicKey, ciphertext]); + return hmacSha256Sign(macKey, dataToMac); + }).then(function(mac) { + return { + iv: iv, + ephemPublicKey: ephemPublicKey, + ciphertext: ciphertext, + mac: mac, + }; + }); +}; -
-

.HEADERS.TITLE

-

.HEADERS.WELCOME

-
+exports.decrypt = function(privateKey, opts) { + assert(subtle, "WebCryptoAPI is not available"); + // Tmp variable to save context from flat promises; + var encryptionKey; + return derive(privateKey, opts.ephemPublicKey).then(function(Px) { + return sha512(Px); + }).then(function(hash) { + encryptionKey = hash.slice(0, 32); + var macKey = hash.slice(32); + var dataToMac = Buffer.concat([ + opts.iv, + opts.ephemPublicKey, + opts.ciphertext + ]); + return hmacSha256Verify(macKey, dataToMac, opts.mac); + }).then(function(macGood) { + assert(macGood, "Bad MAC"); + return aesCbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); + }).then(function(msg) { + return new Buffer(new Uint8Array(msg)); + }); +}; -
-

.TITLE

-

.WELCOME

-
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) +},{"buffer":414,"elliptic":195}],195:[function(require,module,exports){ +'use strict'; -
-
- - angular.module('ngView', ['pascalprecht.translate']) +var elliptic = exports; - .config(function ($translateProvider) { +elliptic.version = require('../package.json').version; +elliptic.utils = require('./elliptic/utils'); +elliptic.rand = require('brorand'); +elliptic.curve = require('./elliptic/curve'); +elliptic.curves = require('./elliptic/curves'); - $translateProvider.translations('en',{ - 'TRANSLATION_ID': 'Hello there!', - 'CONTENT': { - 'HEADERS': { - TITLE: 'Title' - } - }, - 'CONTENT.HEADERS.WELCOME': 'Welcome' - }).preferredLanguage('en'); +// Protocols +elliptic.ec = require('./elliptic/ec'); +elliptic.eddsa = require('./elliptic/eddsa'); - }); +},{"../package.json":210,"./elliptic/curve":198,"./elliptic/curves":201,"./elliptic/ec":202,"./elliptic/eddsa":205,"./elliptic/utils":209,"brorand":182}],196:[function(require,module,exports){ +'use strict'; - -
- */ -.directive('translateNamespace', translateNamespaceDirective); +var BN = require('bn.js'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var getNAF = utils.getNAF; +var getJSF = utils.getJSF; +var assert = utils.assert; -function translateNamespaceDirective() { +function BaseCurve(type, conf) { + this.type = type; + this.p = new BN(conf.p, 16); - 'use strict'; + // Use Montgomery, when there is no fast reduction for the prime + this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p); - return { - restrict: 'A', - scope: true, - compile: function () { - return { - pre: function (scope, iElement, iAttrs) { - scope.translateNamespace = _getTranslateNamespace(scope); + // Useful for many curves + this.zero = new BN(0).toRed(this.red); + this.one = new BN(1).toRed(this.red); + this.two = new BN(2).toRed(this.red); - if (scope.translateNamespace && iAttrs.translateNamespace.charAt(0) === '.') { - scope.translateNamespace += iAttrs.translateNamespace; - } else { - scope.translateNamespace = iAttrs.translateNamespace; - } - } - }; - } - }; -} + // Curve configuration, optional + this.n = conf.n && new BN(conf.n, 16); + this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); -/** - * Returns the scope's namespace. - * @private - * @param scope - * @returns {string} - */ -function _getTranslateNamespace(scope) { - 'use strict'; - if (scope.translateNamespace) { - return scope.translateNamespace; - } - if (scope.$parent) { - return _getTranslateNamespace(scope.$parent); + // Temporary arrays + this._wnafT1 = new Array(4); + this._wnafT2 = new Array(4); + this._wnafT3 = new Array(4); + this._wnafT4 = new Array(4); + + // Generalized Greg Maxwell's trick + var adjustCount = this.n && this.p.div(this.n); + if (!adjustCount || adjustCount.cmpn(100) > 0) { + this.redN = null; + } else { + this._maxwellTrick = true; + this.redN = this.n.toRed(this.red); } } +module.exports = BaseCurve; -translateNamespaceDirective.displayName = 'translateNamespaceDirective'; - -angular.module('pascalprecht.translate') -/** - * @ngdoc directive - * @name pascalprecht.translate.directive:translateLanguage - * @restrict A - * - * @description - * Forces the language to the directives in the underlying scope. - * - * @param {string=} translate language that will be negotiated. - * - * @example - - -
- -
-

HELLO

-
- -
-

HELLO

-
+BaseCurve.prototype.point = function point() { + throw new Error('Not implemented'); +}; -
-
- - angular.module('ngView', ['pascalprecht.translate']) +BaseCurve.prototype.validate = function validate() { + throw new Error('Not implemented'); +}; - .config(function ($translateProvider) { +BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { + assert(p.precomputed); + var doubles = p._getDoubles(); - $translateProvider - .translations('en',{ - 'HELLO': 'Hello world!' - }) - .translations('de',{ - 'HELLO': 'Hallo Welt!' - }) - .preferredLanguage('en'); + var naf = getNAF(k, 1); + var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); + I /= 3; - }); + // Translate into more windowed form + var repr = []; + for (var j = 0; j < naf.length; j += doubles.step) { + var nafW = 0; + for (var k = j + doubles.step - 1; k >= j; k--) + nafW = (nafW << 1) + naf[k]; + repr.push(nafW); + } - -
- */ -.directive('translateLanguage', translateLanguageDirective); + var a = this.jpoint(null, null, null); + var b = this.jpoint(null, null, null); + for (var i = I; i > 0; i--) { + for (var j = 0; j < repr.length; j++) { + var nafW = repr[j]; + if (nafW === i) + b = b.mixedAdd(doubles.points[j]); + else if (nafW === -i) + b = b.mixedAdd(doubles.points[j].neg()); + } + a = a.add(b); + } + return a.toP(); +}; -function translateLanguageDirective() { +BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { + var w = 4; - 'use strict'; + // Precompute window + var nafPoints = p._getNAFPoints(w); + w = nafPoints.wnd; + var wnd = nafPoints.points; - return { - restrict: 'A', - scope: true, - compile: function () { - return function linkFn(scope, iElement, iAttrs) { + // Get NAF form + var naf = getNAF(k, w); - iAttrs.$observe('translateLanguage', function (newTranslateLanguage) { - scope.translateLanguage = newTranslateLanguage; - }); + // Add `this`*(N+1) for every w-NAF index + var acc = this.jpoint(null, null, null); + for (var i = naf.length - 1; i >= 0; i--) { + // Count zeroes + for (var k = 0; i >= 0 && naf[i] === 0; i--) + k++; + if (i >= 0) + k++; + acc = acc.dblp(k); - scope.$watch('translateLanguage', function(){ - scope.$broadcast('translateLanguageChanged'); - }); - }; + if (i < 0) + break; + var z = naf[i]; + assert(z !== 0); + if (p.type === 'affine') { + // J +- P + if (z > 0) + acc = acc.mixedAdd(wnd[(z - 1) >> 1]); + else + acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); + } else { + // J +- J + if (z > 0) + acc = acc.add(wnd[(z - 1) >> 1]); + else + acc = acc.add(wnd[(-z - 1) >> 1].neg()); } - }; -} - -translateLanguageDirective.displayName = 'translateLanguageDirective'; - -angular.module('pascalprecht.translate') -/** - * @ngdoc filter - * @name pascalprecht.translate.filter:translate - * @requires $parse - * @requires pascalprecht.translate.$translate - * @function - * - * @description - * Uses `$translate` service to translate contents. Accepts interpolate parameters - * to pass dynamized values though translation. - * - * @param {string} translationId A translation id to be translated. - * @param {*=} interpolateParams Optional object literal (as hash or string) to pass values into translation. - * - * @returns {string} Translated text. - * - * @example - - -
+ } + return p.type === 'affine' ? acc.toP() : acc; +}; -
{{ 'TRANSLATION_ID' | translate }}
-
{{ translationId | translate }}
-
{{ 'WITH_VALUES' | translate:'{value: 5}' }}
-
{{ 'WITH_VALUES' | translate:values }}
+BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, + points, + coeffs, + len, + jacobianResult) { + var wndWidth = this._wnafT1; + var wnd = this._wnafT2; + var naf = this._wnafT3; -
-
- - angular.module('ngView', ['pascalprecht.translate']) + // Fill all arrays + var max = 0; + for (var i = 0; i < len; i++) { + var p = points[i]; + var nafPoints = p._getNAFPoints(defW); + wndWidth[i] = nafPoints.wnd; + wnd[i] = nafPoints.points; + } - .config(function ($translateProvider) { + // Comb small window NAFs + for (var i = len - 1; i >= 1; i -= 2) { + var a = i - 1; + var b = i; + if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { + naf[a] = getNAF(coeffs[a], wndWidth[a]); + naf[b] = getNAF(coeffs[b], wndWidth[b]); + max = Math.max(naf[a].length, max); + max = Math.max(naf[b].length, max); + continue; + } - $translateProvider.translations('en', { - 'TRANSLATION_ID': 'Hello there!', - 'WITH_VALUES': 'The following value is dynamic: {{value}}' - }); - $translateProvider.preferredLanguage('en'); + var comb = [ + points[a], /* 1 */ + null, /* 3 */ + null, /* 5 */ + points[b] /* 7 */ + ]; - }); + // Try to avoid Projective points, if possible + if (points[a].y.cmp(points[b].y) === 0) { + comb[1] = points[a].add(points[b]); + comb[2] = points[a].toJ().mixedAdd(points[b].neg()); + } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { + comb[1] = points[a].toJ().mixedAdd(points[b]); + comb[2] = points[a].add(points[b].neg()); + } else { + comb[1] = points[a].toJ().mixedAdd(points[b]); + comb[2] = points[a].toJ().mixedAdd(points[b].neg()); + } - angular.module('ngView').controller('TranslateCtrl', function ($scope) { - $scope.translationId = 'TRANSLATION_ID'; + var index = [ + -3, /* -1 -1 */ + -1, /* -1 0 */ + -5, /* -1 1 */ + -7, /* 0 -1 */ + 0, /* 0 0 */ + 7, /* 0 1 */ + 5, /* 1 -1 */ + 1, /* 1 0 */ + 3 /* 1 1 */ + ]; - $scope.values = { - value: 78 - }; - }); - -
- */ -.filter('translate', translateFilterFactory); + var jsf = getJSF(coeffs[a], coeffs[b]); + max = Math.max(jsf[0].length, max); + naf[a] = new Array(max); + naf[b] = new Array(max); + for (var j = 0; j < max; j++) { + var ja = jsf[0][j] | 0; + var jb = jsf[1][j] | 0; -function translateFilterFactory($parse, $translate) { + naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; + naf[b][j] = 0; + wnd[a] = comb; + } + } - 'use strict'; + var acc = this.jpoint(null, null, null); + var tmp = this._wnafT4; + for (var i = max; i >= 0; i--) { + var k = 0; - var translateFilter = function (translationId, interpolateParams, interpolation, forceLanguage) { - if (!angular.isObject(interpolateParams)) { - var ctx = this || { - '__SCOPE_IS_NOT_AVAILABLE': 'More info at https://github.com/angular/angular.js/commit/8863b9d04c722b278fa93c5d66ad1e578ad6eb1f' - }; - interpolateParams = $parse(interpolateParams)(ctx); + while (i >= 0) { + var zero = true; + for (var j = 0; j < len; j++) { + tmp[j] = naf[j][i] | 0; + if (tmp[j] !== 0) + zero = false; + } + if (!zero) + break; + k++; + i--; } + if (i >= 0) + k++; + acc = acc.dblp(k); + if (i < 0) + break; - return $translate.instant(translationId, interpolateParams, interpolation, forceLanguage); - }; + for (var j = 0; j < len; j++) { + var z = tmp[j]; + var p; + if (z === 0) + continue; + else if (z > 0) + p = wnd[j][(z - 1) >> 1]; + else if (z < 0) + p = wnd[j][(-z - 1) >> 1].neg(); - if ($translate.statefulFilter()) { - translateFilter.$stateful = true; + if (p.type === 'affine') + acc = acc.mixedAdd(p); + else + acc = acc.add(p); + } } + // Zeroify references + for (var i = 0; i < len; i++) + wnd[i] = null; - return translateFilter; + if (jacobianResult) + return acc; + else + return acc.toP(); +}; + +function BasePoint(curve, type) { + this.curve = curve; + this.type = type; + this.precomputed = null; } +BaseCurve.BasePoint = BasePoint; -translateFilterFactory.displayName = 'translateFilterFactory'; +BasePoint.prototype.eq = function eq(/*other*/) { + throw new Error('Not implemented'); +}; -angular.module('pascalprecht.translate') +BasePoint.prototype.validate = function validate() { + return this.curve.validate(this); +}; -/** - * @ngdoc object - * @name pascalprecht.translate.$translationCache - * @requires $cacheFactory - * - * @description - * The first time a translation table is used, it is loaded in the translation cache for quick retrieval. You - * can load translation tables directly into the cache by consuming the - * `$translationCache` service directly. - * - * @return {object} $cacheFactory object. - */ - .factory('$translationCache', $translationCache); +BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) { + bytes = utils.toArray(bytes, enc); -function $translationCache($cacheFactory) { + var len = this.p.byteLength(); - 'use strict'; + // uncompressed, hybrid-odd, hybrid-even + if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) && + bytes.length - 1 === 2 * len) { + if (bytes[0] === 0x06) + assert(bytes[bytes.length - 1] % 2 === 0); + else if (bytes[0] === 0x07) + assert(bytes[bytes.length - 1] % 2 === 1); - return $cacheFactory('translations'); -} + var res = this.point(bytes.slice(1, 1 + len), + bytes.slice(1 + len, 1 + 2 * len)); -$translationCache.displayName = '$translationCache'; -return 'pascalprecht.translate'; + return res; + } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) && + bytes.length - 1 === len) { + return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03); + } + throw new Error('Unknown point format'); +}; -})); +BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) { + return this.encode(enc, true); +}; -},{}],180:[function(require,module,exports){ -/** - * @license AngularJS v1.7.5 - * (c) 2010-2018 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window) {'use strict'; +BasePoint.prototype._encode = function _encode(compact) { + var len = this.curve.p.byteLength(); + var x = this.getX().toArray('be', len); -/* exported - minErrConfig, - errorHandlingConfig, - isValidObjectMaxDepth -*/ + if (compact) + return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x); -var minErrConfig = { - objectMaxDepth: 5, - urlErrorParamsEnabled: true + return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ; }; -/** - * @ngdoc function - * @name angular.errorHandlingConfig - * @module ng - * @kind function - * - * @description - * Configure several aspects of error handling in AngularJS if used as a setter or return the - * current configuration if used as a getter. The following options are supported: - * - * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages. - * - * Omitted or undefined options will leave the corresponding configuration values unchanged. - * - * @param {Object=} config - The configuration object. May only contain the options that need to be - * updated. Supported keys: - * - * * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a - * non-positive or non-numeric value, removes the max depth limit. - * Default: 5 - * - * * `urlErrorParamsEnabled` **{Boolean}** - Specifies wether the generated error url will - * contain the parameters of the thrown error. Disabling the parameters can be useful if the - * generated error url is very long. - * - * Default: true. When used without argument, it returns the current value. - */ -function errorHandlingConfig(config) { - if (isObject(config)) { - if (isDefined(config.objectMaxDepth)) { - minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN; - } - if (isDefined(config.urlErrorParamsEnabled) && isBoolean(config.urlErrorParamsEnabled)) { - minErrConfig.urlErrorParamsEnabled = config.urlErrorParamsEnabled; - } - } else { - return minErrConfig; - } -} +BasePoint.prototype.encode = function encode(enc, compact) { + return utils.encode(this._encode(compact), enc); +}; -/** - * @private - * @param {Number} maxDepth - * @return {boolean} - */ -function isValidObjectMaxDepth(maxDepth) { - return isNumber(maxDepth) && maxDepth > 0; -} +BasePoint.prototype.precompute = function precompute(power) { + if (this.precomputed) + return this; + var precomputed = { + doubles: null, + naf: null, + beta: null + }; + precomputed.naf = this._getNAFPoints(8); + precomputed.doubles = this._getDoubles(4, power); + precomputed.beta = this._getBeta(); + this.precomputed = precomputed; -/** - * @description - * - * This object provides a utility for producing rich Error messages within - * AngularJS. It can be called as follows: - * - * var exampleMinErr = minErr('example'); - * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); - * - * The above creates an instance of minErr in the example namespace. The - * resulting error will have a namespaced error code of example.one. The - * resulting error will replace {0} with the value of foo, and {1} with the - * value of bar. The object is not restricted in the number of arguments it can - * take. - * - * If fewer arguments are specified than necessary for interpolation, the extra - * interpolation markers will be preserved in the final string. - * - * Since data will be parsed statically during a build step, some restrictions - * are applied with respect to how minErr instances are created and called. - * Instances should have names of the form namespaceMinErr for a minErr created - * using minErr('namespace') . Error codes, namespaces and template strings - * should all be static strings, not variables or general expressions. - * - * @param {string} module The namespace to use for the new minErr instance. - * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning - * error from returned function, for cases when a particular type of error is useful. - * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance - */ + return this; +}; -function minErr(module, ErrorConstructor) { - ErrorConstructor = ErrorConstructor || Error; +BasePoint.prototype._hasDoubles = function _hasDoubles(k) { + if (!this.precomputed) + return false; - var url = 'https://errors.angularjs.org/1.7.5/'; - var regex = url.replace('.', '\\.') + '[\\s\\S]*'; - var errRegExp = new RegExp(regex, 'g'); + var doubles = this.precomputed.doubles; + if (!doubles) + return false; - return function() { - var code = arguments[0], - template = arguments[1], - message = '[' + (module ? module + ':' : '') + code + '] ', - templateArgs = sliceArgs(arguments, 2).map(function(arg) { - return toDebugString(arg, minErrConfig.objectMaxDepth); - }), - paramPrefix, i; + return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step); +}; - // A minErr message has two parts: the message itself and the url that contains the - // encoded message. - // The message's parameters can contain other error messages which also include error urls. - // To prevent the messages from getting too long, we strip the error urls from the parameters. +BasePoint.prototype._getDoubles = function _getDoubles(step, power) { + if (this.precomputed && this.precomputed.doubles) + return this.precomputed.doubles; - message += template.replace(/\{\d+\}/g, function(match) { - var index = +match.slice(1, -1); + var doubles = [ this ]; + var acc = this; + for (var i = 0; i < power; i += step) { + for (var j = 0; j < step; j++) + acc = acc.dbl(); + doubles.push(acc); + } + return { + step: step, + points: doubles + }; +}; - if (index < templateArgs.length) { - return templateArgs[index].replace(errRegExp, ''); - } +BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { + if (this.precomputed && this.precomputed.naf) + return this.precomputed.naf; - return match; - }); + var res = [ this ]; + var max = (1 << wnd) - 1; + var dbl = max === 1 ? null : this.dbl(); + for (var i = 1; i < max; i++) + res[i] = res[i - 1].add(dbl); + return { + wnd: wnd, + points: res + }; +}; - message += '\n' + url + (module ? module + '/' : '') + code; +BasePoint.prototype._getBeta = function _getBeta() { + return null; +}; - if (minErrConfig.urlErrorParamsEnabled) { - for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { - message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]); - } - } +BasePoint.prototype.dblp = function dblp(k) { + var r = this; + for (var i = 0; i < k; i++) + r = r.dbl(); + return r; +}; - return new ErrorConstructor(message); - }; -} +},{"../../elliptic":195,"bn.js":181}],197:[function(require,module,exports){ +'use strict'; -/* We need to tell ESLint what variables are being exported */ -/* exported - angular, - msie, - jqLite, - jQuery, - slice, - splice, - push, - toString, - minErrConfig, - errorHandlingConfig, - isValidObjectMaxDepth, - ngMinErr, - angularModule, - uid, - REGEX_STRING_REGEXP, - VALIDITY_STATE_PROPERTY, +var curve = require('../curve'); +var elliptic = require('../../elliptic'); +var BN = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; - lowercase, - uppercase, - nodeName_, - isArrayLike, - forEach, - forEachSorted, - reverseParams, - nextUid, - setHashKey, - extend, - toInt, - inherit, - merge, - noop, - identity, - valueFn, - isUndefined, - isDefined, - isObject, - isBlankObject, - isString, - isNumber, - isNumberNaN, - isDate, - isError, - isArray, - isFunction, - isRegExp, - isWindow, - isScope, - isFile, - isFormData, - isBlob, - isBoolean, - isPromiseLike, - trim, - escapeForRegexp, - isElement, - makeMap, - includes, - arrayRemove, - copy, - simpleCompare, - equals, - csp, - jq, - concat, - sliceArgs, - bind, - toJsonReplacer, - toJson, - fromJson, - convertTimezoneToLocal, - timezoneToOffset, - addDateMinutes, - startingTag, - tryDecodeURIComponent, - parseKeyValue, - toKeyValue, - encodeUriSegment, - encodeUriQuery, - angularInit, - bootstrap, - getTestability, - snake_case, - bindJQuery, - assertArg, - assertArgFn, - assertNotHasOwnProperty, - getter, - getBlockNodes, - hasOwnProperty, - createMap, - stringify, +var assert = elliptic.utils.assert; - NODE_TYPE_ELEMENT, - NODE_TYPE_ATTRIBUTE, - NODE_TYPE_TEXT, - NODE_TYPE_COMMENT, - NODE_TYPE_DOCUMENT, - NODE_TYPE_DOCUMENT_FRAGMENT -*/ +function EdwardsCurve(conf) { + // NOTE: Important as we are creating point in Base.call() + this.twisted = (conf.a | 0) !== 1; + this.mOneA = this.twisted && (conf.a | 0) === -1; + this.extended = this.mOneA; -//////////////////////////////////// + Base.call(this, 'edwards', conf); -/** - * @ngdoc module - * @name ng - * @module ng - * @installation - * @description - * - * The ng module is loaded by default when an AngularJS application is started. The module itself - * contains the essential components for an AngularJS application to function. The table below - * lists a high level breakdown of each of the services/factories, filters, directives and testing - * components available within this core module. - * - */ + this.a = new BN(conf.a, 16).umod(this.red.m); + this.a = this.a.toRed(this.red); + this.c = new BN(conf.c, 16).toRed(this.red); + this.c2 = this.c.redSqr(); + this.d = new BN(conf.d, 16).toRed(this.red); + this.dd = this.d.redAdd(this.d); -var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/; + assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); + this.oneC = (conf.c | 0) === 1; +} +inherits(EdwardsCurve, Base); +module.exports = EdwardsCurve; -// The name of a form control's ValidityState property. -// This is used so that it's possible for internal tests to create mock ValidityStates. -var VALIDITY_STATE_PROPERTY = 'validity'; +EdwardsCurve.prototype._mulA = function _mulA(num) { + if (this.mOneA) + return num.redNeg(); + else + return this.a.redMul(num); +}; +EdwardsCurve.prototype._mulC = function _mulC(num) { + if (this.oneC) + return num; + else + return this.c.redMul(num); +}; -var hasOwnProperty = Object.prototype.hasOwnProperty; +// Just for compatibility with Short curve +EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { + return this.point(x, y, z, t); +}; -/** - * @private - * - * @description Converts the specified string to lowercase. - * @param {string} string String to be converted to lowercase. - * @returns {string} Lowercased string. - */ -var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;}; +EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) { + x = new BN(x, 16); + if (!x.red) + x = x.toRed(this.red); -/** - * @private - * - * @description Converts the specified string to uppercase. - * @param {string} string String to be converted to uppercase. - * @returns {string} Uppercased string. - */ -var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;}; + var x2 = x.redSqr(); + var rhs = this.c2.redSub(this.a.redMul(x2)); + var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); + var y2 = rhs.redMul(lhs.redInvm()); + var y = y2.redSqrt(); + if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) + throw new Error('invalid point'); -var - msie, // holds major version number for IE, or NaN if UA is not IE. - jqLite, // delay binding since jQuery could be loaded after us. - jQuery, // delay binding - slice = [].slice, - splice = [].splice, - push = [].push, - toString = Object.prototype.toString, - getPrototypeOf = Object.getPrototypeOf, - ngMinErr = minErr('ng'), + var isOdd = y.fromRed().isOdd(); + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); - /** @name angular */ - angular = window.angular || (window.angular = {}), - angularModule, - uid = 0; + return this.point(x, y); +}; -// Support: IE 9-11 only -/** - * documentMode is an IE-only property - * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx - */ -msie = window.document.documentMode; +EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) { + y = new BN(y, 16); + if (!y.red) + y = y.toRed(this.red); + // x^2 = (y^2 - c^2) / (c^2 d y^2 - a) + var y2 = y.redSqr(); + var lhs = y2.redSub(this.c2); + var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a); + var x2 = lhs.redMul(rhs.redInvm()); -/** - * @private - * @param {*} obj - * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, - * String ...) - */ -function isArrayLike(obj) { + if (x2.cmp(this.zero) === 0) { + if (odd) + throw new Error('invalid point'); + else + return this.point(this.zero, y); + } - // `null`, `undefined` and `window` are not array-like - if (obj == null || isWindow(obj)) return false; + var x = x2.redSqrt(); + if (x.redSqr().redSub(x2).cmp(this.zero) !== 0) + throw new Error('invalid point'); - // arrays, strings and jQuery/jqLite objects are array like - // * jqLite is either the jQuery or jqLite constructor function - // * we have to check the existence of jqLite first as this method is called - // via the forEach method when constructing the jqLite object in the first place - if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true; + if (x.fromRed().isOdd() !== odd) + x = x.redNeg(); - // Support: iOS 8.2 (not reproducible in simulator) - // "length" in obj used to prevent JIT error (gh-11508) - var length = 'length' in Object(obj) && obj.length; + return this.point(x, y); +}; - // NodeList objects (with `item` method) and - // other objects with suitable length characteristics are array-like - return isNumber(length) && (length >= 0 && (length - 1) in obj || typeof obj.item === 'function'); +EdwardsCurve.prototype.validate = function validate(point) { + if (point.isInfinity()) + return true; -} + // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) + point.normalize(); -/** - * @ngdoc function - * @name angular.forEach - * @module ng - * @kind function - * - * @description - * Invokes the `iterator` function once for each item in `obj` collection, which can be either an - * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value` - * is the value of an object property or an array element, `key` is the object property key or - * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional. - * - * It is worth noting that `.forEach` does not iterate over inherited properties because it filters - * using the `hasOwnProperty` method. - * - * Unlike ES262's - * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18), - * providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just - * return the value provided. - * - ```js - var values = {name: 'misko', gender: 'male'}; - var log = []; - angular.forEach(values, function(value, key) { - this.push(key + ': ' + value); - }, log); - expect(log).toEqual(['name: misko', 'gender: male']); - ``` - * - * @param {Object|Array} obj Object to iterate over. - * @param {Function} iterator Iterator function. - * @param {Object=} context Object to become context (`this`) for the iterator function. - * @returns {Object|Array} Reference to `obj`. - */ + var x2 = point.x.redSqr(); + var y2 = point.y.redSqr(); + var lhs = x2.redMul(this.a).redAdd(y2); + var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); -function forEach(obj, iterator, context) { - var key, length; - if (obj) { - if (isFunction(obj)) { - for (key in obj) { - if (key !== 'prototype' && key !== 'length' && key !== 'name' && obj.hasOwnProperty(key)) { - iterator.call(context, obj[key], key, obj); - } - } - } else if (isArray(obj) || isArrayLike(obj)) { - var isPrimitive = typeof obj !== 'object'; - for (key = 0, length = obj.length; key < length; key++) { - if (isPrimitive || key in obj) { - iterator.call(context, obj[key], key, obj); - } - } - } else if (obj.forEach && obj.forEach !== forEach) { - obj.forEach(iterator, context, obj); - } else if (isBlankObject(obj)) { - // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty - for (key in obj) { - iterator.call(context, obj[key], key, obj); - } - } else if (typeof obj.hasOwnProperty === 'function') { - // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed - for (key in obj) { - if (obj.hasOwnProperty(key)) { - iterator.call(context, obj[key], key, obj); - } - } - } else { - // Slow path for objects which do not have a method `hasOwnProperty` - for (key in obj) { - if (hasOwnProperty.call(obj, key)) { - iterator.call(context, obj[key], key, obj); - } - } + return lhs.cmp(rhs) === 0; +}; + +function Point(curve, x, y, z, t) { + Base.BasePoint.call(this, curve, 'projective'); + if (x === null && y === null && z === null) { + this.x = this.curve.zero; + this.y = this.curve.one; + this.z = this.curve.one; + this.t = this.curve.zero; + this.zOne = true; + } else { + this.x = new BN(x, 16); + this.y = new BN(y, 16); + this.z = z ? new BN(z, 16) : this.curve.one; + this.t = t && new BN(t, 16); + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); + if (this.t && !this.t.red) + this.t = this.t.toRed(this.curve.red); + this.zOne = this.z === this.curve.one; + + // Use extended coordinates + if (this.curve.extended && !this.t) { + this.t = this.x.redMul(this.y); + if (!this.zOne) + this.t = this.t.redMul(this.z.redInvm()); } } - return obj; } +inherits(Point, Base.BasePoint); -function forEachSorted(obj, iterator, context) { - var keys = Object.keys(obj).sort(); - for (var i = 0; i < keys.length; i++) { - iterator.call(context, obj[keys[i]], keys[i]); - } - return keys; -} +EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { + return Point.fromJSON(this, obj); +}; +EdwardsCurve.prototype.point = function point(x, y, z, t) { + return new Point(this, x, y, z, t); +}; -/** - * when using forEach the params are value, key, but it is often useful to have key, value. - * @param {function(string, *)} iteratorFn - * @returns {function(*, string)} - */ -function reverseParams(iteratorFn) { - return function(value, key) {iteratorFn(key, value);}; -} +Point.fromJSON = function fromJSON(curve, obj) { + return new Point(curve, obj[0], obj[1], obj[2]); +}; -/** - * A consistent way of creating unique IDs in angular. - * - * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before - * we hit number precision issues in JavaScript. - * - * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M - * - * @returns {number} an unique alpha-numeric string - */ -function nextUid() { - return ++uid; -} +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; +Point.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.x.cmpn(0) === 0 && + (this.y.cmp(this.z) === 0 || + (this.zOne && this.y.cmp(this.curve.c) === 0)); +}; -/** - * Set or clear the hashkey for an object. - * @param obj object - * @param h the hashkey (!truthy to delete the hashkey) - */ -function setHashKey(obj, h) { - if (h) { - obj.$$hashKey = h; - } else { - delete obj.$$hashKey; - } -} +Point.prototype._extDbl = function _extDbl() { + // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // #doubling-dbl-2008-hwcd + // 4M + 4S + // A = X1^2 + var a = this.x.redSqr(); + // B = Y1^2 + var b = this.y.redSqr(); + // C = 2 * Z1^2 + var c = this.z.redSqr(); + c = c.redIAdd(c); + // D = a * A + var d = this.curve._mulA(a); + // E = (X1 + Y1)^2 - A - B + var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); + // G = D + B + var g = d.redAdd(b); + // F = G - C + var f = g.redSub(c); + // H = D - B + var h = d.redSub(b); + // X3 = E * F + var nx = e.redMul(f); + // Y3 = G * H + var ny = g.redMul(h); + // T3 = E * H + var nt = e.redMul(h); + // Z3 = F * G + var nz = f.redMul(g); + return this.curve.point(nx, ny, nz, nt); +}; -function baseExtend(dst, objs, deep) { - var h = dst.$$hashKey; +Point.prototype._projDbl = function _projDbl() { + // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // #doubling-dbl-2008-bbjlp + // #doubling-dbl-2007-bl + // and others + // Generally 3M + 4S or 2M + 4S - for (var i = 0, ii = objs.length; i < ii; ++i) { - var obj = objs[i]; - if (!isObject(obj) && !isFunction(obj)) continue; - var keys = Object.keys(obj); - for (var j = 0, jj = keys.length; j < jj; j++) { - var key = keys[j]; - var src = obj[key]; + // B = (X1 + Y1)^2 + var b = this.x.redAdd(this.y).redSqr(); + // C = X1^2 + var c = this.x.redSqr(); + // D = Y1^2 + var d = this.y.redSqr(); - if (deep && isObject(src)) { - if (isDate(src)) { - dst[key] = new Date(src.valueOf()); - } else if (isRegExp(src)) { - dst[key] = new RegExp(src); - } else if (src.nodeName) { - dst[key] = src.cloneNode(true); - } else if (isElement(src)) { - dst[key] = src.clone(); - } else { - if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {}; - baseExtend(dst[key], [src], true); - } - } else { - dst[key] = src; - } + var nx; + var ny; + var nz; + if (this.curve.twisted) { + // E = a * C + var e = this.curve._mulA(c); + // F = E + D + var f = e.redAdd(d); + if (this.zOne) { + // X3 = (B - C - D) * (F - 2) + nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); + // Y3 = F * (E - D) + ny = f.redMul(e.redSub(d)); + // Z3 = F^2 - 2 * F + nz = f.redSqr().redSub(f).redSub(f); + } else { + // H = Z1^2 + var h = this.z.redSqr(); + // J = F - 2 * H + var j = f.redSub(h).redISub(h); + // X3 = (B-C-D)*J + nx = b.redSub(c).redISub(d).redMul(j); + // Y3 = F * (E - D) + ny = f.redMul(e.redSub(d)); + // Z3 = F * J + nz = f.redMul(j); } + } else { + // E = C + D + var e = c.redAdd(d); + // H = (c * Z1)^2 + var h = this.curve._mulC(this.z).redSqr(); + // J = E - 2 * H + var j = e.redSub(h).redSub(h); + // X3 = c * (B - E) * J + nx = this.curve._mulC(b.redISub(e)).redMul(j); + // Y3 = c * E * (C - D) + ny = this.curve._mulC(e).redMul(c.redISub(d)); + // Z3 = E * J + nz = e.redMul(j); } + return this.curve.point(nx, ny, nz); +}; - setHashKey(dst, h); - return dst; -} - -/** - * @ngdoc function - * @name angular.extend - * @module ng - * @kind function - * - * @description - * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s) - * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so - * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`. - * - * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use - * {@link angular.merge} for this. - * - * @param {Object} dst Destination object. - * @param {...Object} src Source object(s). - * @returns {Object} Reference to `dst`. - */ -function extend(dst) { - return baseExtend(dst, slice.call(arguments, 1), false); -} - +Point.prototype.dbl = function dbl() { + if (this.isInfinity()) + return this; -/** -* @ngdoc function -* @name angular.merge -* @module ng -* @kind function -* -* @description -* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s) -* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so -* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`. -* -* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source -* objects, performing a deep copy. -* -* @deprecated -* sinceVersion="1.6.5" -* This function is deprecated, but will not be removed in the 1.x lifecycle. -* There are edge cases (see {@link angular.merge#known-issues known issues}) that are not -* supported by this function. We suggest -* using [lodash's merge()](https://lodash.com/docs/4.17.4#merge) instead. -* -* @knownIssue -* This is a list of (known) object types that are not handled correctly by this function: -* - [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob) -* - [`MediaStream`](https://developer.mozilla.org/docs/Web/API/MediaStream) -* - [`CanvasGradient`](https://developer.mozilla.org/docs/Web/API/CanvasGradient) -* - AngularJS {@link $rootScope.Scope scopes}; -* -* @param {Object} dst Destination object. -* @param {...Object} src Source object(s). -* @returns {Object} Reference to `dst`. -*/ -function merge(dst) { - return baseExtend(dst, slice.call(arguments, 1), true); -} + // Double in extended coordinates + if (this.curve.extended) + return this._extDbl(); + else + return this._projDbl(); +}; +Point.prototype._extAdd = function _extAdd(p) { + // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // #addition-add-2008-hwcd-3 + // 8M + // A = (Y1 - X1) * (Y2 - X2) + var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); + // B = (Y1 + X1) * (Y2 + X2) + var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); + // C = T1 * k * T2 + var c = this.t.redMul(this.curve.dd).redMul(p.t); + // D = Z1 * 2 * Z2 + var d = this.z.redMul(p.z.redAdd(p.z)); + // E = B - A + var e = b.redSub(a); + // F = D - C + var f = d.redSub(c); + // G = D + C + var g = d.redAdd(c); + // H = B + A + var h = b.redAdd(a); + // X3 = E * F + var nx = e.redMul(f); + // Y3 = G * H + var ny = g.redMul(h); + // T3 = E * H + var nt = e.redMul(h); + // Z3 = F * G + var nz = f.redMul(g); + return this.curve.point(nx, ny, nz, nt); +}; -function toInt(str) { - return parseInt(str, 10); -} +Point.prototype._projAdd = function _projAdd(p) { + // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // #addition-add-2008-bbjlp + // #addition-add-2007-bl + // 10M + 1S -var isNumberNaN = Number.isNaN || function isNumberNaN(num) { - // eslint-disable-next-line no-self-compare - return num !== num; + // A = Z1 * Z2 + var a = this.z.redMul(p.z); + // B = A^2 + var b = a.redSqr(); + // C = X1 * X2 + var c = this.x.redMul(p.x); + // D = Y1 * Y2 + var d = this.y.redMul(p.y); + // E = d * C * D + var e = this.curve.d.redMul(c).redMul(d); + // F = B - E + var f = b.redSub(e); + // G = B + E + var g = b.redAdd(e); + // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) + var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); + var nx = a.redMul(f).redMul(tmp); + var ny; + var nz; + if (this.curve.twisted) { + // Y3 = A * G * (D - a * C) + ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); + // Z3 = F * G + nz = f.redMul(g); + } else { + // Y3 = A * G * (D - C) + ny = a.redMul(g).redMul(d.redSub(c)); + // Z3 = c * F * G + nz = this.curve._mulC(f).redMul(g); + } + return this.curve.point(nx, ny, nz); }; +Point.prototype.add = function add(p) { + if (this.isInfinity()) + return p; + if (p.isInfinity()) + return this; -function inherit(parent, extra) { - return extend(Object.create(parent), extra); -} - -/** - * @ngdoc function - * @name angular.noop - * @module ng - * @kind function - * - * @description - * A function that performs no operations. This function can be useful when writing code in the - * functional style. - ```js - function foo(callback) { - var result = calculateResult(); - (callback || angular.noop)(result); - } - ``` - */ -function noop() {} -noop.$inject = []; + if (this.curve.extended) + return this._extAdd(p); + else + return this._projAdd(p); +}; +Point.prototype.mul = function mul(k) { + if (this._hasDoubles(k)) + return this.curve._fixedNafMul(this, k); + else + return this.curve._wnafMul(this, k); +}; -/** - * @ngdoc function - * @name angular.identity - * @module ng - * @kind function - * - * @description - * A function that returns its first argument. This function is useful when writing code in the - * functional style. - * - ```js - function transformer(transformationFn, value) { - return (transformationFn || angular.identity)(value); - }; +Point.prototype.mulAdd = function mulAdd(k1, p, k2) { + return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false); +}; - // E.g. - function getResult(fn, input) { - return (fn || angular.identity)(input); - }; +Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) { + return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true); +}; - getResult(function(n) { return n * 2; }, 21); // returns 42 - getResult(null, 21); // returns 21 - getResult(undefined, 21); // returns 21 - ``` - * - * @param {*} value to be returned. - * @returns {*} the value passed in. - */ -function identity($) {return $;} -identity.$inject = []; +Point.prototype.normalize = function normalize() { + if (this.zOne) + return this; + // Normalize coordinates + var zi = this.z.redInvm(); + this.x = this.x.redMul(zi); + this.y = this.y.redMul(zi); + if (this.t) + this.t = this.t.redMul(zi); + this.z = this.curve.one; + this.zOne = true; + return this; +}; -function valueFn(value) {return function valueRef() {return value;};} +Point.prototype.neg = function neg() { + return this.curve.point(this.x.redNeg(), + this.y, + this.z, + this.t && this.t.redNeg()); +}; -function hasCustomToString(obj) { - return isFunction(obj.toString) && obj.toString !== toString; -} +Point.prototype.getX = function getX() { + this.normalize(); + return this.x.fromRed(); +}; +Point.prototype.getY = function getY() { + this.normalize(); + return this.y.fromRed(); +}; -/** - * @ngdoc function - * @name angular.isUndefined - * @module ng - * @kind function - * - * @description - * Determines if a reference is undefined. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is undefined. - */ -function isUndefined(value) {return typeof value === 'undefined';} +Point.prototype.eq = function eq(other) { + return this === other || + this.getX().cmp(other.getX()) === 0 && + this.getY().cmp(other.getY()) === 0; +}; +Point.prototype.eqXToP = function eqXToP(x) { + var rx = x.toRed(this.curve.red).redMul(this.z); + if (this.x.cmp(rx) === 0) + return true; -/** - * @ngdoc function - * @name angular.isDefined - * @module ng - * @kind function - * - * @description - * Determines if a reference is defined. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is defined. - */ -function isDefined(value) {return typeof value !== 'undefined';} + var xc = x.clone(); + var t = this.curve.redN.redMul(this.z); + for (;;) { + xc.iadd(this.curve.n); + if (xc.cmp(this.curve.p) >= 0) + return false; + rx.redIAdd(t); + if (this.x.cmp(rx) === 0) + return true; + } +}; -/** - * @ngdoc function - * @name angular.isObject - * @module ng - * @kind function - * - * @description - * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not - * considered to be objects. Note that JavaScript arrays are objects. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Object` but not `null`. - */ -function isObject(value) { - // http://jsperf.com/isobject4 - return value !== null && typeof value === 'object'; -} +// Compatibility with BaseCurve +Point.prototype.toP = Point.prototype.normalize; +Point.prototype.mixedAdd = Point.prototype.add; +},{"../../elliptic":195,"../curve":198,"bn.js":181,"inherits":246}],198:[function(require,module,exports){ +'use strict'; -/** - * Determine if a value is an object with a null prototype - * - * @returns {boolean} True if `value` is an `Object` with a null prototype - */ -function isBlankObject(value) { - return value !== null && typeof value === 'object' && !getPrototypeOf(value); -} +var curve = exports; +curve.base = require('./base'); +curve.short = require('./short'); +curve.mont = require('./mont'); +curve.edwards = require('./edwards'); -/** - * @ngdoc function - * @name angular.isString - * @module ng - * @kind function - * - * @description - * Determines if a reference is a `String`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `String`. - */ -function isString(value) {return typeof value === 'string';} +},{"./base":196,"./edwards":197,"./mont":199,"./short":200}],199:[function(require,module,exports){ +'use strict'; +var curve = require('../curve'); +var BN = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; -/** - * @ngdoc function - * @name angular.isNumber - * @module ng - * @kind function - * - * @description - * Determines if a reference is a `Number`. - * - * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`. - * - * If you wish to exclude these then you can use the native - * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite) - * method. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Number`. - */ -function isNumber(value) {return typeof value === 'number';} +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +function MontCurve(conf) { + Base.call(this, 'mont', conf); -/** - * @ngdoc function - * @name angular.isDate - * @module ng - * @kind function - * - * @description - * Determines if a value is a date. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Date`. - */ -function isDate(value) { - return toString.call(value) === '[object Date]'; + this.a = new BN(conf.a, 16).toRed(this.red); + this.b = new BN(conf.b, 16).toRed(this.red); + this.i4 = new BN(4).toRed(this.red).redInvm(); + this.two = new BN(2).toRed(this.red); + this.a24 = this.i4.redMul(this.a.redAdd(this.two)); } +inherits(MontCurve, Base); +module.exports = MontCurve; +MontCurve.prototype.validate = function validate(point) { + var x = point.normalize().x; + var x2 = x.redSqr(); + var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); + var y = rhs.redSqrt(); -/** - * @ngdoc function - * @name angular.isArray - * @module ng - * @kind function - * - * @description - * Determines if a reference is an `Array`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Array`. - */ -function isArray(arr) { - return Array.isArray(arr) || arr instanceof Array; -} + return y.redSqr().cmp(rhs) === 0; +}; -/** - * @description - * Determines if a reference is an `Error`. - * Loosely based on https://www.npmjs.com/package/iserror - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Error`. - */ -function isError(value) { - var tag = toString.call(value); - switch (tag) { - case '[object Error]': return true; - case '[object Exception]': return true; - case '[object DOMException]': return true; - default: return value instanceof Error; +function Point(curve, x, z) { + Base.BasePoint.call(this, curve, 'projective'); + if (x === null && z === null) { + this.x = this.curve.one; + this.z = this.curve.zero; + } else { + this.x = new BN(x, 16); + this.z = new BN(z, 16); + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); } } +inherits(Point, Base.BasePoint); -/** - * @ngdoc function - * @name angular.isFunction - * @module ng - * @kind function - * - * @description - * Determines if a reference is a `Function`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Function`. - */ -function isFunction(value) {return typeof value === 'function';} - - -/** - * Determines if a value is a regular expression object. - * - * @private - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `RegExp`. - */ -function isRegExp(value) { - return toString.call(value) === '[object RegExp]'; -} - - -/** - * Checks if `obj` is a window object. - * - * @private - * @param {*} obj Object to check - * @returns {boolean} True if `obj` is a window obj. - */ -function isWindow(obj) { - return obj && obj.window === obj; -} - +MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) { + return this.point(utils.toArray(bytes, enc), 1); +}; -function isScope(obj) { - return obj && obj.$evalAsync && obj.$watch; -} +MontCurve.prototype.point = function point(x, z) { + return new Point(this, x, z); +}; +MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { + return Point.fromJSON(this, obj); +}; -function isFile(obj) { - return toString.call(obj) === '[object File]'; -} +Point.prototype.precompute = function precompute() { + // No-op +}; +Point.prototype._encode = function _encode() { + return this.getX().toArray('be', this.curve.p.byteLength()); +}; -function isFormData(obj) { - return toString.call(obj) === '[object FormData]'; -} +Point.fromJSON = function fromJSON(curve, obj) { + return new Point(curve, obj[0], obj[1] || curve.one); +}; +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; -function isBlob(obj) { - return toString.call(obj) === '[object Blob]'; -} +Point.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.z.cmpn(0) === 0; +}; +Point.prototype.dbl = function dbl() { + // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 + // 2M + 2S + 4A -function isBoolean(value) { - return typeof value === 'boolean'; -} + // A = X1 + Z1 + var a = this.x.redAdd(this.z); + // AA = A^2 + var aa = a.redSqr(); + // B = X1 - Z1 + var b = this.x.redSub(this.z); + // BB = B^2 + var bb = b.redSqr(); + // C = AA - BB + var c = aa.redSub(bb); + // X3 = AA * BB + var nx = aa.redMul(bb); + // Z3 = C * (BB + A24 * C) + var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); + return this.curve.point(nx, nz); +}; +Point.prototype.add = function add() { + throw new Error('Not supported on Montgomery curve'); +}; -function isPromiseLike(obj) { - return obj && isFunction(obj.then); -} +Point.prototype.diffAdd = function diffAdd(p, diff) { + // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 + // 4M + 2S + 6A + // A = X2 + Z2 + var a = this.x.redAdd(this.z); + // B = X2 - Z2 + var b = this.x.redSub(this.z); + // C = X3 + Z3 + var c = p.x.redAdd(p.z); + // D = X3 - Z3 + var d = p.x.redSub(p.z); + // DA = D * A + var da = d.redMul(a); + // CB = C * B + var cb = c.redMul(b); + // X5 = Z1 * (DA + CB)^2 + var nx = diff.z.redMul(da.redAdd(cb).redSqr()); + // Z5 = X1 * (DA - CB)^2 + var nz = diff.x.redMul(da.redISub(cb).redSqr()); + return this.curve.point(nx, nz); +}; -var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array]$/; -function isTypedArray(value) { - return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value)); -} +Point.prototype.mul = function mul(k) { + var t = k.clone(); + var a = this; // (N / 2) * Q + Q + var b = this.curve.point(null, null); // (N / 2) * Q + var c = this; // Q -function isArrayBuffer(obj) { - return toString.call(obj) === '[object ArrayBuffer]'; -} + for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1)) + bits.push(t.andln(1)); + for (var i = bits.length - 1; i >= 0; i--) { + if (bits[i] === 0) { + // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q + a = a.diffAdd(b, c); + // N * Q = 2 * ((N / 2) * Q + Q)) + b = b.dbl(); + } else { + // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) + b = a.diffAdd(b, c); + // N * Q + Q = 2 * ((N / 2) * Q + Q) + a = a.dbl(); + } + } + return b; +}; -var trim = function(value) { - return isString(value) ? value.trim() : value; +Point.prototype.mulAdd = function mulAdd() { + throw new Error('Not supported on Montgomery curve'); }; -// Copied from: -// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021 -// Prereq: s is a string. -var escapeForRegexp = function(s) { - return s - .replace(/([-()[\]{}+?*.$^|,:#= 0) { - array.splice(index, 1); - } - return index; -} +var assert = elliptic.utils.assert; -/** - * @ngdoc function - * @name angular.copy - * @module ng - * @kind function - * - * @description - * Creates a deep copy of `source`, which should be an object or an array. - * - * * If no destination is supplied, a copy of the object or array is created. - * * If a destination is provided, all of its elements (for arrays) or properties (for objects) - * are deleted and then all elements/properties from the source are copied to it. - * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. - * * If `source` is identical to `destination` an exception will be thrown. - * - *
- * - *
- * Only enumerable properties are taken into account. Non-enumerable properties (both on `source` - * and on `destination`) will be ignored. - *
- * - * @param {*} source The source that will be used to make a copy. Can be any type, including - * primitives, `null`, and `undefined`. - * @param {(Object|Array)=} destination Destination into which the source is copied. If provided, - * must be of the same type as `source`. - * @returns {*} The copy or updated `destination`, if `destination` was specified. - * - * @example - - -
-
-
-
- Gender: -
- - -
-
form = {{user | json}}
-
leader = {{leader | json}}
-
-
- - // Module: copyExample - angular. - module('copyExample', []). - controller('ExampleController', ['$scope', function($scope) { - $scope.leader = {}; +function ShortCurve(conf) { + Base.call(this, 'short', conf); - $scope.reset = function() { - // Example with 1 argument - $scope.user = angular.copy($scope.leader); - }; + this.a = new BN(conf.a, 16).toRed(this.red); + this.b = new BN(conf.b, 16).toRed(this.red); + this.tinv = this.two.redInvm(); - $scope.update = function(user) { - // Example with 2 arguments - angular.copy(user, $scope.leader); - }; + this.zeroA = this.a.fromRed().cmpn(0) === 0; + this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; - $scope.reset(); - }]); - -
- */ -function copy(source, destination, maxDepth) { - var stackSource = []; - var stackDest = []; - maxDepth = isValidObjectMaxDepth(maxDepth) ? maxDepth : NaN; + // If the curve is endomorphic, precalculate beta and lambda + this.endo = this._getEndomorphism(conf); + this._endoWnafT1 = new Array(4); + this._endoWnafT2 = new Array(4); +} +inherits(ShortCurve, Base); +module.exports = ShortCurve; - if (destination) { - if (isTypedArray(destination) || isArrayBuffer(destination)) { - throw ngMinErr('cpta', 'Can\'t copy! TypedArray destination cannot be mutated.'); - } - if (source === destination) { - throw ngMinErr('cpi', 'Can\'t copy! Source and destination are identical.'); - } +ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { + // No efficient endomorphism + if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) + return; - // Empty the destination object - if (isArray(destination)) { - destination.length = 0; + // Compute beta and lambda, that lambda * P = (beta * Px; Py) + var beta; + var lambda; + if (conf.beta) { + beta = new BN(conf.beta, 16).toRed(this.red); + } else { + var betas = this._getEndoRoots(this.p); + // Choose the smallest beta + beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; + beta = beta.toRed(this.red); + } + if (conf.lambda) { + lambda = new BN(conf.lambda, 16); + } else { + // Choose the lambda that is matching selected beta + var lambdas = this._getEndoRoots(this.n); + if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { + lambda = lambdas[0]; } else { - forEach(destination, function(value, key) { - if (key !== '$$hashKey') { - delete destination[key]; - } - }); + lambda = lambdas[1]; + assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); } - - stackSource.push(source); - stackDest.push(destination); - return copyRecurse(source, destination, maxDepth); } - return copyElement(source, maxDepth); - - function copyRecurse(source, destination, maxDepth) { - maxDepth--; - if (maxDepth < 0) { - return '...'; - } - var h = destination.$$hashKey; - var key; - if (isArray(source)) { - for (var i = 0, ii = source.length; i < ii; i++) { - destination.push(copyElement(source[i], maxDepth)); - } - } else if (isBlankObject(source)) { - // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty - for (key in source) { - destination[key] = copyElement(source[key], maxDepth); - } - } else if (source && typeof source.hasOwnProperty === 'function') { - // Slow path, which must rely on hasOwnProperty - for (key in source) { - if (source.hasOwnProperty(key)) { - destination[key] = copyElement(source[key], maxDepth); - } - } - } else { - // Slowest path --- hasOwnProperty can't be called as a method - for (key in source) { - if (hasOwnProperty.call(source, key)) { - destination[key] = copyElement(source[key], maxDepth); - } - } - } - setHashKey(destination, h); - return destination; + // Get basis vectors, used for balanced length-two representation + var basis; + if (conf.basis) { + basis = conf.basis.map(function(vec) { + return { + a: new BN(vec.a, 16), + b: new BN(vec.b, 16) + }; + }); + } else { + basis = this._getEndoBasis(lambda); } - function copyElement(source, maxDepth) { - // Simple values - if (!isObject(source)) { - return source; - } + return { + beta: beta, + lambda: lambda, + basis: basis + }; +}; - // Already copied values - var index = stackSource.indexOf(source); - if (index !== -1) { - return stackDest[index]; - } +ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { + // Find roots of for x^2 + x + 1 in F + // Root = (-1 +- Sqrt(-3)) / 2 + // + var red = num === this.p ? this.red : BN.mont(num); + var tinv = new BN(2).toRed(red).redInvm(); + var ntinv = tinv.redNeg(); - if (isWindow(source) || isScope(source)) { - throw ngMinErr('cpws', - 'Can\'t copy! Making copies of Window or Scope instances is not supported.'); - } + var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv); - var needsRecurse = false; - var destination = copyType(source); + var l1 = ntinv.redAdd(s).fromRed(); + var l2 = ntinv.redSub(s).fromRed(); + return [ l1, l2 ]; +}; - if (destination === undefined) { - destination = isArray(source) ? [] : Object.create(getPrototypeOf(source)); - needsRecurse = true; - } +ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { + // aprxSqrt >= sqrt(this.n) + var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2)); - stackSource.push(source); - stackDest.push(destination); + // 3.74 + // Run EGCD, until r(L + 1) < aprxSqrt + var u = lambda; + var v = this.n.clone(); + var x1 = new BN(1); + var y1 = new BN(0); + var x2 = new BN(0); + var y2 = new BN(1); - return needsRecurse - ? copyRecurse(source, destination, maxDepth) - : destination; - } + // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) + var a0; + var b0; + // First vector + var a1; + var b1; + // Second vector + var a2; + var b2; - function copyType(source) { - switch (toString.call(source)) { - case '[object Int8Array]': - case '[object Int16Array]': - case '[object Int32Array]': - case '[object Float32Array]': - case '[object Float64Array]': - case '[object Uint8Array]': - case '[object Uint8ClampedArray]': - case '[object Uint16Array]': - case '[object Uint32Array]': - return new source.constructor(copyElement(source.buffer), source.byteOffset, source.length); - - case '[object ArrayBuffer]': - // Support: IE10 - if (!source.slice) { - // If we're in this case we know the environment supports ArrayBuffer - /* eslint-disable no-undef */ - var copied = new ArrayBuffer(source.byteLength); - new Uint8Array(copied).set(new Uint8Array(source)); - /* eslint-enable */ - return copied; - } - return source.slice(0); + var prevR; + var i = 0; + var r; + var x; + while (u.cmpn(0) !== 0) { + var q = v.div(u); + r = v.sub(q.mul(u)); + x = x2.sub(q.mul(x1)); + var y = y2.sub(q.mul(y1)); - case '[object Boolean]': - case '[object Number]': - case '[object String]': - case '[object Date]': - return new source.constructor(source.valueOf()); + if (!a1 && r.cmp(aprxSqrt) < 0) { + a0 = prevR.neg(); + b0 = x1; + a1 = r.neg(); + b1 = x; + } else if (a1 && ++i === 2) { + break; + } + prevR = r; - case '[object RegExp]': - var re = new RegExp(source.source, source.toString().match(/[^/]*$/)[0]); - re.lastIndex = source.lastIndex; - return re; + v = u; + u = r; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } + a2 = r.neg(); + b2 = x; - case '[object Blob]': - return new source.constructor([source], {type: source.type}); - } + var len1 = a1.sqr().add(b1.sqr()); + var len2 = a2.sqr().add(b2.sqr()); + if (len2.cmp(len1) >= 0) { + a2 = a0; + b2 = b0; + } - if (isFunction(source.cloneNode)) { - return source.cloneNode(true); - } + // Normalize signs + if (a1.negative) { + a1 = a1.neg(); + b1 = b1.neg(); + } + if (a2.negative) { + a2 = a2.neg(); + b2 = b2.neg(); } -} + return [ + { a: a1, b: b1 }, + { a: a2, b: b2 } + ]; +}; -// eslint-disable-next-line no-self-compare -function simpleCompare(a, b) { return a === b || (a !== a && b !== b); } +ShortCurve.prototype._endoSplit = function _endoSplit(k) { + var basis = this.endo.basis; + var v1 = basis[0]; + var v2 = basis[1]; + var c1 = v2.b.mul(k).divRound(this.n); + var c2 = v1.b.neg().mul(k).divRound(this.n); -/** - * @ngdoc function - * @name angular.equals - * @module ng - * @kind function - * - * @description - * Determines if two objects or two values are equivalent. Supports value types, regular - * expressions, arrays and objects. - * - * Two objects or values are considered equivalent if at least one of the following is true: - * - * * Both objects or values pass `===` comparison. - * * Both objects or values are of the same type and all of their properties are equal by - * comparing them with `angular.equals`. - * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) - * * Both values represent the same regular expression (In JavaScript, - * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual - * representation matches). - * - * During a property comparison, properties of `function` type and properties with names - * that begin with `$` are ignored. - * - * Scope and DOMWindow objects are being compared only by identify (`===`). - * - * @param {*} o1 Object or value to compare. - * @param {*} o2 Object or value to compare. - * @returns {boolean} True if arguments are equal. - * - * @example - - -
-
-

User 1

- Name: - Age: + var p1 = c1.mul(v1.a); + var p2 = c2.mul(v2.a); + var q1 = c1.mul(v1.b); + var q2 = c2.mul(v2.b); -

User 2

- Name: - Age: + // Calculate answer + var k1 = k.sub(p1).sub(p2); + var k2 = q1.add(q2).neg(); + return { k1: k1, k2: k2 }; +}; -
-
- -
- User 1:
{{user1 | json}}
- User 2:
{{user2 | json}}
- Equal:
{{result}}
-
-
-
- - angular.module('equalsExample', []).controller('ExampleController', ['$scope', function($scope) { - $scope.user1 = {}; - $scope.user2 = {}; - $scope.compare = function() { - $scope.result = angular.equals($scope.user1, $scope.user2); - }; - }]); - -
- */ -function equals(o1, o2) { - if (o1 === o2) return true; - if (o1 === null || o2 === null) return false; - // eslint-disable-next-line no-self-compare - if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN - var t1 = typeof o1, t2 = typeof o2, length, key, keySet; - if (t1 === t2 && t1 === 'object') { - if (isArray(o1)) { - if (!isArray(o2)) return false; - if ((length = o1.length) === o2.length) { - for (key = 0; key < length; key++) { - if (!equals(o1[key], o2[key])) return false; - } - return true; - } - } else if (isDate(o1)) { - if (!isDate(o2)) return false; - return simpleCompare(o1.getTime(), o2.getTime()); - } else if (isRegExp(o1)) { - if (!isRegExp(o2)) return false; - return o1.toString() === o2.toString(); - } else { - if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || - isArray(o2) || isDate(o2) || isRegExp(o2)) return false; - keySet = createMap(); - for (key in o1) { - if (key.charAt(0) === '$' || isFunction(o1[key])) continue; - if (!equals(o1[key], o2[key])) return false; - keySet[key] = true; - } - for (key in o2) { - if (!(key in keySet) && - key.charAt(0) !== '$' && - isDefined(o2[key]) && - !isFunction(o2[key])) return false; - } - return true; - } - } - return false; -} +ShortCurve.prototype.pointFromX = function pointFromX(x, odd) { + x = new BN(x, 16); + if (!x.red) + x = x.toRed(this.red); -var csp = function() { - if (!isDefined(csp.rules)) { + var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); + var y = y2.redSqrt(); + if (y.redSqr().redSub(y2).cmp(this.zero) !== 0) + throw new Error('invalid point'); + // XXX Is there any way to tell if the number is odd without converting it + // to non-red form? + var isOdd = y.fromRed().isOdd(); + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); - var ngCspElement = (window.document.querySelector('[ng-csp]') || - window.document.querySelector('[data-ng-csp]')); + return this.point(x, y); +}; - if (ngCspElement) { - var ngCspAttribute = ngCspElement.getAttribute('ng-csp') || - ngCspElement.getAttribute('data-ng-csp'); - csp.rules = { - noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1), - noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1) - }; - } else { - csp.rules = { - noUnsafeEval: noUnsafeEval(), - noInlineStyle: false - }; - } - } +ShortCurve.prototype.validate = function validate(point) { + if (point.inf) + return true; - return csp.rules; + var x = point.x; + var y = point.y; - function noUnsafeEval() { - try { - // eslint-disable-next-line no-new, no-new-func - new Function(''); - return false; - } catch (e) { - return true; + var ax = this.a.redMul(x); + var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); + return y.redSqr().redISub(rhs).cmpn(0) === 0; +}; + +ShortCurve.prototype._endoWnafMulAdd = + function _endoWnafMulAdd(points, coeffs, jacobianResult) { + var npoints = this._endoWnafT1; + var ncoeffs = this._endoWnafT2; + for (var i = 0; i < points.length; i++) { + var split = this._endoSplit(coeffs[i]); + var p = points[i]; + var beta = p._getBeta(); + + if (split.k1.negative) { + split.k1.ineg(); + p = p.neg(true); + } + if (split.k2.negative) { + split.k2.ineg(); + beta = beta.neg(true); } + + npoints[i * 2] = p; + npoints[i * 2 + 1] = beta; + ncoeffs[i * 2] = split.k1; + ncoeffs[i * 2 + 1] = split.k2; + } + var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult); + + // Clean-up references to points and coefficients + for (var j = 0; j < i * 2; j++) { + npoints[j] = null; + ncoeffs[j] = null; } + return res; }; -/** - * @ngdoc directive - * @module ng - * @name ngJq - * - * @element ANY - * @param {string=} ngJq the name of the library available under `window` - * to be used for angular.element - * @description - * Use this directive to force the angular.element library. This should be - * used to force either jqLite by leaving ng-jq blank or setting the name of - * the jquery variable under window (eg. jQuery). - * - * Since AngularJS looks for this directive when it is loaded (doesn't wait for the - * DOMContentLoaded event), it must be placed on an element that comes before the script - * which loads angular. Also, only the first instance of `ng-jq` will be used and all - * others ignored. - * - * @example - * This example shows how to force jqLite using the `ngJq` directive to the `html` tag. - ```html - - - ... - ... - - ``` - * @example - * This example shows how to use a jQuery based library of a different name. - * The library name must be available at the top most 'window'. - ```html - - - ... - ... - - ``` - */ -var jq = function() { - if (isDefined(jq.name_)) return jq.name_; - var el; - var i, ii = ngAttrPrefixes.length, prefix, name; - for (i = 0; i < ii; ++i) { - prefix = ngAttrPrefixes[i]; - el = window.document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]'); - if (el) { - name = el.getAttribute(prefix + 'jq'); - break; +function Point(curve, x, y, isRed) { + Base.BasePoint.call(this, curve, 'affine'); + if (x === null && y === null) { + this.x = null; + this.y = null; + this.inf = true; + } else { + this.x = new BN(x, 16); + this.y = new BN(y, 16); + // Force redgomery representation when loading from JSON + if (isRed) { + this.x.forceRed(this.curve.red); + this.y.forceRed(this.curve.red); } + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + this.inf = false; } +} +inherits(Point, Base.BasePoint); - return (jq.name_ = name); +ShortCurve.prototype.point = function point(x, y, isRed) { + return new Point(this, x, y, isRed); }; -function concat(array1, array2, index) { - return array1.concat(slice.call(array2, index)); -} +ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { + return Point.fromJSON(this, obj, red); +}; -function sliceArgs(args, startIndex) { - return slice.call(args, startIndex || 0); -} +Point.prototype._getBeta = function _getBeta() { + if (!this.curve.endo) + return; + var pre = this.precomputed; + if (pre && pre.beta) + return pre.beta; -/** - * @ngdoc function - * @name angular.bind - * @module ng - * @kind function - * - * @description - * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for - * `fn`). You can supply optional `args` that are prebound to the function. This feature is also - * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as - * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application). - * - * @param {Object} self Context which `fn` should be evaluated in. - * @param {function()} fn Function to be bound. - * @param {...*} args Optional arguments to be prebound to the `fn` function call. - * @returns {function()} Function that wraps the `fn` with all the specified bindings. - */ -function bind(self, fn) { - var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : []; - if (isFunction(fn) && !(fn instanceof RegExp)) { - return curryArgs.length - ? function() { - return arguments.length - ? fn.apply(self, concat(curryArgs, arguments, 0)) - : fn.apply(self, curryArgs); - } - : function() { - return arguments.length - ? fn.apply(self, arguments) - : fn.call(self); - }; - } else { - // In IE, native methods are not functions so they cannot be bound (note: they don't need to be). - return fn; + var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); + if (pre) { + var curve = this.curve; + var endoMul = function(p) { + return curve.point(p.x.redMul(curve.endo.beta), p.y); + }; + pre.beta = beta; + beta.precomputed = { + beta: null, + naf: pre.naf && { + wnd: pre.naf.wnd, + points: pre.naf.points.map(endoMul) + }, + doubles: pre.doubles && { + step: pre.doubles.step, + points: pre.doubles.points.map(endoMul) + } + }; } -} + return beta; +}; +Point.prototype.toJSON = function toJSON() { + if (!this.precomputed) + return [ this.x, this.y ]; -function toJsonReplacer(key, value) { - var val = value; + return [ this.x, this.y, this.precomputed && { + doubles: this.precomputed.doubles && { + step: this.precomputed.doubles.step, + points: this.precomputed.doubles.points.slice(1) + }, + naf: this.precomputed.naf && { + wnd: this.precomputed.naf.wnd, + points: this.precomputed.naf.points.slice(1) + } + } ]; +}; - if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') { - val = undefined; - } else if (isWindow(value)) { - val = '$WINDOW'; - } else if (value && window.document === value) { - val = '$DOCUMENT'; - } else if (isScope(value)) { - val = '$SCOPE'; +Point.fromJSON = function fromJSON(curve, obj, red) { + if (typeof obj === 'string') + obj = JSON.parse(obj); + var res = curve.point(obj[0], obj[1], red); + if (!obj[2]) + return res; + + function obj2point(obj) { + return curve.point(obj[0], obj[1], red); } - return val; -} + var pre = obj[2]; + res.precomputed = { + beta: null, + doubles: pre.doubles && { + step: pre.doubles.step, + points: [ res ].concat(pre.doubles.points.map(obj2point)) + }, + naf: pre.naf && { + wnd: pre.naf.wnd, + points: [ res ].concat(pre.naf.points.map(obj2point)) + } + }; + return res; +}; +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; -/** - * @ngdoc function - * @name angular.toJson - * @module ng - * @kind function - * - * @description - * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be - * stripped since AngularJS uses this notation internally. - * - * @param {Object|Array|Date|string|number|boolean} obj Input to be serialized into JSON. - * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace. - * If set to an integer, the JSON output will contain that many spaces per indentation. - * @returns {string|undefined} JSON-ified string representing `obj`. - * @knownIssue - * - * The Safari browser throws a `RangeError` instead of returning `null` when it tries to stringify a `Date` - * object with an invalid date value. The only reliable way to prevent this is to monkeypatch the - * `Date.prototype.toJSON` method as follows: - * - * ``` - * var _DatetoJSON = Date.prototype.toJSON; - * Date.prototype.toJSON = function() { - * try { - * return _DatetoJSON.call(this); - * } catch(e) { - * if (e instanceof RangeError) { - * return null; - * } - * throw e; - * } - * }; - * ``` - * - * See https://github.com/angular/angular.js/pull/14221 for more information. - */ -function toJson(obj, pretty) { - if (isUndefined(obj)) return undefined; - if (!isNumber(pretty)) { - pretty = pretty ? 2 : null; - } - return JSON.stringify(obj, toJsonReplacer, pretty); -} +Point.prototype.isInfinity = function isInfinity() { + return this.inf; +}; +Point.prototype.add = function add(p) { + // O + P = P + if (this.inf) + return p; -/** - * @ngdoc function - * @name angular.fromJson - * @module ng - * @kind function - * - * @description - * Deserializes a JSON string. - * - * @param {string} json JSON string to deserialize. - * @returns {Object|Array|string|number} Deserialized JSON string. - */ -function fromJson(json) { - return isString(json) - ? JSON.parse(json) - : json; -} + // P + O = P + if (p.inf) + return this; + // P + P = 2P + if (this.eq(p)) + return this.dbl(); -var ALL_COLONS = /:/g; -function timezoneToOffset(timezone, fallback) { - // Support: IE 9-11 only, Edge 13-15+ - // IE/Edge do not "understand" colon (`:`) in timezone - timezone = timezone.replace(ALL_COLONS, ''); - var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000; - return isNumberNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset; -} + // P + (-P) = O + if (this.neg().eq(p)) + return this.curve.point(null, null); + // P + Q = O + if (this.x.cmp(p.x) === 0) + return this.curve.point(null, null); -function addDateMinutes(date, minutes) { - date = new Date(date.getTime()); - date.setMinutes(date.getMinutes() + minutes); - return date; -} + var c = this.y.redSub(p.y); + if (c.cmpn(0) !== 0) + c = c.redMul(this.x.redSub(p.x).redInvm()); + var nx = c.redSqr().redISub(this.x).redISub(p.x); + var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); + return this.curve.point(nx, ny); +}; +Point.prototype.dbl = function dbl() { + if (this.inf) + return this; -function convertTimezoneToLocal(date, timezone, reverse) { - reverse = reverse ? -1 : 1; - var dateTimezoneOffset = date.getTimezoneOffset(); - var timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset); - return addDateMinutes(date, reverse * (timezoneOffset - dateTimezoneOffset)); -} + // 2P = O + var ys1 = this.y.redAdd(this.y); + if (ys1.cmpn(0) === 0) + return this.curve.point(null, null); + var a = this.curve.a; -/** - * @returns {string} Returns the string representation of the element. - */ -function startingTag(element) { - element = jqLite(element).clone().empty(); - var elemHtml = jqLite('
').append(element).html(); - try { - return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) : - elemHtml. - match(/^(<[^>]+>)/)[1]. - replace(/^<([\w-]+)/, function(match, nodeName) {return '<' + lowercase(nodeName);}); - } catch (e) { - return lowercase(elemHtml); - } + var x2 = this.x.redSqr(); + var dyinv = ys1.redInvm(); + var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); -} + var nx = c.redSqr().redISub(this.x.redAdd(this.x)); + var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); + return this.curve.point(nx, ny); +}; +Point.prototype.getX = function getX() { + return this.x.fromRed(); +}; -///////////////////////////////////////////////// +Point.prototype.getY = function getY() { + return this.y.fromRed(); +}; -/** - * Tries to decode the URI component without throwing an exception. - * - * @private - * @param str value potential URI component to check. - * @returns {boolean} True if `value` can be decoded - * with the decodeURIComponent function. - */ -function tryDecodeURIComponent(value) { - try { - return decodeURIComponent(value); - } catch (e) { - // Ignore any invalid uri component. - } -} +Point.prototype.mul = function mul(k) { + k = new BN(k, 16); + if (this._hasDoubles(k)) + return this.curve._fixedNafMul(this, k); + else if (this.curve.endo) + return this.curve._endoWnafMulAdd([ this ], [ k ]); + else + return this.curve._wnafMul(this, k); +}; -/** - * Parses an escaped url query string into key-value pairs. - * @returns {Object.} - */ -function parseKeyValue(/**string*/keyValue) { - var obj = {}; - forEach((keyValue || '').split('&'), function(keyValue) { - var splitPoint, key, val; - if (keyValue) { - key = keyValue = keyValue.replace(/\+/g,'%20'); - splitPoint = keyValue.indexOf('='); - if (splitPoint !== -1) { - key = keyValue.substring(0, splitPoint); - val = keyValue.substring(splitPoint + 1); - } - key = tryDecodeURIComponent(key); - if (isDefined(key)) { - val = isDefined(val) ? tryDecodeURIComponent(val) : true; - if (!hasOwnProperty.call(obj, key)) { - obj[key] = val; - } else if (isArray(obj[key])) { - obj[key].push(val); - } else { - obj[key] = [obj[key],val]; - } - } - } - }); - return obj; -} +Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { + var points = [ this, p2 ]; + var coeffs = [ k1, k2 ]; + if (this.curve.endo) + return this.curve._endoWnafMulAdd(points, coeffs); + else + return this.curve._wnafMulAdd(1, points, coeffs, 2); +}; -function toKeyValue(obj) { - var parts = []; - forEach(obj, function(value, key) { - if (isArray(value)) { - forEach(value, function(arrayValue) { - parts.push(encodeUriQuery(key, true) + - (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true))); - }); - } else { - parts.push(encodeUriQuery(key, true) + - (value === true ? '' : '=' + encodeUriQuery(value, true))); - } - }); - return parts.length ? parts.join('&') : ''; -} +Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) { + var points = [ this, p2 ]; + var coeffs = [ k1, k2 ]; + if (this.curve.endo) + return this.curve._endoWnafMulAdd(points, coeffs, true); + else + return this.curve._wnafMulAdd(1, points, coeffs, 2, true); +}; +Point.prototype.eq = function eq(p) { + return this === p || + this.inf === p.inf && + (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); +}; -/** - * We need our custom method because encodeURIComponent is too aggressive and doesn't follow - * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path - * segments: - * segment = *pchar - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * pct-encoded = "%" HEXDIG HEXDIG - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ -function encodeUriSegment(val) { - return encodeUriQuery(val, true). - replace(/%26/gi, '&'). - replace(/%3D/gi, '='). - replace(/%2B/gi, '+'); -} +Point.prototype.neg = function neg(_precompute) { + if (this.inf) + return this; + var res = this.curve.point(this.x, this.y.redNeg()); + if (_precompute && this.precomputed) { + var pre = this.precomputed; + var negate = function(p) { + return p.neg(); + }; + res.precomputed = { + naf: pre.naf && { + wnd: pre.naf.wnd, + points: pre.naf.points.map(negate) + }, + doubles: pre.doubles && { + step: pre.doubles.step, + points: pre.doubles.points.map(negate) + } + }; + } + return res; +}; -/** - * This method is intended for encoding *key* or *value* parts of query component. We need a custom - * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be - * encoded per http://tools.ietf.org/html/rfc3986: - * query = *( pchar / "/" / "?" ) - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * pct-encoded = "%" HEXDIG HEXDIG - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ -function encodeUriQuery(val, pctEncodeSpaces) { - return encodeURIComponent(val). - replace(/%40/gi, '@'). - replace(/%3A/gi, ':'). - replace(/%24/g, '$'). - replace(/%2C/gi, ','). - replace(/%3B/gi, ';'). - replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); -} +Point.prototype.toJ = function toJ() { + if (this.inf) + return this.curve.jpoint(null, null, null); -var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-']; + var res = this.curve.jpoint(this.x, this.y, this.curve.one); + return res; +}; -function getNgAttribute(element, ngAttr) { - var attr, i, ii = ngAttrPrefixes.length; - for (i = 0; i < ii; ++i) { - attr = ngAttrPrefixes[i] + ngAttr; - if (isString(attr = element.getAttribute(attr))) { - return attr; - } +function JPoint(curve, x, y, z) { + Base.BasePoint.call(this, curve, 'jacobian'); + if (x === null && y === null && z === null) { + this.x = this.curve.one; + this.y = this.curve.one; + this.z = new BN(0); + } else { + this.x = new BN(x, 16); + this.y = new BN(y, 16); + this.z = new BN(z, 16); } - return null; + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); + + this.zOne = this.z === this.curve.one; } +inherits(JPoint, Base.BasePoint); -function allowAutoBootstrap(document) { - var script = document.currentScript; +ShortCurve.prototype.jpoint = function jpoint(x, y, z) { + return new JPoint(this, x, y, z); +}; - if (!script) { - // Support: IE 9-11 only - // IE does not have `document.currentScript` - return true; - } +JPoint.prototype.toP = function toP() { + if (this.isInfinity()) + return this.curve.point(null, null); - // If the `currentScript` property has been clobbered just return false, since this indicates a probable attack - if (!(script instanceof window.HTMLScriptElement || script instanceof window.SVGScriptElement)) { - return false; + var zinv = this.z.redInvm(); + var zinv2 = zinv.redSqr(); + var ax = this.x.redMul(zinv2); + var ay = this.y.redMul(zinv2).redMul(zinv); + + return this.curve.point(ax, ay); +}; + +JPoint.prototype.neg = function neg() { + return this.curve.jpoint(this.x, this.y.redNeg(), this.z); +}; + +JPoint.prototype.add = function add(p) { + // O + P = P + if (this.isInfinity()) + return p; + + // P + O = P + if (p.isInfinity()) + return this; + + // 12M + 4S + 7A + var pz2 = p.z.redSqr(); + var z2 = this.z.redSqr(); + var u1 = this.x.redMul(pz2); + var u2 = p.x.redMul(z2); + var s1 = this.y.redMul(pz2.redMul(p.z)); + var s2 = p.y.redMul(z2.redMul(this.z)); + + var h = u1.redSub(u2); + var r = s1.redSub(s2); + if (h.cmpn(0) === 0) { + if (r.cmpn(0) !== 0) + return this.curve.jpoint(null, null, null); + else + return this.dbl(); } - var attributes = script.attributes; - var srcs = [attributes.getNamedItem('src'), attributes.getNamedItem('href'), attributes.getNamedItem('xlink:href')]; + var h2 = h.redSqr(); + var h3 = h2.redMul(h); + var v = u1.redMul(h2); - return srcs.every(function(src) { - if (!src) { - return true; - } - if (!src.value) { - return false; - } + var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); + var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); + var nz = this.z.redMul(p.z).redMul(h); - var link = document.createElement('a'); - link.href = src.value; + return this.curve.jpoint(nx, ny, nz); +}; - if (document.location.origin === link.origin) { - // Same-origin resources are always allowed, even for non-whitelisted schemes. - return true; - } - // Disabled bootstrapping unless angular.js was loaded from a known scheme used on the web. - // This is to prevent angular.js bundled with browser extensions from being used to bypass the - // content security policy in web pages and other browser extensions. - switch (link.protocol) { - case 'http:': - case 'https:': - case 'ftp:': - case 'blob:': - case 'file:': - case 'data:': - return true; - default: - return false; - } - }); -} +JPoint.prototype.mixedAdd = function mixedAdd(p) { + // O + P = P + if (this.isInfinity()) + return p.toJ(); -// Cached as it has to run during loading so that document.currentScript is available. -var isAutoBootstrapAllowed = allowAutoBootstrap(window.document); + // P + O = P + if (p.isInfinity()) + return this; -/** - * @ngdoc directive - * @name ngApp - * @module ng - * - * @element ANY - * @param {angular.Module} ngApp an optional application - * {@link angular.module module} name to load. - * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be - * created in "strict-di" mode. This means that the application will fail to invoke functions which - * do not use explicit function annotation (and are thus unsuitable for minification), as described - * in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in - * tracking down the root of these bugs. - * - * @description - * - * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive - * designates the **root element** of the application and is typically placed near the root element - * of the page - e.g. on the `` or `` tags. - * - * There are a few things to keep in mind when using `ngApp`: - * - only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp` - * found in the document will be used to define the root element to auto-bootstrap as an - * application. To run multiple applications in an HTML document you must manually bootstrap them using - * {@link angular.bootstrap} instead. - * - AngularJS applications cannot be nested within each other. - * - Do not use a directive that uses {@link ng.$compile#transclusion transclusion} on the same element as `ngApp`. - * This includes directives such as {@link ng.ngIf `ngIf`}, {@link ng.ngInclude `ngInclude`} and - * {@link ngRoute.ngView `ngView`}. - * Doing this misplaces the app {@link ng.$rootElement `$rootElement`} and the app's {@link auto.$injector injector}, - * causing animations to stop working and making the injector inaccessible from outside the app. - * - * You can specify an **AngularJS module** to be used as the root module for the application. This - * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It - * should contain the application code needed or have dependencies on other modules that will - * contain the code. See {@link angular.module} for more information. - * - * In the example below if the `ngApp` directive were not placed on the `html` element then the - * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}` - * would not be resolved to `3`. - * - * @example - * - * ### Simple Usage - * - * `ngApp` is the easiest, and most common way to bootstrap an application. - * - - -
- I can add: {{a}} + {{b}} = {{ a+b }} -
-
- - angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) { - $scope.a = 1; - $scope.b = 2; - }); - -
- * - * @example - * - * ### With `ngStrictDi` - * - * Using `ngStrictDi`, you would see something like this: - * - - -
-
- I can add: {{a}} + {{b}} = {{ a+b }} + // 8M + 3S + 7A + var z2 = this.z.redSqr(); + var u1 = this.x; + var u2 = p.x.redMul(z2); + var s1 = this.y; + var s2 = p.y.redMul(z2).redMul(this.z); -

This renders because the controller does not fail to - instantiate, by using explicit annotation style (see - script.js for details) -

-
+ var h = u1.redSub(u2); + var r = s1.redSub(s2); + if (h.cmpn(0) === 0) { + if (r.cmpn(0) !== 0) + return this.curve.jpoint(null, null, null); + else + return this.dbl(); + } -
- Name:
- Hello, {{name}}! + var h2 = h.redSqr(); + var h3 = h2.redMul(h); + var v = u1.redMul(h2); -

This renders because the controller does not fail to - instantiate, by using explicit annotation style - (see script.js for details) -

-
+ var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); + var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); + var nz = this.z.redMul(h); -
- I can add: {{a}} + {{b}} = {{ a+b }} + return this.curve.jpoint(nx, ny, nz); +}; -

The controller could not be instantiated, due to relying - on automatic function annotations (which are disabled in - strict mode). As such, the content of this section is not - interpolated, and there should be an error in your web console. -

-
-
-
- - angular.module('ngAppStrictDemo', []) - // BadController will fail to instantiate, due to relying on automatic function annotation, - // rather than an explicit annotation - .controller('BadController', function($scope) { - $scope.a = 1; - $scope.b = 2; - }) - // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated, - // due to using explicit annotations using the array style and $inject property, respectively. - .controller('GoodController1', ['$scope', function($scope) { - $scope.a = 1; - $scope.b = 2; - }]) - .controller('GoodController2', GoodController2); - function GoodController2($scope) { - $scope.name = 'World'; - } - GoodController2.$inject = ['$scope']; - - - div[ng-controller] { - margin-bottom: 1em; - -webkit-border-radius: 4px; - border-radius: 4px; - border: 1px solid; - padding: .5em; - } - div[ng-controller^=Good] { - border-color: #d6e9c6; - background-color: #dff0d8; - color: #3c763d; - } - div[ng-controller^=Bad] { - border-color: #ebccd1; - background-color: #f2dede; - color: #a94442; - margin-bottom: 0; - } - -
- */ -function angularInit(element, bootstrap) { - var appElement, - module, - config = {}; - - // The element `element` has priority over any other element. - forEach(ngAttrPrefixes, function(prefix) { - var name = prefix + 'app'; - - if (!appElement && element.hasAttribute && element.hasAttribute(name)) { - appElement = element; - module = element.getAttribute(name); - } - }); - forEach(ngAttrPrefixes, function(prefix) { - var name = prefix + 'app'; - var candidate; +JPoint.prototype.dblp = function dblp(pow) { + if (pow === 0) + return this; + if (this.isInfinity()) + return this; + if (!pow) + return this.dbl(); - if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) { - appElement = candidate; - module = candidate.getAttribute(name); - } - }); - if (appElement) { - if (!isAutoBootstrapAllowed) { - try { - window.console.error('AngularJS: disabling automatic bootstrap. - * - * - * - * ``` - * - * @param {DOMElement} element DOM element which is the root of AngularJS application. - * @param {Array=} modules an array of modules to load into the application. - * Each item in the array should be the name of a predefined module or a (DI annotated) - * function that will be invoked by the injector as a `config` block. - * See: {@link angular.module modules} - * @param {Object=} config an object for defining configuration options for the application. The - * following keys are supported: - * - * * `strictDi` - disable automatic function annotation for the application. This is meant to - * assist in finding bugs which break minified code. Defaults to `false`. - * - * @returns {auto.$injector} Returns the newly created injector for this app. - */ -function bootstrap(element, modules, config) { - if (!isObject(config)) config = {}; - var defaultConfig = { - strictDi: false - }; - config = extend(defaultConfig, config); - var doBootstrap = function() { - element = jqLite(element); + // 1M + 2S + 1A + N * (4S + 5M + 8A) + // N = 1 => 6M + 6S + 9A + var a = this.curve.a; + var tinv = this.curve.tinv; - if (element.injector()) { - var tag = (element[0] === window.document) ? 'document' : startingTag(element); - // Encode angle brackets to prevent input from being sanitized to empty string #8683. - throw ngMinErr( - 'btstrpd', - 'App already bootstrapped with this element \'{0}\'', - tag.replace(//,'>')); - } + var jx = this.x; + var jy = this.y; + var jz = this.z; + var jz4 = jz.redSqr().redSqr(); - modules = modules || []; - modules.unshift(['$provide', function($provide) { - $provide.value('$rootElement', element); - }]); + // Reuse results + var jyd = jy.redAdd(jy); + for (var i = 0; i < pow; i++) { + var jx2 = jx.redSqr(); + var jyd2 = jyd.redSqr(); + var jyd4 = jyd2.redSqr(); + var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); - if (config.debugInfoEnabled) { - // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`. - modules.push(['$compileProvider', function($compileProvider) { - $compileProvider.debugInfoEnabled(true); - }]); - } + var t1 = jx.redMul(jyd2); + var nx = c.redSqr().redISub(t1.redAdd(t1)); + var t2 = t1.redISub(nx); + var dny = c.redMul(t2); + dny = dny.redIAdd(dny).redISub(jyd4); + var nz = jyd.redMul(jz); + if (i + 1 < pow) + jz4 = jz4.redMul(jyd4); - modules.unshift('ng'); - var injector = createInjector(modules, config.strictDi); - injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', - function bootstrapApply(scope, element, compile, injector) { - scope.$apply(function() { - element.data('$injector', injector); - compile(element)(scope); - }); - }] - ); - return injector; - }; + jx = nx; + jz = nz; + jyd = dny; + } - var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/; - var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/; + return this.curve.jpoint(jx, jyd.redMul(tinv), jz); +}; - if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) { - config.debugInfoEnabled = true; - window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, ''); - } +JPoint.prototype.dbl = function dbl() { + if (this.isInfinity()) + return this; - if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) { - return doBootstrap(); - } + if (this.curve.zeroA) + return this._zeroDbl(); + else if (this.curve.threeA) + return this._threeDbl(); + else + return this._dbl(); +}; - window.name = window.name.replace(NG_DEFER_BOOTSTRAP, ''); - angular.resumeBootstrap = function(extraModules) { - forEach(extraModules, function(module) { - modules.push(module); - }); - return doBootstrap(); - }; +JPoint.prototype._zeroDbl = function _zeroDbl() { + var nx; + var ny; + var nz; + // Z = 1 + if (this.zOne) { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html + // #doubling-mdbl-2007-bl + // 1M + 5S + 14A - if (isFunction(angular.resumeDeferredBootstrap)) { - angular.resumeDeferredBootstrap(); - } -} + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // S = 2 * ((X1 + YY)^2 - XX - YYYY) + var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + s = s.redIAdd(s); + // M = 3 * XX + a; a = 0 + var m = xx.redAdd(xx).redIAdd(xx); + // T = M ^ 2 - 2*S + var t = m.redSqr().redISub(s).redISub(s); -/** - * @ngdoc function - * @name angular.reloadWithDebugInfo - * @module ng - * @description - * Use this function to reload the current application with debug information turned on. - * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`. - * - * See {@link ng.$compileProvider#debugInfoEnabled} for more. - */ -function reloadWithDebugInfo() { - window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name; - window.location.reload(); -} + // 8 * YYYY + var yyyy8 = yyyy.redIAdd(yyyy); + yyyy8 = yyyy8.redIAdd(yyyy8); + yyyy8 = yyyy8.redIAdd(yyyy8); -/** - * @name angular.getTestability - * @module ng - * @description - * Get the testability service for the instance of AngularJS on the given - * element. - * @param {DOMElement} element DOM element which is the root of AngularJS application. - */ -function getTestability(rootElement) { - var injector = angular.element(rootElement).injector(); - if (!injector) { - throw ngMinErr('test', - 'no injector found for element argument to getTestability'); - } - return injector.get('$$testability'); -} + // X3 = T + nx = t; + // Y3 = M * (S - T) - 8 * YYYY + ny = m.redMul(s.redISub(t)).redISub(yyyy8); + // Z3 = 2*Y1 + nz = this.y.redAdd(this.y); + } else { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html + // #doubling-dbl-2009-l + // 2M + 5S + 13A -var SNAKE_CASE_REGEXP = /[A-Z]/g; -function snake_case(name, separator) { - separator = separator || '_'; - return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { - return (pos ? separator : '') + letter.toLowerCase(); - }); -} + // A = X1^2 + var a = this.x.redSqr(); + // B = Y1^2 + var b = this.y.redSqr(); + // C = B^2 + var c = b.redSqr(); + // D = 2 * ((X1 + B)^2 - A - C) + var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); + d = d.redIAdd(d); + // E = 3 * A + var e = a.redAdd(a).redIAdd(a); + // F = E^2 + var f = e.redSqr(); -var bindJQueryFired = false; -function bindJQuery() { - var originalCleanData; + // 8 * C + var c8 = c.redIAdd(c); + c8 = c8.redIAdd(c8); + c8 = c8.redIAdd(c8); - if (bindJQueryFired) { - return; + // X3 = F - 2 * D + nx = f.redISub(d).redISub(d); + // Y3 = E * (D - X3) - 8 * C + ny = e.redMul(d.redISub(nx)).redISub(c8); + // Z3 = 2 * Y1 * Z1 + nz = this.y.redMul(this.z); + nz = nz.redIAdd(nz); } - // bind to jQuery if present; - var jqName = jq(); - jQuery = isUndefined(jqName) ? window.jQuery : // use jQuery (if present) - !jqName ? undefined : // use jqLite - window[jqName]; // use jQuery specified by `ngJq` + return this.curve.jpoint(nx, ny, nz); +}; - // Use jQuery if it exists with proper functionality, otherwise default to us. - // AngularJS 1.2+ requires jQuery 1.7+ for on()/off() support. - // AngularJS 1.3+ technically requires at least jQuery 2.1+ but it may work with older - // versions. It will not work for sure with jQuery <1.7, though. - if (jQuery && jQuery.fn.on) { - jqLite = jQuery; - extend(jQuery.fn, { - scope: JQLitePrototype.scope, - isolateScope: JQLitePrototype.isolateScope, - controller: /** @type {?} */ (JQLitePrototype).controller, - injector: JQLitePrototype.injector, - inheritedData: JQLitePrototype.inheritedData - }); +JPoint.prototype._threeDbl = function _threeDbl() { + var nx; + var ny; + var nz; + // Z = 1 + if (this.zOne) { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html + // #doubling-mdbl-2007-bl + // 1M + 5S + 15A + + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // S = 2 * ((X1 + YY)^2 - XX - YYYY) + var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + s = s.redIAdd(s); + // M = 3 * XX + a + var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); + // T = M^2 - 2 * S + var t = m.redSqr().redISub(s).redISub(s); + // X3 = T + nx = t; + // Y3 = M * (S - T) - 8 * YYYY + var yyyy8 = yyyy.redIAdd(yyyy); + yyyy8 = yyyy8.redIAdd(yyyy8); + yyyy8 = yyyy8.redIAdd(yyyy8); + ny = m.redMul(s.redISub(t)).redISub(yyyy8); + // Z3 = 2 * Y1 + nz = this.y.redAdd(this.y); } else { - jqLite = JQLite; + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + // 3M + 5S + + // delta = Z1^2 + var delta = this.z.redSqr(); + // gamma = Y1^2 + var gamma = this.y.redSqr(); + // beta = X1 * gamma + var beta = this.x.redMul(gamma); + // alpha = 3 * (X1 - delta) * (X1 + delta) + var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); + alpha = alpha.redAdd(alpha).redIAdd(alpha); + // X3 = alpha^2 - 8 * beta + var beta4 = beta.redIAdd(beta); + beta4 = beta4.redIAdd(beta4); + var beta8 = beta4.redAdd(beta4); + nx = alpha.redSqr().redISub(beta8); + // Z3 = (Y1 + Z1)^2 - gamma - delta + nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); + // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 + var ggamma8 = gamma.redSqr(); + ggamma8 = ggamma8.redIAdd(ggamma8); + ggamma8 = ggamma8.redIAdd(ggamma8); + ggamma8 = ggamma8.redIAdd(ggamma8); + ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); } - // All nodes removed from the DOM via various jqLite/jQuery APIs like .remove() - // are passed through jqLite/jQuery.cleanData. Monkey-patch this method to fire - // the $destroy event on all removed nodes. - originalCleanData = jqLite.cleanData; - jqLite.cleanData = function(elems) { - var events; - for (var i = 0, elem; (elem = elems[i]) != null; i++) { - events = (jqLite._data(elem) || {}).events; - if (events && events.$destroy) { - jqLite(elem).triggerHandler('$destroy'); - } - } - originalCleanData(elems); - }; + return this.curve.jpoint(nx, ny, nz); +}; - angular.element = jqLite; +JPoint.prototype._dbl = function _dbl() { + var a = this.curve.a; - // Prevent double-proxying. - bindJQueryFired = true; -} + // 4M + 6S + 10A + var jx = this.x; + var jy = this.y; + var jz = this.z; + var jz4 = jz.redSqr().redSqr(); -/** - * throw error if the argument is falsy. - */ -function assertArg(arg, name, reason) { - if (!arg) { - throw ngMinErr('areq', 'Argument \'{0}\' is {1}', (name || '?'), (reason || 'required')); - } - return arg; -} + var jx2 = jx.redSqr(); + var jy2 = jy.redSqr(); -function assertArgFn(arg, name, acceptArrayAnnotation) { - if (acceptArrayAnnotation && isArray(arg)) { - arg = arg[arg.length - 1]; - } + var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); - assertArg(isFunction(arg), name, 'not a function, got ' + - (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg)); - return arg; -} + var jxd4 = jx.redAdd(jx); + jxd4 = jxd4.redIAdd(jxd4); + var t1 = jxd4.redMul(jy2); + var nx = c.redSqr().redISub(t1.redAdd(t1)); + var t2 = t1.redISub(nx); -/** - * throw error if the name given is hasOwnProperty - * @param {String} name the name to test - * @param {String} context the context in which the name is used, such as module or directive - */ -function assertNotHasOwnProperty(name, context) { - if (name === 'hasOwnProperty') { - throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); - } -} + var jyd8 = jy2.redSqr(); + jyd8 = jyd8.redIAdd(jyd8); + jyd8 = jyd8.redIAdd(jyd8); + jyd8 = jyd8.redIAdd(jyd8); + var ny = c.redMul(t2).redISub(jyd8); + var nz = jy.redAdd(jy).redMul(jz); -/** - * Return the value accessible from the object by path. Any undefined traversals are ignored - * @param {Object} obj starting object - * @param {String} path path to traverse - * @param {boolean} [bindFnToScope=true] - * @returns {Object} value as accessible by path - */ -//TODO(misko): this function needs to be removed -function getter(obj, path, bindFnToScope) { - if (!path) return obj; - var keys = path.split('.'); - var key; - var lastInstance = obj; - var len = keys.length; + return this.curve.jpoint(nx, ny, nz); +}; - for (var i = 0; i < len; i++) { - key = keys[i]; - if (obj) { - obj = (lastInstance = obj)[key]; - } - } - if (!bindFnToScope && isFunction(obj)) { - return bind(lastInstance, obj); - } - return obj; -} +JPoint.prototype.trpl = function trpl() { + if (!this.curve.zeroA) + return this.dbl().add(this); -/** - * Return the DOM siblings between the first and last node in the given array. - * @param {Array} array like object - * @returns {Array} the inputted object or a jqLite collection containing the nodes - */ -function getBlockNodes(nodes) { - // TODO(perf): update `nodes` instead of creating a new object? - var node = nodes[0]; - var endNode = nodes[nodes.length - 1]; - var blockNodes; + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl + // 5M + 10S + ... - for (var i = 1; node !== endNode && (node = node.nextSibling); i++) { - if (blockNodes || nodes[i] !== node) { - if (!blockNodes) { - blockNodes = jqLite(slice.call(nodes, 0, i)); - } - blockNodes.push(node); - } - } + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // ZZ = Z1^2 + var zz = this.z.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // M = 3 * XX + a * ZZ2; a = 0 + var m = xx.redAdd(xx).redIAdd(xx); + // MM = M^2 + var mm = m.redSqr(); + // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM + var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + e = e.redIAdd(e); + e = e.redAdd(e).redIAdd(e); + e = e.redISub(mm); + // EE = E^2 + var ee = e.redSqr(); + // T = 16*YYYY + var t = yyyy.redIAdd(yyyy); + t = t.redIAdd(t); + t = t.redIAdd(t); + t = t.redIAdd(t); + // U = (M + E)^2 - MM - EE - T + var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); + // X3 = 4 * (X1 * EE - 4 * YY * U) + var yyu4 = yy.redMul(u); + yyu4 = yyu4.redIAdd(yyu4); + yyu4 = yyu4.redIAdd(yyu4); + var nx = this.x.redMul(ee).redISub(yyu4); + nx = nx.redIAdd(nx); + nx = nx.redIAdd(nx); + // Y3 = 8 * Y1 * (U * (T - U) - E * EE) + var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); + ny = ny.redIAdd(ny); + ny = ny.redIAdd(ny); + ny = ny.redIAdd(ny); + // Z3 = (Z1 + E)^2 - ZZ - EE + var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); - return blockNodes || nodes; -} + return this.curve.jpoint(nx, ny, nz); +}; +JPoint.prototype.mul = function mul(k, kbase) { + k = new BN(k, kbase); -/** - * Creates a new object without a prototype. This object is useful for lookup without having to - * guard against prototypically inherited properties via hasOwnProperty. - * - * Related micro-benchmarks: - * - http://jsperf.com/object-create2 - * - http://jsperf.com/proto-map-lookup/2 - * - http://jsperf.com/for-in-vs-object-keys2 - * - * @returns {Object} - */ -function createMap() { - return Object.create(null); -} + return this.curve._wnafMul(this, k); +}; -function stringify(value) { - if (value == null) { // null || undefined - return ''; - } - switch (typeof value) { - case 'string': - break; - case 'number': - value = '' + value; - break; - default: - if (hasCustomToString(value) && !isArray(value) && !isDate(value)) { - value = value.toString(); - } else { - value = toJson(value); - } - } +JPoint.prototype.eq = function eq(p) { + if (p.type === 'affine') + return this.eq(p.toJ()); - return value; -} + if (this === p) + return true; -var NODE_TYPE_ELEMENT = 1; -var NODE_TYPE_ATTRIBUTE = 2; -var NODE_TYPE_TEXT = 3; -var NODE_TYPE_COMMENT = 8; -var NODE_TYPE_DOCUMENT = 9; -var NODE_TYPE_DOCUMENT_FRAGMENT = 11; + // x1 * z2^2 == x2 * z1^2 + var z2 = this.z.redSqr(); + var pz2 = p.z.redSqr(); + if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) + return false; -/** - * @ngdoc type - * @name angular.Module - * @module ng - * @description - * - * Interface for configuring AngularJS {@link angular.module modules}. - */ + // y1 * z2^3 == y2 * z1^3 + var z3 = z2.redMul(this.z); + var pz3 = pz2.redMul(p.z); + return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; +}; -function setupModuleLoader(window) { +JPoint.prototype.eqXToP = function eqXToP(x) { + var zs = this.z.redSqr(); + var rx = x.toRed(this.curve.red).redMul(zs); + if (this.x.cmp(rx) === 0) + return true; - var $injectorMinErr = minErr('$injector'); - var ngMinErr = minErr('ng'); + var xc = x.clone(); + var t = this.curve.redN.redMul(zs); + for (;;) { + xc.iadd(this.curve.n); + if (xc.cmp(this.curve.p) >= 0) + return false; - function ensure(obj, name, factory) { - return obj[name] || (obj[name] = factory()); + rx.redIAdd(t); + if (this.x.cmp(rx) === 0) + return true; } +}; - var angular = ensure(window, 'angular', Object); +JPoint.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; - // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap - angular.$$minErr = angular.$$minErr || minErr; +JPoint.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.z.cmpn(0) === 0; +}; - return ensure(angular, 'module', function() { - /** @type {Object.} */ - var modules = {}; +},{"../../elliptic":195,"../curve":198,"bn.js":181,"inherits":246}],201:[function(require,module,exports){ +'use strict'; - /** - * @ngdoc function - * @name angular.module - * @module ng - * @description - * - * The `angular.module` is a global place for creating, registering and retrieving AngularJS - * modules. - * All modules (AngularJS core or 3rd party) that should be available to an application must be - * registered using this mechanism. - * - * Passing one argument retrieves an existing {@link angular.Module}, - * whereas passing more than one argument creates a new {@link angular.Module} - * - * - * # Module - * - * A module is a collection of services, directives, controllers, filters, and configuration information. - * `angular.module` is used to configure the {@link auto.$injector $injector}. - * - * ```js - * // Create a new module - * var myModule = angular.module('myModule', []); - * - * // register a new service - * myModule.value('appName', 'MyCoolApp'); - * - * // configure existing services inside initialization blocks. - * myModule.config(['$locationProvider', function($locationProvider) { - * // Configure existing providers - * $locationProvider.hashPrefix('!'); - * }]); - * ``` - * - * Then you can create an injector and load your modules like this: - * - * ```js - * var injector = angular.injector(['ng', 'myModule']) - * ``` - * - * However it's more likely that you'll just use - * {@link ng.directive:ngApp ngApp} or - * {@link angular.bootstrap} to simplify this process for you. - * - * @param {!string} name The name of the module to create or retrieve. - * @param {!Array.=} requires If specified then new module is being created. If - * unspecified then the module is being retrieved for further configuration. - * @param {Function=} configFn Optional configuration function for the module. Same as - * {@link angular.Module#config Module#config()}. - * @returns {angular.Module} new module with the {@link angular.Module} api. - */ - return function module(name, requires, configFn) { +var curves = exports; - var info = {}; +var hash = require('hash.js'); +var elliptic = require('../elliptic'); - var assertNotHasOwnProperty = function(name, context) { - if (name === 'hasOwnProperty') { - throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); - } - }; +var assert = elliptic.utils.assert; - assertNotHasOwnProperty(name, 'module'); - if (requires && modules.hasOwnProperty(name)) { - modules[name] = null; - } - return ensure(modules, name, function() { - if (!requires) { - throw $injectorMinErr('nomod', 'Module \'{0}\' is not available! You either misspelled ' + - 'the module name or forgot to load it. If registering a module ensure that you ' + - 'specify the dependencies as the second argument.', name); - } +function PresetCurve(options) { + if (options.type === 'short') + this.curve = new elliptic.curve.short(options); + else if (options.type === 'edwards') + this.curve = new elliptic.curve.edwards(options); + else + this.curve = new elliptic.curve.mont(options); + this.g = this.curve.g; + this.n = this.curve.n; + this.hash = options.hash; - /** @type {!Array.>} */ - var invokeQueue = []; + assert(this.g.validate(), 'Invalid curve'); + assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); +} +curves.PresetCurve = PresetCurve; - /** @type {!Array.} */ - var configBlocks = []; +function defineCurve(name, options) { + Object.defineProperty(curves, name, { + configurable: true, + enumerable: true, + get: function() { + var curve = new PresetCurve(options); + Object.defineProperty(curves, name, { + configurable: true, + enumerable: true, + value: curve + }); + return curve; + } + }); +} - /** @type {!Array.} */ - var runBlocks = []; +defineCurve('p192', { + type: 'short', + prime: 'p192', + p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', + a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', + b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', + n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', + hash: hash.sha256, + gRed: false, + g: [ + '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', + '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' + ] +}); - var config = invokeLater('$injector', 'invoke', 'push', configBlocks); +defineCurve('p224', { + type: 'short', + prime: 'p224', + p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', + a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', + b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', + n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', + hash: hash.sha256, + gRed: false, + g: [ + 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', + 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' + ] +}); - /** @type {angular.Module} */ - var moduleInstance = { - // Private state - _invokeQueue: invokeQueue, - _configBlocks: configBlocks, - _runBlocks: runBlocks, +defineCurve('p256', { + type: 'short', + prime: null, + p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', + a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', + b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', + n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', + hash: hash.sha256, + gRed: false, + g: [ + '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', + '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' + ] +}); - /** - * @ngdoc method - * @name angular.Module#info - * @module ng - * - * @param {Object=} info Information about the module - * @returns {Object|Module} The current info object for this module if called as a getter, - * or `this` if called as a setter. - * - * @description - * Read and write custom information about this module. - * For example you could put the version of the module in here. - * - * ```js - * angular.module('myModule', []).info({ version: '1.0.0' }); - * ``` - * - * The version could then be read back out by accessing the module elsewhere: - * - * ``` - * var version = angular.module('myModule').info().version; - * ``` - * - * You can also retrieve this information during runtime via the - * {@link $injector#modules `$injector.modules`} property: - * - * ```js - * var version = $injector.modules['myModule'].info().version; - * ``` - */ - info: function(value) { - if (isDefined(value)) { - if (!isObject(value)) throw ngMinErr('aobj', 'Argument \'{0}\' must be an object', 'value'); - info = value; - return this; - } - return info; - }, +defineCurve('p384', { + type: 'short', + prime: null, + p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'fffffffe ffffffff 00000000 00000000 ffffffff', + a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'fffffffe ffffffff 00000000 00000000 fffffffc', + b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' + + '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef', + n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' + + 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973', + hash: hash.sha384, + gRed: false, + g: [ + 'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' + + '5502f25d bf55296c 3a545e38 72760ab7', + '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' + + '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f' + ] +}); - /** - * @ngdoc property - * @name angular.Module#requires - * @module ng - * - * @description - * Holds the list of modules which the injector will load before the current module is - * loaded. - */ - requires: requires, +defineCurve('p521', { + type: 'short', + prime: null, + p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff ffffffff ffffffff ffffffff', + a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff ffffffff ffffffff fffffffc', + b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' + + '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' + + '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00', + n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' + + 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' + + 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409', + hash: hash.sha512, + gRed: false, + g: [ + '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' + + '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' + + 'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66', + '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' + + '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' + + '3fad0761 353c7086 a272c240 88be9476 9fd16650' + ] +}); - /** - * @ngdoc property - * @name angular.Module#name - * @module ng - * - * @description - * Name of the module. - */ - name: name, +defineCurve('curve25519', { + type: 'mont', + prime: 'p25519', + p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', + a: '76d06', + b: '1', + n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', + hash: hash.sha256, + gRed: false, + g: [ + '9' + ] +}); +defineCurve('ed25519', { + type: 'edwards', + prime: 'p25519', + p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', + a: '-1', + c: '1', + // -121665 * (121666^(-1)) (mod P) + d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', + n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', + hash: hash.sha256, + gRed: false, + g: [ + '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', - /** - * @ngdoc method - * @name angular.Module#provider - * @module ng - * @param {string} name service name - * @param {Function} providerType Construction function for creating new instance of the - * service. - * @description - * See {@link auto.$provide#provider $provide.provider()}. - */ - provider: invokeLaterAndSetModuleName('$provide', 'provider'), + // 4/5 + '6666666666666666666666666666666666666666666666666666666666666658' + ] +}); - /** - * @ngdoc method - * @name angular.Module#factory - * @module ng - * @param {string} name service name - * @param {Function} providerFunction Function for creating new instance of the service. - * @description - * See {@link auto.$provide#factory $provide.factory()}. - */ - factory: invokeLaterAndSetModuleName('$provide', 'factory'), +var pre; +try { + pre = require('./precomputed/secp256k1'); +} catch (e) { + pre = undefined; +} - /** - * @ngdoc method - * @name angular.Module#service - * @module ng - * @param {string} name service name - * @param {Function} constructor A constructor function that will be instantiated. - * @description - * See {@link auto.$provide#service $provide.service()}. - */ - service: invokeLaterAndSetModuleName('$provide', 'service'), +defineCurve('secp256k1', { + type: 'short', + prime: 'k256', + p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', + a: '0', + b: '7', + n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', + h: '1', + hash: hash.sha256, - /** - * @ngdoc method - * @name angular.Module#value - * @module ng - * @param {string} name service name - * @param {*} object Service instance object. - * @description - * See {@link auto.$provide#value $provide.value()}. - */ - value: invokeLater('$provide', 'value'), - - /** - * @ngdoc method - * @name angular.Module#constant - * @module ng - * @param {string} name constant name - * @param {*} object Constant value. - * @description - * Because the constants are fixed, they get applied before other provide methods. - * See {@link auto.$provide#constant $provide.constant()}. - */ - constant: invokeLater('$provide', 'constant', 'unshift'), - - /** - * @ngdoc method - * @name angular.Module#decorator - * @module ng - * @param {string} name The name of the service to decorate. - * @param {Function} decorFn This function will be invoked when the service needs to be - * instantiated and should return the decorated service instance. - * @description - * See {@link auto.$provide#decorator $provide.decorator()}. - */ - decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks), - - /** - * @ngdoc method - * @name angular.Module#animation - * @module ng - * @param {string} name animation name - * @param {Function} animationFactory Factory function for creating new instance of an - * animation. - * @description - * - * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. - * - * - * Defines an animation hook that can be later used with - * {@link $animate $animate} service and directives that use this service. - * - * ```js - * module.animation('.animation-name', function($inject1, $inject2) { - * return { - * eventName : function(element, done) { - * //code to run the animation - * //once complete, then run done() - * return function cancellationFunction(element) { - * //code to cancel the animation - * } - * } - * } - * }) - * ``` - * - * See {@link ng.$animateProvider#register $animateProvider.register()} and - * {@link ngAnimate ngAnimate module} for more information. - */ - animation: invokeLaterAndSetModuleName('$animateProvider', 'register'), + // Precomputed endomorphism + beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', + lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', + basis: [ + { + a: '3086d221a7d46bcde86c90e49284eb15', + b: '-e4437ed6010e88286f547fa90abfe4c3' + }, + { + a: '114ca50f7a8e2f3f657c1108d9d44cfd8', + b: '3086d221a7d46bcde86c90e49284eb15' + } + ], - /** - * @ngdoc method - * @name angular.Module#filter - * @module ng - * @param {string} name Filter name - this must be a valid AngularJS expression identifier - * @param {Function} filterFactory Factory function for creating new instance of filter. - * @description - * See {@link ng.$filterProvider#register $filterProvider.register()}. - * - *
- * **Note:** Filter names must be valid AngularJS {@link expression} identifiers, such as `uppercase` or `orderBy`. - * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace - * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores - * (`myapp_subsection_filterx`). - *
- */ - filter: invokeLaterAndSetModuleName('$filterProvider', 'register'), + gRed: false, + g: [ + '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', + '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', + pre + ] +}); - /** - * @ngdoc method - * @name angular.Module#controller - * @module ng - * @param {string|Object} name Controller name, or an object map of controllers where the - * keys are the names and the values are the constructors. - * @param {Function} constructor Controller constructor function. - * @description - * See {@link ng.$controllerProvider#register $controllerProvider.register()}. - */ - controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'), +},{"../elliptic":195,"./precomputed/secp256k1":208,"hash.js":232}],202:[function(require,module,exports){ +'use strict'; - /** - * @ngdoc method - * @name angular.Module#directive - * @module ng - * @param {string|Object} name Directive name, or an object map of directives where the - * keys are the names and the values are the factories. - * @param {Function} directiveFactory Factory function for creating new instance of - * directives. - * @description - * See {@link ng.$compileProvider#directive $compileProvider.directive()}. - */ - directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'), +var BN = require('bn.js'); +var HmacDRBG = require('hmac-drbg'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; - /** - * @ngdoc method - * @name angular.Module#component - * @module ng - * @param {string|Object} name Name of the component in camelCase (i.e. `myComp` which will match ``), - * or an object map of components where the keys are the names and the values are the component definition objects. - * @param {Object} options Component definition object (a simplified - * {@link ng.$compile#directive-definition-object directive definition object}) - * - * @description - * See {@link ng.$compileProvider#component $compileProvider.component()}. - */ - component: invokeLaterAndSetModuleName('$compileProvider', 'component'), +var KeyPair = require('./key'); +var Signature = require('./signature'); - /** - * @ngdoc method - * @name angular.Module#config - * @module ng - * @param {Function} configFn Execute this function on module load. Useful for service - * configuration. - * @description - * Use this method to configure services by injecting their - * {@link angular.Module#provider `providers`}, e.g. for adding routes to the - * {@link ngRoute.$routeProvider $routeProvider}. - * - * Note that you can only inject {@link angular.Module#provider `providers`} and - * {@link angular.Module#constant `constants`} into this function. - * - * For more about how to configure services, see - * {@link providers#provider-recipe Provider Recipe}. - */ - config: config, +function EC(options) { + if (!(this instanceof EC)) + return new EC(options); - /** - * @ngdoc method - * @name angular.Module#run - * @module ng - * @param {Function} initializationFn Execute this function after injector creation. - * Useful for application initialization. - * @description - * Use this method to register work which should be performed when the injector is done - * loading all modules. - */ - run: function(block) { - runBlocks.push(block); - return this; - } - }; + // Shortcut `elliptic.ec(curve-name)` + if (typeof options === 'string') { + assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); - if (configFn) { - config(configFn); - } + options = elliptic.curves[options]; + } - return moduleInstance; + // Shortcut for `elliptic.ec(elliptic.curves.curveName)` + if (options instanceof elliptic.curves.PresetCurve) + options = { curve: options }; - /** - * @param {string} provider - * @param {string} method - * @param {String=} insertMethod - * @returns {angular.Module} - */ - function invokeLater(provider, method, insertMethod, queue) { - if (!queue) queue = invokeQueue; - return function() { - queue[insertMethod || 'push']([provider, method, arguments]); - return moduleInstance; - }; - } + this.curve = options.curve.curve; + this.n = this.curve.n; + this.nh = this.n.ushrn(1); + this.g = this.curve.g; - /** - * @param {string} provider - * @param {string} method - * @returns {angular.Module} - */ - function invokeLaterAndSetModuleName(provider, method, queue) { - if (!queue) queue = invokeQueue; - return function(recipeName, factoryFunction) { - if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name; - queue.push([provider, method, arguments]); - return moduleInstance; - }; - } - }); - }; - }); + // Point on curve + this.g = options.curve.g; + this.g.precompute(options.curve.n.bitLength() + 1); + // Hash for function for DRBG + this.hash = options.hash || options.curve.hash; } +module.exports = EC; -/* global shallowCopy: true */ +EC.prototype.keyPair = function keyPair(options) { + return new KeyPair(this, options); +}; -/** - * Creates a shallow copy of an object, an array or a primitive. - * - * Assumes that there are no proto properties for objects. - */ -function shallowCopy(src, dst) { - if (isArray(src)) { - dst = dst || []; +EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) { + return KeyPair.fromPrivate(this, priv, enc); +}; - for (var i = 0, ii = src.length; i < ii; i++) { - dst[i] = src[i]; - } - } else if (isObject(src)) { - dst = dst || {}; +EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) { + return KeyPair.fromPublic(this, pub, enc); +}; - for (var key in src) { - if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) { - dst[key] = src[key]; - } - } - } +EC.prototype.genKeyPair = function genKeyPair(options) { + if (!options) + options = {}; - return dst || src; -} + // Instantiate Hmac_DRBG + var drbg = new HmacDRBG({ + hash: this.hash, + pers: options.pers, + persEnc: options.persEnc || 'utf8', + entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), + entropyEnc: options.entropy && options.entropyEnc || 'utf8', + nonce: this.n.toArray() + }); -/* exported toDebugString */ + var bytes = this.n.byteLength(); + var ns2 = this.n.sub(new BN(2)); + do { + var priv = new BN(drbg.generate(bytes)); + if (priv.cmp(ns2) > 0) + continue; -function serializeObject(obj, maxDepth) { - var seen = []; + priv.iaddn(1); + return this.keyFromPrivate(priv); + } while (true); +}; - // There is no direct way to stringify object until reaching a specific depth - // and a very deep object can cause a performance issue, so we copy the object - // based on this specific depth and then stringify it. - if (isValidObjectMaxDepth(maxDepth)) { - // This file is also included in `angular-loader`, so `copy()` might not always be available in - // the closure. Therefore, it is lazily retrieved as `angular.copy()` when needed. - obj = angular.copy(obj, null, maxDepth); +EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { + var delta = msg.byteLength() * 8 - this.n.bitLength(); + if (delta > 0) + msg = msg.ushrn(delta); + if (!truncOnly && msg.cmp(this.n) >= 0) + return msg.sub(this.n); + else + return msg; +}; + +EC.prototype.sign = function sign(msg, key, enc, options) { + if (typeof enc === 'object') { + options = enc; + enc = null; } - return JSON.stringify(obj, function(key, val) { - val = toJsonReplacer(key, val); - if (isObject(val)) { + if (!options) + options = {}; - if (seen.indexOf(val) >= 0) return '...'; + key = this.keyFromPrivate(key, enc); + msg = this._truncateToN(new BN(msg, 16)); - seen.push(val); - } - return val; - }); -} + // Zero-extend key to provide enough entropy + var bytes = this.n.byteLength(); + var bkey = key.getPrivate().toArray('be', bytes); -function toDebugString(obj, maxDepth) { - if (typeof obj === 'function') { - return obj.toString().replace(/ \{[\s\S]*$/, ''); - } else if (isUndefined(obj)) { - return 'undefined'; - } else if (typeof obj !== 'string') { - return serializeObject(obj, maxDepth); - } - return obj; -} + // Zero-extend nonce to have the same byte size as N + var nonce = msg.toArray('be', bytes); -/* global angularModule: true, - version: true, + // Instantiate Hmac_DRBG + var drbg = new HmacDRBG({ + hash: this.hash, + entropy: bkey, + nonce: nonce, + pers: options.pers, + persEnc: options.persEnc || 'utf8' + }); - $CompileProvider, + // Number of bytes to generate + var ns1 = this.n.sub(new BN(1)); - htmlAnchorDirective, - inputDirective, - inputDirective, - formDirective, - scriptDirective, - selectDirective, - optionDirective, - ngBindDirective, - ngBindHtmlDirective, - ngBindTemplateDirective, - ngClassDirective, - ngClassEvenDirective, - ngClassOddDirective, - ngCloakDirective, - ngControllerDirective, - ngFormDirective, - ngHideDirective, - ngIfDirective, - ngIncludeDirective, - ngIncludeFillContentDirective, - ngInitDirective, - ngNonBindableDirective, - ngPluralizeDirective, - ngRefDirective, - ngRepeatDirective, - ngShowDirective, - ngStyleDirective, - ngSwitchDirective, - ngSwitchWhenDirective, - ngSwitchDefaultDirective, - ngOptionsDirective, - ngTranscludeDirective, - ngModelDirective, - ngListDirective, - ngChangeDirective, - patternDirective, - patternDirective, - requiredDirective, - requiredDirective, - minlengthDirective, - minlengthDirective, - maxlengthDirective, - maxlengthDirective, - ngValueDirective, - ngModelOptionsDirective, - ngAttributeAliasDirectives, - ngEventDirectives, + for (var iter = 0; true; iter++) { + var k = options.k ? + options.k(iter) : + new BN(drbg.generate(this.n.byteLength())); + k = this._truncateToN(k, true); + if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) + continue; - $AnchorScrollProvider, - $AnimateProvider, - $CoreAnimateCssProvider, - $$CoreAnimateJsProvider, - $$CoreAnimateQueueProvider, - $$AnimateRunnerFactoryProvider, - $$AnimateAsyncRunFactoryProvider, - $BrowserProvider, - $CacheFactoryProvider, - $ControllerProvider, - $DateProvider, - $DocumentProvider, - $$IsDocumentHiddenProvider, - $ExceptionHandlerProvider, - $FilterProvider, - $$ForceReflowProvider, - $InterpolateProvider, - $$IntervalFactoryProvider, - $IntervalProvider, - $HttpProvider, - $HttpParamSerializerProvider, - $HttpParamSerializerJQLikeProvider, - $HttpBackendProvider, - $xhrFactoryProvider, - $jsonpCallbacksProvider, - $LocationProvider, - $LogProvider, - $$MapProvider, - $ParseProvider, - $RootScopeProvider, - $QProvider, - $$QProvider, - $$SanitizeUriProvider, - $SceProvider, - $SceDelegateProvider, - $SnifferProvider, - $$TaskTrackerFactoryProvider, - $TemplateCacheProvider, - $TemplateRequestProvider, - $$TestabilityProvider, - $TimeoutProvider, - $$RAFProvider, - $WindowProvider, - $$jqLiteProvider, - $$CookieReaderProvider -*/ + var kp = this.g.mul(k); + if (kp.isInfinity()) + continue; + var kpX = kp.getX(); + var r = kpX.umod(this.n); + if (r.cmpn(0) === 0) + continue; -/** - * @ngdoc object - * @name angular.version - * @module ng - * @description - * An object that contains information about the current AngularJS version. - * - * This object has the following properties: - * - * - `full` – `{string}` – Full version string, such as "0.9.18". - * - `major` – `{number}` – Major version number, such as "0". - * - `minor` – `{number}` – Minor version number, such as "9". - * - `dot` – `{number}` – Dot version number, such as "18". - * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". - */ -var version = { - // These placeholder strings will be replaced by grunt's `build` task. - // They need to be double- or single-quoted. - full: '1.7.5', - major: 1, - minor: 7, - dot: 5, - codeName: 'anti-prettification' -}; + var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)); + s = s.umod(this.n); + if (s.cmpn(0) === 0) + continue; + var recoveryParam = (kp.getY().isOdd() ? 1 : 0) | + (kpX.cmp(r) !== 0 ? 2 : 0); -function publishExternalAPI(angular) { - extend(angular, { - 'errorHandlingConfig': errorHandlingConfig, - 'bootstrap': bootstrap, - 'copy': copy, - 'extend': extend, - 'merge': merge, - 'equals': equals, - 'element': jqLite, - 'forEach': forEach, - 'injector': createInjector, - 'noop': noop, - 'bind': bind, - 'toJson': toJson, - 'fromJson': fromJson, - 'identity': identity, - 'isUndefined': isUndefined, - 'isDefined': isDefined, - 'isString': isString, - 'isFunction': isFunction, - 'isObject': isObject, - 'isNumber': isNumber, - 'isElement': isElement, - 'isArray': isArray, - 'version': version, - 'isDate': isDate, - 'callbacks': {$$counter: 0}, - 'getTestability': getTestability, - 'reloadWithDebugInfo': reloadWithDebugInfo, - '$$minErr': minErr, - '$$csp': csp, - '$$encodeUriSegment': encodeUriSegment, - '$$encodeUriQuery': encodeUriQuery, - '$$lowercase': lowercase, - '$$stringify': stringify, - '$$uppercase': uppercase - }); + // Use complement of `s`, if it is > `n / 2` + if (options.canonical && s.cmp(this.nh) > 0) { + s = this.n.sub(s); + recoveryParam ^= 1; + } - angularModule = setupModuleLoader(window); + return new Signature({ r: r, s: s, recoveryParam: recoveryParam }); + } +}; - angularModule('ng', ['ngLocale'], ['$provide', - function ngModule($provide) { - // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it. - $provide.provider({ - $$sanitizeUri: $$SanitizeUriProvider - }); - $provide.provider('$compile', $CompileProvider). - directive({ - a: htmlAnchorDirective, - input: inputDirective, - textarea: inputDirective, - form: formDirective, - script: scriptDirective, - select: selectDirective, - option: optionDirective, - ngBind: ngBindDirective, - ngBindHtml: ngBindHtmlDirective, - ngBindTemplate: ngBindTemplateDirective, - ngClass: ngClassDirective, - ngClassEven: ngClassEvenDirective, - ngClassOdd: ngClassOddDirective, - ngCloak: ngCloakDirective, - ngController: ngControllerDirective, - ngForm: ngFormDirective, - ngHide: ngHideDirective, - ngIf: ngIfDirective, - ngInclude: ngIncludeDirective, - ngInit: ngInitDirective, - ngNonBindable: ngNonBindableDirective, - ngPluralize: ngPluralizeDirective, - ngRef: ngRefDirective, - ngRepeat: ngRepeatDirective, - ngShow: ngShowDirective, - ngStyle: ngStyleDirective, - ngSwitch: ngSwitchDirective, - ngSwitchWhen: ngSwitchWhenDirective, - ngSwitchDefault: ngSwitchDefaultDirective, - ngOptions: ngOptionsDirective, - ngTransclude: ngTranscludeDirective, - ngModel: ngModelDirective, - ngList: ngListDirective, - ngChange: ngChangeDirective, - pattern: patternDirective, - ngPattern: patternDirective, - required: requiredDirective, - ngRequired: requiredDirective, - minlength: minlengthDirective, - ngMinlength: minlengthDirective, - maxlength: maxlengthDirective, - ngMaxlength: maxlengthDirective, - ngValue: ngValueDirective, - ngModelOptions: ngModelOptionsDirective - }). - directive({ - ngInclude: ngIncludeFillContentDirective - }). - directive(ngAttributeAliasDirectives). - directive(ngEventDirectives); - $provide.provider({ - $anchorScroll: $AnchorScrollProvider, - $animate: $AnimateProvider, - $animateCss: $CoreAnimateCssProvider, - $$animateJs: $$CoreAnimateJsProvider, - $$animateQueue: $$CoreAnimateQueueProvider, - $$AnimateRunner: $$AnimateRunnerFactoryProvider, - $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider, - $browser: $BrowserProvider, - $cacheFactory: $CacheFactoryProvider, - $controller: $ControllerProvider, - $document: $DocumentProvider, - $$isDocumentHidden: $$IsDocumentHiddenProvider, - $exceptionHandler: $ExceptionHandlerProvider, - $filter: $FilterProvider, - $$forceReflow: $$ForceReflowProvider, - $interpolate: $InterpolateProvider, - $interval: $IntervalProvider, - $$intervalFactory: $$IntervalFactoryProvider, - $http: $HttpProvider, - $httpParamSerializer: $HttpParamSerializerProvider, - $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider, - $httpBackend: $HttpBackendProvider, - $xhrFactory: $xhrFactoryProvider, - $jsonpCallbacks: $jsonpCallbacksProvider, - $location: $LocationProvider, - $log: $LogProvider, - $parse: $ParseProvider, - $rootScope: $RootScopeProvider, - $q: $QProvider, - $$q: $$QProvider, - $sce: $SceProvider, - $sceDelegate: $SceDelegateProvider, - $sniffer: $SnifferProvider, - $$taskTrackerFactory: $$TaskTrackerFactoryProvider, - $templateCache: $TemplateCacheProvider, - $templateRequest: $TemplateRequestProvider, - $$testability: $$TestabilityProvider, - $timeout: $TimeoutProvider, - $window: $WindowProvider, - $$rAF: $$RAFProvider, - $$jqLite: $$jqLiteProvider, - $$Map: $$MapProvider, - $$cookieReader: $$CookieReaderProvider - }); - } - ]) - .info({ angularVersion: '1.7.5' }); -} +EC.prototype.verify = function verify(msg, signature, key, enc) { + msg = this._truncateToN(new BN(msg, 16)); + key = this.keyFromPublic(key, enc); + signature = new Signature(signature, 'hex'); -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Any commits to this file should be reviewed with security in mind. * - * Changes to this file can potentially create security vulnerabilities. * - * An approval from 2 Core members with history of modifying * - * this file is required. * - * * - * Does the change somehow allow for arbitrary javascript to be executed? * - * Or allows for someone to change the prototype of built-in objects? * - * Or gives undesired access to variables likes document or window? * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + // Perform primitive values validation + var r = signature.r; + var s = signature.s; + if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) + return false; + if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) + return false; -/* global - JQLitePrototype: true, - BOOLEAN_ATTR: true, - ALIASED_ATTR: true -*/ + // Validate signature + var sinv = s.invm(this.n); + var u1 = sinv.mul(msg).umod(this.n); + var u2 = sinv.mul(r).umod(this.n); -////////////////////////////////// -//JQLite -////////////////////////////////// + if (!this.curve._maxwellTrick) { + var p = this.g.mulAdd(u1, key.getPublic(), u2); + if (p.isInfinity()) + return false; -/** - * @ngdoc function - * @name angular.element - * @module ng - * @kind function - * - * @description - * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. - * - * If jQuery is available, `angular.element` is an alias for the - * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element` - * delegates to AngularJS's built-in subset of jQuery, called "jQuery lite" or **jqLite**. - * - * jqLite is a tiny, API-compatible subset of jQuery that allows - * AngularJS to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most - * commonly needed functionality with the goal of having a very small footprint. - * - * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the - * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a - * specific version of jQuery if multiple versions exist on the page. - * - *
**Note:** All element references in AngularJS are always wrapped with jQuery or - * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.
- * - *
**Note:** Keep in mind that this function will not find elements - * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)` - * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.
- * - * ## AngularJS's jqLite - * jqLite provides only the following jQuery methods: - * - * - [`addClass()`](http://api.jquery.com/addClass/) - Does not support a function as first argument - * - [`after()`](http://api.jquery.com/after/) - * - [`append()`](http://api.jquery.com/append/) - Contrary to jQuery, this doesn't clone elements - * so will not work correctly when invoked on a jqLite object containing more than one DOM node - * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters - * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData - * - [`children()`](http://api.jquery.com/children/) - Does not support selectors - * - [`clone()`](http://api.jquery.com/clone/) - * - [`contents()`](http://api.jquery.com/contents/) - * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. - * As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing. - * - [`data()`](http://api.jquery.com/data/) - * - [`detach()`](http://api.jquery.com/detach/) - * - [`empty()`](http://api.jquery.com/empty/) - * - [`eq()`](http://api.jquery.com/eq/) - * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name - * - [`hasClass()`](http://api.jquery.com/hasClass/) - * - [`html()`](http://api.jquery.com/html/) - * - [`next()`](http://api.jquery.com/next/) - Does not support selectors - * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData - * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter - * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors - * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors - * - [`prepend()`](http://api.jquery.com/prepend/) - * - [`prop()`](http://api.jquery.com/prop/) - * - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`) - * - [`remove()`](http://api.jquery.com/remove/) - * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes - * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument - * - [`removeData()`](http://api.jquery.com/removeData/) - * - [`replaceWith()`](http://api.jquery.com/replaceWith/) - * - [`text()`](http://api.jquery.com/text/) - * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument - * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers - * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter - * - [`val()`](http://api.jquery.com/val/) - * - [`wrap()`](http://api.jquery.com/wrap/) - * - * ## jQuery/jqLite Extras - * AngularJS also provides the following additional methods and events to both jQuery and jqLite: - * - * ### Events - * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event - * on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM - * element before it is removed. - * - * ### Methods - * - `controller(name)` - retrieves the controller of the current element or its parent. By default - * retrieves controller associated with the `ngController` directive. If `name` is provided as - * camelCase directive name, then the controller for this directive will be retrieved (e.g. - * `'ngModel'`). - * - `injector()` - retrieves the injector of the current element or its parent. - * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current - * element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to - * be enabled. - * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the - * current element. This getter should be used only on elements that contain a directive which starts a new isolate - * scope. Calling `scope()` on this element always returns the original non-isolate scope. - * Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled. - * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top - * parent element is reached. - * - * @knownIssue You cannot spy on `angular.element` if you are using Jasmine version 1.x. See - * https://github.com/angular/angular.js/issues/14251 for more information. - * - * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery. - * @returns {Object} jQuery object. - */ + return p.getX().umod(this.n).cmp(r) === 0; + } -JQLite.expando = 'ng339'; + // NOTE: Greg Maxwell's trick, inspired by: + // https://git.io/vad3K -var jqCache = JQLite.cache = {}, - jqId = 1; + var p = this.g.jmulAdd(u1, key.getPublic(), u2); + if (p.isInfinity()) + return false; -/* - * !!! This is an undocumented "private" function !!! - */ -JQLite._data = function(node) { - //jQuery always returns an object on cache miss - return this.cache[node[this.expando]] || {}; + // Compare `p.x` of Jacobian point with `r`, + // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the + // inverse of `p.z^2` + return p.eqXToP(r); }; -function jqNextId() { return ++jqId; } +EC.prototype.recoverPubKey = function(msg, signature, j, enc) { + assert((3 & j) === j, 'The recovery param is more than two bits'); + signature = new Signature(signature, enc); + var n = this.n; + var e = new BN(msg); + var r = signature.r; + var s = signature.s; -var DASH_LOWERCASE_REGEXP = /-([a-z])/g; -var MS_HACK_REGEXP = /^-ms-/; -var MOUSE_EVENT_MAP = { mouseleave: 'mouseout', mouseenter: 'mouseover' }; -var jqLiteMinErr = minErr('jqLite'); + // A set LSB signifies that the y-coordinate is odd + var isYOdd = j & 1; + var isSecondKey = j >> 1; + if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey) + throw new Error('Unable to find sencond key candinate'); -/** - * Converts kebab-case to camelCase. - * There is also a special case for the ms prefix starting with a lowercase letter. - * @param name Name to normalize - */ -function cssKebabToCamel(name) { - return kebabToCamel(name.replace(MS_HACK_REGEXP, 'ms-')); -} + // 1.1. Let x = r + jn. + if (isSecondKey) + r = this.curve.pointFromX(r.add(this.curve.n), isYOdd); + else + r = this.curve.pointFromX(r, isYOdd); -function fnCamelCaseReplace(all, letter) { - return letter.toUpperCase(); -} + var rInv = signature.r.invm(n); + var s1 = n.sub(e).mul(rInv).umod(n); + var s2 = s.mul(rInv).umod(n); -/** - * Converts kebab-case to camelCase. - * @param name Name to normalize - */ -function kebabToCamel(name) { - return name - .replace(DASH_LOWERCASE_REGEXP, fnCamelCaseReplace); -} + // 1.6.1 Compute Q = r^-1 (sR - eG) + // Q = r^-1 (sR + -eG) + return this.g.mulAdd(s1, r, s2); +}; -var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/; -var HTML_REGEXP = /<|&#?\w+;/; -var TAG_NAME_REGEXP = /<([\w:-]+)/; -var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi; +EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) { + signature = new Signature(signature, enc); + if (signature.recoveryParam !== null) + return signature.recoveryParam; -var wrapMap = { - 'option': [1, ''], + for (var i = 0; i < 4; i++) { + var Qprime; + try { + Qprime = this.recoverPubKey(e, signature, i); + } catch (e) { + continue; + } - 'thead': [1, '', '
'], - 'col': [2, '', '
'], - 'tr': [2, '', '
'], - 'td': [3, '', '
'], - '_default': [0, '', ''] + if (Qprime.eq(Q)) + return i; + } + throw new Error('Unable to find valid recovery factor'); }; -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - +},{"../../elliptic":195,"./key":203,"./signature":204,"bn.js":181,"hmac-drbg":244}],203:[function(require,module,exports){ +'use strict'; -function jqLiteIsTextNode(html) { - return !HTML_REGEXP.test(html); -} +var BN = require('bn.js'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; -function jqLiteAcceptsData(node) { - // The window object can accept data but has no nodeType - // Otherwise we are only interested in elements (1) and documents (9) - var nodeType = node.nodeType; - return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT; -} +function KeyPair(ec, options) { + this.ec = ec; + this.priv = null; + this.pub = null; -function jqLiteHasData(node) { - for (var key in jqCache[node.ng339]) { - return true; - } - return false; + // KeyPair(ec, { priv: ..., pub: ... }) + if (options.priv) + this._importPrivate(options.priv, options.privEnc); + if (options.pub) + this._importPublic(options.pub, options.pubEnc); } +module.exports = KeyPair; -function jqLiteBuildFragment(html, context) { - var tmp, tag, wrap, - fragment = context.createDocumentFragment(), - nodes = [], i; - - if (jqLiteIsTextNode(html)) { - // Convert non-html into a text node - nodes.push(context.createTextNode(html)); - } else { - // Convert html into DOM nodes - tmp = fragment.appendChild(context.createElement('div')); - tag = (TAG_NAME_REGEXP.exec(html) || ['', ''])[1].toLowerCase(); - wrap = wrapMap[tag] || wrapMap._default; - tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, '<$1>') + wrap[2]; - - // Descend through wrappers to the right content - i = wrap[0]; - while (i--) { - tmp = tmp.lastChild; - } +KeyPair.fromPublic = function fromPublic(ec, pub, enc) { + if (pub instanceof KeyPair) + return pub; - nodes = concat(nodes, tmp.childNodes); + return new KeyPair(ec, { + pub: pub, + pubEnc: enc + }); +}; - tmp = fragment.firstChild; - tmp.textContent = ''; - } +KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { + if (priv instanceof KeyPair) + return priv; - // Remove wrapper from fragment - fragment.textContent = ''; - fragment.innerHTML = ''; // Clear inner HTML - forEach(nodes, function(node) { - fragment.appendChild(node); + return new KeyPair(ec, { + priv: priv, + privEnc: enc }); +}; - return fragment; -} +KeyPair.prototype.validate = function validate() { + var pub = this.getPublic(); -function jqLiteParseHTML(html, context) { - context = context || window.document; - var parsed; + if (pub.isInfinity()) + return { result: false, reason: 'Invalid public key' }; + if (!pub.validate()) + return { result: false, reason: 'Public key is not a point' }; + if (!pub.mul(this.ec.curve.n).isInfinity()) + return { result: false, reason: 'Public key * N != O' }; - if ((parsed = SINGLE_TAG_REGEXP.exec(html))) { - return [context.createElement(parsed[1])]; - } + return { result: true, reason: null }; +}; - if ((parsed = jqLiteBuildFragment(html, context))) { - return parsed.childNodes; +KeyPair.prototype.getPublic = function getPublic(compact, enc) { + // compact is optional argument + if (typeof compact === 'string') { + enc = compact; + compact = null; } - return []; -} + if (!this.pub) + this.pub = this.ec.g.mul(this.priv); -function jqLiteWrapNode(node, wrapper) { - var parent = node.parentNode; + if (!enc) + return this.pub; - if (parent) { - parent.replaceChild(wrapper, node); - } + return this.pub.encode(enc, compact); +}; - wrapper.appendChild(node); -} +KeyPair.prototype.getPrivate = function getPrivate(enc) { + if (enc === 'hex') + return this.priv.toString(16, 2); + else + return this.priv; +}; +KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { + this.priv = new BN(key, enc || 16); -// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259. -var jqLiteContains = window.Node.prototype.contains || /** @this */ function(arg) { - // eslint-disable-next-line no-bitwise - return !!(this.compareDocumentPosition(arg) & 16); + // Ensure that the priv won't be bigger than n, otherwise we may fail + // in fixed multiplication method + this.priv = this.priv.umod(this.ec.curve.n); }; -///////////////////////////////////////////// -function JQLite(element) { - if (element instanceof JQLite) { - return element; +KeyPair.prototype._importPublic = function _importPublic(key, enc) { + if (key.x || key.y) { + // Montgomery points only have an `x` coordinate. + // Weierstrass/Edwards points on the other hand have both `x` and + // `y` coordinates. + if (this.ec.curve.type === 'mont') { + assert(key.x, 'Need x coordinate'); + } else if (this.ec.curve.type === 'short' || + this.ec.curve.type === 'edwards') { + assert(key.x && key.y, 'Need both x and y coordinate'); + } + this.pub = this.ec.curve.point(key.x, key.y); + return; } + this.pub = this.ec.curve.decodePoint(key, enc); +}; - var argIsString; +// ECDH +KeyPair.prototype.derive = function derive(pub) { + return pub.mul(this.priv).getX(); +}; - if (isString(element)) { - element = trim(element); - argIsString = true; - } - if (!(this instanceof JQLite)) { - if (argIsString && element.charAt(0) !== '<') { - throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element'); - } - return new JQLite(element); - } - - if (argIsString) { - jqLiteAddNodes(this, jqLiteParseHTML(element)); - } else if (isFunction(element)) { - jqLiteReady(element); - } else { - jqLiteAddNodes(this, element); - } -} +// ECDSA +KeyPair.prototype.sign = function sign(msg, enc, options) { + return this.ec.sign(msg, this, enc, options); +}; -function jqLiteClone(element) { - return element.cloneNode(true); -} +KeyPair.prototype.verify = function verify(msg, signature) { + return this.ec.verify(msg, signature, this); +}; -function jqLiteDealoc(element, onlyDescendants) { - if (!onlyDescendants && jqLiteAcceptsData(element)) jqLite.cleanData([element]); +KeyPair.prototype.inspect = function inspect() { + return ''; +}; - if (element.querySelectorAll) { - jqLite.cleanData(element.querySelectorAll('*')); - } -} +},{"../../elliptic":195,"bn.js":181}],204:[function(require,module,exports){ +'use strict'; -function isEmptyObject(obj) { - var name; +var BN = require('bn.js'); - for (name in obj) { - return false; - } - return true; -} +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; -function removeIfEmptyData(element) { - var expandoId = element.ng339; - var expandoStore = expandoId && jqCache[expandoId]; +function Signature(options, enc) { + if (options instanceof Signature) + return options; - var events = expandoStore && expandoStore.events; - var data = expandoStore && expandoStore.data; + if (this._importDER(options, enc)) + return; - if ((!data || isEmptyObject(data)) && (!events || isEmptyObject(events))) { - delete jqCache[expandoId]; - element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it - } + assert(options.r && options.s, 'Signature without r or s'); + this.r = new BN(options.r, 16); + this.s = new BN(options.s, 16); + if (options.recoveryParam === undefined) + this.recoveryParam = null; + else + this.recoveryParam = options.recoveryParam; } +module.exports = Signature; -function jqLiteOff(element, type, fn, unsupported) { - if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument'); - - var expandoStore = jqLiteExpandoStore(element); - var events = expandoStore && expandoStore.events; - var handle = expandoStore && expandoStore.handle; - - if (!handle) return; //no listeners registered - - if (!type) { - for (type in events) { - if (type !== '$destroy') { - element.removeEventListener(type, handle); - } - delete events[type]; - } - } else { - - var removeHandler = function(type) { - var listenerFns = events[type]; - if (isDefined(fn)) { - arrayRemove(listenerFns || [], fn); - } - if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) { - element.removeEventListener(type, handle); - delete events[type]; - } - }; - - forEach(type.split(' '), function(type) { - removeHandler(type); - if (MOUSE_EVENT_MAP[type]) { - removeHandler(MOUSE_EVENT_MAP[type]); - } - }); - } - - removeIfEmptyData(element); +function Position() { + this.place = 0; } -function jqLiteRemoveData(element, name) { - var expandoId = element.ng339; - var expandoStore = expandoId && jqCache[expandoId]; - - if (expandoStore) { - if (name) { - delete expandoStore.data[name]; - } else { - expandoStore.data = {}; - } - - removeIfEmptyData(element); +function getLength(buf, p) { + var initial = buf[p.place++]; + if (!(initial & 0x80)) { + return initial; } -} - - -function jqLiteExpandoStore(element, createIfNecessary) { - var expandoId = element.ng339, - expandoStore = expandoId && jqCache[expandoId]; - - if (createIfNecessary && !expandoStore) { - element.ng339 = expandoId = jqNextId(); - expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined}; + var octetLen = initial & 0xf; + var val = 0; + for (var i = 0, off = p.place; i < octetLen; i++, off++) { + val <<= 8; + val |= buf[off]; } - - return expandoStore; + p.place = off; + return val; } - -function jqLiteData(element, key, value) { - if (jqLiteAcceptsData(element)) { - var prop; - - var isSimpleSetter = isDefined(value); - var isSimpleGetter = !isSimpleSetter && key && !isObject(key); - var massGetter = !key; - var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter); - var data = expandoStore && expandoStore.data; - - if (isSimpleSetter) { // data('key', value) - data[kebabToCamel(key)] = value; - } else { - if (massGetter) { // data() - return data; - } else { - if (isSimpleGetter) { // data('key') - // don't force creation of expandoStore if it doesn't exist yet - return data && data[kebabToCamel(key)]; - } else { // mass-setter: data({key1: val1, key2: val2}) - for (prop in key) { - data[kebabToCamel(prop)] = key[prop]; - } - } - } - } +function rmPadding(buf) { + var i = 0; + var len = buf.length - 1; + while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) { + i++; } -} - -function jqLiteHasClass(element, selector) { - if (!element.getAttribute) return false; - return ((' ' + (element.getAttribute('class') || '') + ' ').replace(/[\n\t]/g, ' '). - indexOf(' ' + selector + ' ') > -1); -} - -function jqLiteRemoveClass(element, cssClasses) { - if (cssClasses && element.setAttribute) { - var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') - .replace(/[\n\t]/g, ' '); - var newClasses = existingClasses; - - forEach(cssClasses.split(' '), function(cssClass) { - cssClass = trim(cssClass); - newClasses = newClasses.replace(' ' + cssClass + ' ', ' '); - }); - - if (newClasses !== existingClasses) { - element.setAttribute('class', trim(newClasses)); - } + if (i === 0) { + return buf; } + return buf.slice(i); } -function jqLiteAddClass(element, cssClasses) { - if (cssClasses && element.setAttribute) { - var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') - .replace(/[\n\t]/g, ' '); - var newClasses = existingClasses; - - forEach(cssClasses.split(' '), function(cssClass) { - cssClass = trim(cssClass); - if (newClasses.indexOf(' ' + cssClass + ' ') === -1) { - newClasses += cssClass + ' '; - } - }); - - if (newClasses !== existingClasses) { - element.setAttribute('class', trim(newClasses)); - } +Signature.prototype._importDER = function _importDER(data, enc) { + data = utils.toArray(data, enc); + var p = new Position(); + if (data[p.place++] !== 0x30) { + return false; } -} - - -function jqLiteAddNodes(root, elements) { - // THIS CODE IS VERY HOT. Don't make changes without benchmarking. - - if (elements) { - - // if a Node (the most common case) - if (elements.nodeType) { - root[root.length++] = elements; - } else { - var length = elements.length; - - // if an Array or NodeList and not a Window - if (typeof length === 'number' && elements.window !== elements) { - if (length) { - for (var i = 0; i < length; i++) { - root[root.length++] = elements[i]; - } - } - } else { - root[root.length++] = elements; - } - } + var len = getLength(data, p); + if ((len + p.place) !== data.length) { + return false; } -} - - -function jqLiteController(element, name) { - return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller'); -} - -function jqLiteInheritedData(element, name, value) { - // if element is the document object work with the html element instead - // this makes $(document).scope() possible - if (element.nodeType === NODE_TYPE_DOCUMENT) { - element = element.documentElement; + if (data[p.place++] !== 0x02) { + return false; } - var names = isArray(name) ? name : [name]; - - while (element) { - for (var i = 0, ii = names.length; i < ii; i++) { - if (isDefined(value = jqLite.data(element, names[i]))) return value; - } - - // If dealing with a document fragment node with a host element, and no parent, use the host - // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM - // to lookup parent controllers. - element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host); + var rlen = getLength(data, p); + var r = data.slice(p.place, rlen + p.place); + p.place += rlen; + if (data[p.place++] !== 0x02) { + return false; } -} - -function jqLiteEmpty(element) { - jqLiteDealoc(element, true); - while (element.firstChild) { - element.removeChild(element.firstChild); + var slen = getLength(data, p); + if (data.length !== slen + p.place) { + return false; } -} - -function jqLiteRemove(element, keepData) { - if (!keepData) jqLiteDealoc(element); - var parent = element.parentNode; - if (parent) parent.removeChild(element); -} - - -function jqLiteDocumentLoaded(action, win) { - win = win || window; - if (win.document.readyState === 'complete') { - // Force the action to be run async for consistent behavior - // from the action's point of view - // i.e. it will definitely not be in a $apply - win.setTimeout(action); - } else { - // No need to unbind this handler as load is only ever called once - jqLite(win).on('load', action); + var s = data.slice(p.place, slen + p.place); + if (r[0] === 0 && (r[1] & 0x80)) { + r = r.slice(1); } -} - -function jqLiteReady(fn) { - function trigger() { - window.document.removeEventListener('DOMContentLoaded', trigger); - window.removeEventListener('load', trigger); - fn(); + if (s[0] === 0 && (s[1] & 0x80)) { + s = s.slice(1); } - // check if document is already loaded - if (window.document.readyState === 'complete') { - window.setTimeout(fn); - } else { - // We can not use jqLite since we are not done loading and jQuery could be loaded later. + this.r = new BN(r); + this.s = new BN(s); + this.recoveryParam = null; - // Works for modern browsers and IE9 - window.document.addEventListener('DOMContentLoaded', trigger); + return true; +}; - // Fallback to window.onload for others - window.addEventListener('load', trigger); +function constructLength(arr, len) { + if (len < 0x80) { + arr.push(len); + return; + } + var octets = 1 + (Math.log(len) / Math.LN2 >>> 3); + arr.push(octets | 0x80); + while (--octets) { + arr.push((len >>> (octets << 3)) & 0xff); } + arr.push(len); } -////////////////////////////////////////// -// Functions which are declared directly. -////////////////////////////////////////// -var JQLitePrototype = JQLite.prototype = { - ready: jqLiteReady, - toString: function() { - var value = []; - forEach(this, function(e) { value.push('' + e);}); - return '[' + value.join(', ') + ']'; - }, +Signature.prototype.toDER = function toDER(enc) { + var r = this.r.toArray(); + var s = this.s.toArray(); - eq: function(index) { - return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]); - }, + // Pad values + if (r[0] & 0x80) + r = [ 0 ].concat(r); + // Pad values + if (s[0] & 0x80) + s = [ 0 ].concat(s); - length: 0, - push: push, - sort: [].sort, - splice: [].splice -}; + r = rmPadding(r); + s = rmPadding(s); -////////////////////////////////////////// -// Functions iterating getter/setters. -// these functions return self on setter and -// value on get. -////////////////////////////////////////// -var BOOLEAN_ATTR = {}; -forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) { - BOOLEAN_ATTR[lowercase(value)] = value; -}); -var BOOLEAN_ELEMENTS = {}; -forEach('input,select,option,textarea,button,form,details'.split(','), function(value) { - BOOLEAN_ELEMENTS[value] = true; -}); -var ALIASED_ATTR = { - 'ngMinlength': 'minlength', - 'ngMaxlength': 'maxlength', - 'ngMin': 'min', - 'ngMax': 'max', - 'ngPattern': 'pattern', - 'ngStep': 'step' + while (!s[0] && !(s[1] & 0x80)) { + s = s.slice(1); + } + var arr = [ 0x02 ]; + constructLength(arr, r.length); + arr = arr.concat(r); + arr.push(0x02); + constructLength(arr, s.length); + var backHalf = arr.concat(s); + var res = [ 0x30 ]; + constructLength(res, backHalf.length); + res = res.concat(backHalf); + return utils.encode(res, enc); }; -function getBooleanAttrName(element, name) { - // check dom last since we will most likely fail on name - var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()]; +},{"../../elliptic":195,"bn.js":181}],205:[function(require,module,exports){ +'use strict'; - // booleanAttr is here twice to minimize DOM access - return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr; -} +var hash = require('hash.js'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; +var parseBytes = utils.parseBytes; +var KeyPair = require('./key'); +var Signature = require('./signature'); -function getAliasedAttrName(name) { - return ALIASED_ATTR[name]; -} +function EDDSA(curve) { + assert(curve === 'ed25519', 'only tested with ed25519 so far'); -forEach({ - data: jqLiteData, - removeData: jqLiteRemoveData, - hasData: jqLiteHasData, - cleanData: function jqLiteCleanData(nodes) { - for (var i = 0, ii = nodes.length; i < ii; i++) { - jqLiteRemoveData(nodes[i]); - jqLiteOff(nodes[i]); - } - } -}, function(fn, name) { - JQLite[name] = fn; -}); + if (!(this instanceof EDDSA)) + return new EDDSA(curve); -forEach({ - data: jqLiteData, - inheritedData: jqLiteInheritedData, + var curve = elliptic.curves[curve].curve; + this.curve = curve; + this.g = curve.g; + this.g.precompute(curve.n.bitLength() + 1); - scope: function(element) { - // Can't use jqLiteData here directly so we stay compatible with jQuery! - return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); - }, + this.pointClass = curve.point().constructor; + this.encodingLength = Math.ceil(curve.n.bitLength() / 8); + this.hash = hash.sha512; +} - isolateScope: function(element) { - // Can't use jqLiteData here directly so we stay compatible with jQuery! - return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate'); - }, +module.exports = EDDSA; - controller: jqLiteController, +/** +* @param {Array|String} message - message bytes +* @param {Array|String|KeyPair} secret - secret bytes or a keypair +* @returns {Signature} - signature +*/ +EDDSA.prototype.sign = function sign(message, secret) { + message = parseBytes(message); + var key = this.keyFromSecret(secret); + var r = this.hashInt(key.messagePrefix(), message); + var R = this.g.mul(r); + var Rencoded = this.encodePoint(R); + var s_ = this.hashInt(Rencoded, key.pubBytes(), message) + .mul(key.priv()); + var S = r.add(s_).umod(this.curve.n); + return this.makeSignature({ R: R, S: S, Rencoded: Rencoded }); +}; - injector: function(element) { - return jqLiteInheritedData(element, '$injector'); - }, +/** +* @param {Array} message - message bytes +* @param {Array|String|Signature} sig - sig bytes +* @param {Array|String|Point|KeyPair} pub - public key +* @returns {Boolean} - true if public key matches sig of message +*/ +EDDSA.prototype.verify = function verify(message, sig, pub) { + message = parseBytes(message); + sig = this.makeSignature(sig); + var key = this.keyFromPublic(pub); + var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message); + var SG = this.g.mul(sig.S()); + var RplusAh = sig.R().add(key.pub().mul(h)); + return RplusAh.eq(SG); +}; - removeAttr: function(element, name) { - element.removeAttribute(name); - }, +EDDSA.prototype.hashInt = function hashInt() { + var hash = this.hash(); + for (var i = 0; i < arguments.length; i++) + hash.update(arguments[i]); + return utils.intFromLE(hash.digest()).umod(this.curve.n); +}; - hasClass: jqLiteHasClass, +EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) { + return KeyPair.fromPublic(this, pub); +}; - css: function(element, name, value) { - name = cssKebabToCamel(name); +EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) { + return KeyPair.fromSecret(this, secret); +}; - if (isDefined(value)) { - element.style[name] = value; - } else { - return element.style[name]; - } - }, +EDDSA.prototype.makeSignature = function makeSignature(sig) { + if (sig instanceof Signature) + return sig; + return new Signature(this, sig); +}; - attr: function(element, name, value) { - var ret; - var nodeType = element.nodeType; - if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT || - !element.getAttribute) { - return; - } +/** +* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2 +* +* EDDSA defines methods for encoding and decoding points and integers. These are +* helper convenience methods, that pass along to utility functions implied +* parameters. +* +*/ +EDDSA.prototype.encodePoint = function encodePoint(point) { + var enc = point.getY().toArray('le', this.encodingLength); + enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0; + return enc; +}; - var lowercasedName = lowercase(name); - var isBooleanAttr = BOOLEAN_ATTR[lowercasedName]; +EDDSA.prototype.decodePoint = function decodePoint(bytes) { + bytes = utils.parseBytes(bytes); - if (isDefined(value)) { - // setter + var lastIx = bytes.length - 1; + var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80); + var xIsOdd = (bytes[lastIx] & 0x80) !== 0; - if (value === null || (value === false && isBooleanAttr)) { - element.removeAttribute(name); - } else { - element.setAttribute(name, isBooleanAttr ? lowercasedName : value); - } - } else { - // getter + var y = utils.intFromLE(normed); + return this.curve.pointFromY(y, xIsOdd); +}; - ret = element.getAttribute(name); +EDDSA.prototype.encodeInt = function encodeInt(num) { + return num.toArray('le', this.encodingLength); +}; - if (isBooleanAttr && ret !== null) { - ret = lowercasedName; - } - // Normalize non-existing attributes to undefined (as jQuery). - return ret === null ? undefined : ret; - } - }, +EDDSA.prototype.decodeInt = function decodeInt(bytes) { + return utils.intFromLE(bytes); +}; - prop: function(element, name, value) { - if (isDefined(value)) { - element[name] = value; - } else { - return element[name]; - } - }, +EDDSA.prototype.isPoint = function isPoint(val) { + return val instanceof this.pointClass; +}; - text: (function() { - getText.$dv = ''; - return getText; +},{"../../elliptic":195,"./key":206,"./signature":207,"hash.js":232}],206:[function(require,module,exports){ +'use strict'; - function getText(element, value) { - if (isUndefined(value)) { - var nodeType = element.nodeType; - return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : ''; - } - element.textContent = value; - } - })(), +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; +var parseBytes = utils.parseBytes; +var cachedProperty = utils.cachedProperty; - val: function(element, value) { - if (isUndefined(value)) { - if (element.multiple && nodeName_(element) === 'select') { - var result = []; - forEach(element.options, function(option) { - if (option.selected) { - result.push(option.value || option.text); - } - }); - return result; - } - return element.value; - } - element.value = value; - }, +/** +* @param {EDDSA} eddsa - instance +* @param {Object} params - public/private key parameters +* +* @param {Array} [params.secret] - secret seed bytes +* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms) +* @param {Array} [params.pub] - public key point encoded as bytes +* +*/ +function KeyPair(eddsa, params) { + this.eddsa = eddsa; + this._secret = parseBytes(params.secret); + if (eddsa.isPoint(params.pub)) + this._pub = params.pub; + else + this._pubBytes = parseBytes(params.pub); +} - html: function(element, value) { - if (isUndefined(value)) { - return element.innerHTML; - } - jqLiteDealoc(element, true); - element.innerHTML = value; - }, +KeyPair.fromPublic = function fromPublic(eddsa, pub) { + if (pub instanceof KeyPair) + return pub; + return new KeyPair(eddsa, { pub: pub }); +}; - empty: jqLiteEmpty -}, function(fn, name) { - /** - * Properties: writes return selection, reads return first value - */ - JQLite.prototype[name] = function(arg1, arg2) { - var i, key; - var nodeCount = this.length; +KeyPair.fromSecret = function fromSecret(eddsa, secret) { + if (secret instanceof KeyPair) + return secret; + return new KeyPair(eddsa, { secret: secret }); +}; - // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it - // in a way that survives minification. - // jqLiteEmpty takes no arguments but is a setter. - if (fn !== jqLiteEmpty && - (isUndefined((fn.length === 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) { - if (isObject(arg1)) { +KeyPair.prototype.secret = function secret() { + return this._secret; +}; - // we are a write, but the object properties are the key/values - for (i = 0; i < nodeCount; i++) { - if (fn === jqLiteData) { - // data() takes the whole object in jQuery - fn(this[i], arg1); - } else { - for (key in arg1) { - fn(this[i], key, arg1[key]); - } - } - } - // return self for chaining - return this; - } else { - // we are a read, so read the first child. - // TODO: do we still need this? - var value = fn.$dv; - // Only if we have $dv do we iterate over all, otherwise it is just the first element. - var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount; - for (var j = 0; j < jj; j++) { - var nodeValue = fn(this[j], arg1, arg2); - value = value ? value + nodeValue : nodeValue; - } - return value; - } - } else { - // we are a write, so apply to all children - for (i = 0; i < nodeCount; i++) { - fn(this[i], arg1, arg2); - } - // return self for chaining - return this; - } - }; +cachedProperty(KeyPair, 'pubBytes', function pubBytes() { + return this.eddsa.encodePoint(this.pub()); }); -function createEventHandler(element, events) { - var eventHandler = function(event, type) { - // jQuery specific api - event.isDefaultPrevented = function() { - return event.defaultPrevented; - }; - - var eventFns = events[type || event.type]; - var eventFnsLength = eventFns ? eventFns.length : 0; - - if (!eventFnsLength) return; - - if (isUndefined(event.immediatePropagationStopped)) { - var originalStopImmediatePropagation = event.stopImmediatePropagation; - event.stopImmediatePropagation = function() { - event.immediatePropagationStopped = true; - - if (event.stopPropagation) { - event.stopPropagation(); - } - - if (originalStopImmediatePropagation) { - originalStopImmediatePropagation.call(event); - } - }; - } +cachedProperty(KeyPair, 'pub', function pub() { + if (this._pubBytes) + return this.eddsa.decodePoint(this._pubBytes); + return this.eddsa.g.mul(this.priv()); +}); - event.isImmediatePropagationStopped = function() { - return event.immediatePropagationStopped === true; - }; +cachedProperty(KeyPair, 'privBytes', function privBytes() { + var eddsa = this.eddsa; + var hash = this.hash(); + var lastIx = eddsa.encodingLength - 1; - // Some events have special handlers that wrap the real handler - var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper; + var a = hash.slice(0, eddsa.encodingLength); + a[0] &= 248; + a[lastIx] &= 127; + a[lastIx] |= 64; - // Copy event handlers in case event handlers array is modified during execution. - if ((eventFnsLength > 1)) { - eventFns = shallowCopy(eventFns); - } + return a; +}); - for (var i = 0; i < eventFnsLength; i++) { - if (!event.isImmediatePropagationStopped()) { - handlerWrapper(element, event, eventFns[i]); - } - } - }; +cachedProperty(KeyPair, 'priv', function priv() { + return this.eddsa.decodeInt(this.privBytes()); +}); - // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all - // events on `element` - eventHandler.elem = element; - return eventHandler; -} +cachedProperty(KeyPair, 'hash', function hash() { + return this.eddsa.hash().update(this.secret()).digest(); +}); -function defaultHandlerWrapper(element, event, handler) { - handler.call(element, event); -} +cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() { + return this.hash().slice(this.eddsa.encodingLength); +}); -function specialMouseHandlerWrapper(target, event, handler) { - // Refer to jQuery's implementation of mouseenter & mouseleave - // Read about mouseenter and mouseleave: - // http://www.quirksmode.org/js/events_mouse.html#link8 - var related = event.relatedTarget; - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if (!related || (related !== target && !jqLiteContains.call(target, related))) { - handler.call(target, event); - } -} +KeyPair.prototype.sign = function sign(message) { + assert(this._secret, 'KeyPair can only verify'); + return this.eddsa.sign(message, this); +}; -////////////////////////////////////////// -// Functions iterating traversal. -// These functions chain results into a single -// selector. -////////////////////////////////////////// -forEach({ - removeData: jqLiteRemoveData, +KeyPair.prototype.verify = function verify(message, sig) { + return this.eddsa.verify(message, sig, this); +}; - on: function jqLiteOn(element, type, fn, unsupported) { - if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters'); +KeyPair.prototype.getSecret = function getSecret(enc) { + assert(this._secret, 'KeyPair is public only'); + return utils.encode(this.secret(), enc); +}; - // Do not add event handlers to non-elements because they will not be cleaned up. - if (!jqLiteAcceptsData(element)) { - return; - } +KeyPair.prototype.getPublic = function getPublic(enc) { + return utils.encode(this.pubBytes(), enc); +}; - var expandoStore = jqLiteExpandoStore(element, true); - var events = expandoStore.events; - var handle = expandoStore.handle; +module.exports = KeyPair; - if (!handle) { - handle = expandoStore.handle = createEventHandler(element, events); - } +},{"../../elliptic":195}],207:[function(require,module,exports){ +'use strict'; - // http://jsperf.com/string-indexof-vs-split - var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type]; - var i = types.length; +var BN = require('bn.js'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; +var cachedProperty = utils.cachedProperty; +var parseBytes = utils.parseBytes; - var addHandler = function(type, specialHandlerWrapper, noEventListener) { - var eventFns = events[type]; +/** +* @param {EDDSA} eddsa - eddsa instance +* @param {Array|Object} sig - +* @param {Array|Point} [sig.R] - R point as Point or bytes +* @param {Array|bn} [sig.S] - S scalar as bn or bytes +* @param {Array} [sig.Rencoded] - R point encoded +* @param {Array} [sig.Sencoded] - S scalar encoded +*/ +function Signature(eddsa, sig) { + this.eddsa = eddsa; - if (!eventFns) { - eventFns = events[type] = []; - eventFns.specialHandlerWrapper = specialHandlerWrapper; - if (type !== '$destroy' && !noEventListener) { - element.addEventListener(type, handle); - } - } + if (typeof sig !== 'object') + sig = parseBytes(sig); - eventFns.push(fn); + if (Array.isArray(sig)) { + sig = { + R: sig.slice(0, eddsa.encodingLength), + S: sig.slice(eddsa.encodingLength) }; + } - while (i--) { - type = types[i]; - if (MOUSE_EVENT_MAP[type]) { - addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper); - addHandler(type, undefined, true); - } else { - addHandler(type); - } - } - }, - - off: jqLiteOff, - - one: function(element, type, fn) { - element = jqLite(element); - - //add the listener twice so that when it is called - //you can remove the original function and still be - //able to call element.off(ev, fn) normally - element.on(type, function onFn() { - element.off(type, fn); - element.off(type, onFn); - }); - element.on(type, fn); - }, - - replaceWith: function(element, replaceNode) { - var index, parent = element.parentNode; - jqLiteDealoc(element); - forEach(new JQLite(replaceNode), function(node) { - if (index) { - parent.insertBefore(node, index.nextSibling); - } else { - parent.replaceChild(node, element); - } - index = node; - }); - }, - - children: function(element) { - var children = []; - forEach(element.childNodes, function(element) { - if (element.nodeType === NODE_TYPE_ELEMENT) { - children.push(element); - } - }); - return children; - }, - - contents: function(element) { - return element.contentDocument || element.childNodes || []; - }, - - append: function(element, node) { - var nodeType = element.nodeType; - if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return; - - node = new JQLite(node); - - for (var i = 0, ii = node.length; i < ii; i++) { - var child = node[i]; - element.appendChild(child); - } - }, - - prepend: function(element, node) { - if (element.nodeType === NODE_TYPE_ELEMENT) { - var index = element.firstChild; - forEach(new JQLite(node), function(child) { - element.insertBefore(child, index); - }); - } - }, - - wrap: function(element, wrapNode) { - jqLiteWrapNode(element, jqLite(wrapNode).eq(0).clone()[0]); - }, - - remove: jqLiteRemove, - - detach: function(element) { - jqLiteRemove(element, true); - }, - - after: function(element, newElement) { - var index = element, parent = element.parentNode; - - if (parent) { - newElement = new JQLite(newElement); + assert(sig.R && sig.S, 'Signature without R or S'); - for (var i = 0, ii = newElement.length; i < ii; i++) { - var node = newElement[i]; - parent.insertBefore(node, index.nextSibling); - index = node; - } - } - }, + if (eddsa.isPoint(sig.R)) + this._R = sig.R; + if (sig.S instanceof BN) + this._S = sig.S; - addClass: jqLiteAddClass, - removeClass: jqLiteRemoveClass, + this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded; + this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded; +} - toggleClass: function(element, selector, condition) { - if (selector) { - forEach(selector.split(' '), function(className) { - var classCondition = condition; - if (isUndefined(classCondition)) { - classCondition = !jqLiteHasClass(element, className); - } - (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className); - }); - } - }, +cachedProperty(Signature, 'S', function S() { + return this.eddsa.decodeInt(this.Sencoded()); +}); - parent: function(element) { - var parent = element.parentNode; - return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null; - }, +cachedProperty(Signature, 'R', function R() { + return this.eddsa.decodePoint(this.Rencoded()); +}); - next: function(element) { - return element.nextElementSibling; - }, +cachedProperty(Signature, 'Rencoded', function Rencoded() { + return this.eddsa.encodePoint(this.R()); +}); - find: function(element, selector) { - if (element.getElementsByTagName) { - return element.getElementsByTagName(selector); - } else { - return []; - } - }, +cachedProperty(Signature, 'Sencoded', function Sencoded() { + return this.eddsa.encodeInt(this.S()); +}); - clone: jqLiteClone, +Signature.prototype.toBytes = function toBytes() { + return this.Rencoded().concat(this.Sencoded()); +}; - triggerHandler: function(element, event, extraParameters) { +Signature.prototype.toHex = function toHex() { + return utils.encode(this.toBytes(), 'hex').toUpperCase(); +}; - var dummyEvent, eventFnsCopy, handlerArgs; - var eventName = event.type || event; - var expandoStore = jqLiteExpandoStore(element); - var events = expandoStore && expandoStore.events; - var eventFns = events && events[eventName]; +module.exports = Signature; - if (eventFns) { - // Create a dummy event to pass to the handlers - dummyEvent = { - preventDefault: function() { this.defaultPrevented = true; }, - isDefaultPrevented: function() { return this.defaultPrevented === true; }, - stopImmediatePropagation: function() { this.immediatePropagationStopped = true; }, - isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; }, - stopPropagation: noop, - type: eventName, - target: element - }; +},{"../../elliptic":195,"bn.js":181}],208:[function(require,module,exports){ +module.exports = { + doubles: { + step: 4, + points: [ + [ + 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', + 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' + ], + [ + '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', + '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' + ], + [ + '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', + 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' + ], + [ + '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', + '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' + ], + [ + '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', + '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' + ], + [ + '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', + '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' + ], + [ + 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', + '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' + ], + [ + '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', + 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' + ], + [ + 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', + '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' + ], + [ + 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', + 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' + ], + [ + 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', + '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' + ], + [ + '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', + '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' + ], + [ + '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', + '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' + ], + [ + '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', + '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' + ], + [ + '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', + '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' + ], + [ + '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', + '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' + ], + [ + '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', + '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' + ], + [ + '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', + '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' + ], + [ + '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', + 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' + ], + [ + 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', + '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' + ], + [ + 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', + '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' + ], + [ + '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', + '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' + ], + [ + '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', + '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' + ], + [ + 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', + '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' + ], + [ + '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', + 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' + ], + [ + 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', + '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' + ], + [ + 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', + 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' + ], + [ + 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', + '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' + ], + [ + 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', + 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' + ], + [ + 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', + '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' + ], + [ + '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', + 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' + ], + [ + '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', + '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' + ], + [ + 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', + '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' + ], + [ + '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', + 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' + ], + [ + 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', + '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' + ], + [ + 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', + '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' + ], + [ + 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', + 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' + ], + [ + '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', + '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' + ], + [ + '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', + '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' + ], + [ + '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', + 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' + ], + [ + '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', + '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' + ], + [ + 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', + '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' + ], + [ + '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', + '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' + ], + [ + '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', + 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' + ], + [ + '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', + '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' + ], + [ + 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', + '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' + ], + [ + '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', + 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' + ], + [ + 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', + 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' + ], + [ + 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', + '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' + ], + [ + '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', + 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' + ], + [ + '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', + 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' + ], + [ + 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', + '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' + ], + [ + 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', + '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' + ], + [ + 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', + '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' + ], + [ + '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', + 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' + ], + [ + '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', + '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' + ], + [ + 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', + 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' + ], + [ + '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', + 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' + ], + [ + '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', + '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' + ], + [ + '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', + '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' + ], + [ + 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', + 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' + ], + [ + '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', + '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' + ], + [ + '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', + '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' + ], + [ + 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', + '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' + ], + [ + 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', + 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' + ] + ] + }, + naf: { + wnd: 7, + points: [ + [ + 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', + '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' + ], + [ + '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', + 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' + ], + [ + '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', + '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' + ], + [ + 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', + 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' + ], + [ + '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', + 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' + ], + [ + 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', + 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' + ], + [ + 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', + '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' + ], + [ + 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', + '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' + ], + [ + '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', + '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' + ], + [ + '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', + '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' + ], + [ + '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', + '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' + ], + [ + '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', + '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' + ], + [ + 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', + 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' + ], + [ + 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', + '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' + ], + [ + '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', + 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' + ], + [ + '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', + 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' + ], + [ + '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', + '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' + ], + [ + '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', + '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' + ], + [ + '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', + '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' + ], + [ + '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', + 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' + ], + [ + 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', + 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' + ], + [ + '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', + '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' + ], + [ + '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', + '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' + ], + [ + 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', + 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' + ], + [ + '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', + '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' + ], + [ + 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', + 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' + ], + [ + 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', + 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' + ], + [ + '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', + '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' + ], + [ + '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', + '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' + ], + [ + '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', + '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' + ], + [ + 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', + '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' + ], + [ + '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', + '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' + ], + [ + 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', + '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' + ], + [ + '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', + 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' + ], + [ + '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', + 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' + ], + [ + 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', + 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' + ], + [ + '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', + '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' + ], + [ + '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', + 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' + ], + [ + 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', + 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' + ], + [ + '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', + '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' + ], + [ + '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', + 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' + ], + [ + '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', + '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' + ], + [ + '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', + 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' + ], + [ + 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', + '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' + ], + [ + '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', + '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' + ], + [ + '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', + 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' + ], + [ + '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', + 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' + ], + [ + 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', + 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' + ], + [ + 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', + 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' + ], + [ + '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', + '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' + ], + [ + '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', + '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' + ], + [ + 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', + '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' + ], + [ + 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', + 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' + ], + [ + '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', + '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' + ], + [ + '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', + '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' + ], + [ + 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', + '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' + ], + [ + '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', + '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' + ], + [ + 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', + 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' + ], + [ + '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', + 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' + ], + [ + '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', + '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' + ], + [ + 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', + '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' + ], + [ + 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', + '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' + ], + [ + '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', + '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' + ], + [ + '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', + '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' + ], + [ + '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', + 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' + ], + [ + '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', + 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' + ], + [ + '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', + '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' + ], + [ + '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', + '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' + ], + [ + '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', + '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' + ], + [ + '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', + 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' + ], + [ + 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', + 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' + ], + [ + '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', + 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' + ], + [ + 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', + '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' + ], + [ + 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', + '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' + ], + [ + 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', + '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' + ], + [ + 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', + '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' + ], + [ + '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', + 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' + ], + [ + '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', + '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' + ], + [ + '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', + 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' + ], + [ + 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', + 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' + ], + [ + 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', + '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' + ], + [ + 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', + 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' + ], + [ + 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', + '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' + ], + [ + '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', + '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' + ], + [ + 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', + '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' + ], + [ + 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', + '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' + ], + [ + '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', + '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' + ], + [ + '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', + 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' + ], + [ + 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', + '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' + ], + [ + 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', + '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' + ], + [ + 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', + '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' + ], + [ + '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', + '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' + ], + [ + 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', + 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' + ], + [ + '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', + 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' + ], + [ + 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', + 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' + ], + [ + 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', + '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' + ], + [ + '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', + 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' + ], + [ + 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', + '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' + ], + [ + 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', + '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' + ], + [ + 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', + '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' + ], + [ + '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', + 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' + ], + [ + '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', + 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' + ], + [ + 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', + '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' + ], + [ + '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', + 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' + ], + [ + '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', + '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' + ], + [ + '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', + 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' + ], + [ + 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', + 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' + ], + [ + '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', + 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' + ], + [ + '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', + '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' + ], + [ + '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', + 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' + ], + [ + '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', + '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' + ], + [ + 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', + 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' + ], + [ + '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', + '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' + ], + [ + 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', + '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' + ], + [ + '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', + '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' + ], + [ + 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', + 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' + ], + [ + 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', + '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' + ], + [ + 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', + 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' + ], + [ + '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', + 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' + ], + [ + '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', + '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' + ], + [ + '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', + 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' + ], + [ + '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', + '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' + ], + [ + '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', + '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' + ], + [ + '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', + 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' + ], + [ + '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', + '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' + ], + [ + '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', + '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' + ], + [ + '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', + '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' + ] + ] + } +}; - // If a custom event was provided then extend our dummy event with it - if (event.type) { - dummyEvent = extend(dummyEvent, event); - } +},{}],209:[function(require,module,exports){ +'use strict'; - // Copy event handlers in case event handlers array is modified during execution. - eventFnsCopy = shallowCopy(eventFns); - handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent]; +var utils = exports; +var BN = require('bn.js'); +var minAssert = require('minimalistic-assert'); +var minUtils = require('minimalistic-crypto-utils'); - forEach(eventFnsCopy, function(fn) { - if (!dummyEvent.isImmediatePropagationStopped()) { - fn.apply(element, handlerArgs); - } - }); - } - } -}, function(fn, name) { - /** - * chaining functions - */ - JQLite.prototype[name] = function(arg1, arg2, arg3) { - var value; +utils.assert = minAssert; +utils.toArray = minUtils.toArray; +utils.zero2 = minUtils.zero2; +utils.toHex = minUtils.toHex; +utils.encode = minUtils.encode; - for (var i = 0, ii = this.length; i < ii; i++) { - if (isUndefined(value)) { - value = fn(this[i], arg1, arg2, arg3); - if (isDefined(value)) { - // any function which returns a value needs to be wrapped - value = jqLite(value); - } - } else { - jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3)); - } +// Represent num in a w-NAF form +function getNAF(num, w) { + var naf = []; + var ws = 1 << (w + 1); + var k = num.clone(); + while (k.cmpn(1) >= 0) { + var z; + if (k.isOdd()) { + var mod = k.andln(ws - 1); + if (mod > (ws >> 1) - 1) + z = (ws >> 1) - mod; + else + z = mod; + k.isubn(z); + } else { + z = 0; } - return isDefined(value) ? value : this; - }; -}); - -// bind legacy bind/unbind to on/off -JQLite.prototype.bind = JQLite.prototype.on; -JQLite.prototype.unbind = JQLite.prototype.off; + naf.push(z); + // Optimization, shift by word if possible + var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; + for (var i = 1; i < shift; i++) + naf.push(0); + k.iushrn(shift); + } -// Provider for private $$jqLite service -/** @this */ -function $$jqLiteProvider() { - this.$get = function $$jqLite() { - return extend(JQLite, { - hasClass: function(node, classes) { - if (node.attr) node = node[0]; - return jqLiteHasClass(node, classes); - }, - addClass: function(node, classes) { - if (node.attr) node = node[0]; - return jqLiteAddClass(node, classes); - }, - removeClass: function(node, classes) { - if (node.attr) node = node[0]; - return jqLiteRemoveClass(node, classes); - } - }); - }; + return naf; } +utils.getNAF = getNAF; -/** - * Computes a hash of an 'obj'. - * Hash of a: - * string is string - * number is number as string - * object is either result of calling $$hashKey function on the object or uniquely generated id, - * that is also assigned to the $$hashKey property of the object. - * - * @param obj - * @returns {string} hash string such that the same input will have the same hash string. - * The resulting string key is in 'type:hashKey' format. - */ -function hashKey(obj, nextUidFn) { - var key = obj && obj.$$hashKey; +// Represent k1, k2 in a Joint Sparse Form +function getJSF(k1, k2) { + var jsf = [ + [], + [] + ]; - if (key) { - if (typeof key === 'function') { - key = obj.$$hashKey(); + k1 = k1.clone(); + k2 = k2.clone(); + var d1 = 0; + var d2 = 0; + while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { + + // First phase + var m14 = (k1.andln(3) + d1) & 3; + var m24 = (k2.andln(3) + d2) & 3; + if (m14 === 3) + m14 = -1; + if (m24 === 3) + m24 = -1; + var u1; + if ((m14 & 1) === 0) { + u1 = 0; + } else { + var m8 = (k1.andln(7) + d1) & 7; + if ((m8 === 3 || m8 === 5) && m24 === 2) + u1 = -m14; + else + u1 = m14; } - return key; - } + jsf[0].push(u1); - var objType = typeof obj; - if (objType === 'function' || (objType === 'object' && obj !== null)) { - key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)(); - } else { - key = objType + ':' + obj; + var u2; + if ((m24 & 1) === 0) { + u2 = 0; + } else { + var m8 = (k2.andln(7) + d2) & 7; + if ((m8 === 3 || m8 === 5) && m14 === 2) + u2 = -m24; + else + u2 = m24; + } + jsf[1].push(u2); + + // Second phase + if (2 * d1 === u1 + 1) + d1 = 1 - d1; + if (2 * d2 === u2 + 1) + d2 = 1 - d2; + k1.iushrn(1); + k2.iushrn(1); } - return key; + return jsf; } +utils.getJSF = getJSF; -// A minimal ES2015 Map implementation. -// Should be bug/feature equivalent to the native implementations of supported browsers -// (for the features required in Angular). -// See https://kangax.github.io/compat-table/es6/#test-Map -var nanKey = Object.create(null); -function NgMapShim() { - this._keys = []; - this._values = []; - this._lastKey = NaN; - this._lastIndex = -1; +function cachedProperty(obj, name, computer) { + var key = '_' + name; + obj.prototype[name] = function cachedProperty() { + return this[key] !== undefined ? this[key] : + this[key] = computer.call(this); + }; } -NgMapShim.prototype = { - _idx: function(key) { - if (key !== this._lastKey) { - this._lastKey = key; - this._lastIndex = this._keys.indexOf(key); - } - return this._lastIndex; - }, - _transformKey: function(key) { - return isNumberNaN(key) ? nanKey : key; - }, - get: function(key) { - key = this._transformKey(key); - var idx = this._idx(key); - if (idx !== -1) { - return this._values[idx]; - } - }, - has: function(key) { - key = this._transformKey(key); - var idx = this._idx(key); - return idx !== -1; - }, - set: function(key, value) { - key = this._transformKey(key); - var idx = this._idx(key); - if (idx === -1) { - idx = this._lastIndex = this._keys.length; - } - this._keys[idx] = key; - this._values[idx] = value; +utils.cachedProperty = cachedProperty; - // Support: IE11 - // Do not `return this` to simulate the partial IE11 implementation - }, - delete: function(key) { - key = this._transformKey(key); - var idx = this._idx(key); - if (idx === -1) { - return false; - } - this._keys.splice(idx, 1); - this._values.splice(idx, 1); - this._lastKey = NaN; - this._lastIndex = -1; - return true; - } -}; +function parseBytes(bytes) { + return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') : + bytes; +} +utils.parseBytes = parseBytes; -// For now, always use `NgMapShim`, even if `window.Map` is available. Some native implementations -// are still buggy (often in subtle ways) and can cause hard-to-debug failures. When native `Map` -// implementations get more stable, we can reconsider switching to `window.Map` (when available). -var NgMap = NgMapShim; +function intFromLE(bytes) { + return new BN(bytes, 'hex', 'le'); +} +utils.intFromLE = intFromLE; -var $$MapProvider = [/** @this */function() { - this.$get = [function() { - return NgMap; - }]; -}]; + +},{"bn.js":181,"minimalistic-assert":257,"minimalistic-crypto-utils":258}],210:[function(require,module,exports){ +module.exports={ + "_args": [ + [ + "elliptic@6.4.1", + "/Users/yelpadillo/workspace/mew/etherwallet" + ] + ], + "_from": "elliptic@6.4.1", + "_id": "elliptic@6.4.1", + "_inBundle": false, + "_integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "_location": "/@myetherwallet/mewconnect-web-client/elliptic", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "elliptic@6.4.1", + "name": "elliptic", + "escapedName": "elliptic", + "rawSpec": "6.4.1", + "saveSpec": null, + "fetchSpec": "6.4.1" + }, + "_requiredBy": [ + "/@myetherwallet/mewconnect-web-client/browserify-sign", + "/@myetherwallet/mewconnect-web-client/create-ecdh", + "/@myetherwallet/mewconnect-web-client/eccrypto", + "/@myetherwallet/mewconnect-web-client/eccrypto/secp256k1", + "/@myetherwallet/mewconnect-web-client/secp256k1" + ], + "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "_spec": "6.4.1", + "_where": "/Users/yelpadillo/workspace/mew/etherwallet", + "author": { + "name": "Fedor Indutny", + "email": "fedor@indutny.com" + }, + "bugs": { + "url": "https://github.com/indutny/elliptic/issues" + }, + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "description": "EC cryptography", + "devDependencies": { + "brfs": "^1.4.3", + "coveralls": "^2.11.3", + "grunt": "^0.4.5", + "grunt-browserify": "^5.0.0", + "grunt-cli": "^1.2.0", + "grunt-contrib-connect": "^1.0.0", + "grunt-contrib-copy": "^1.0.0", + "grunt-contrib-uglify": "^1.0.1", + "grunt-mocha-istanbul": "^3.0.1", + "grunt-saucelabs": "^8.6.2", + "istanbul": "^0.4.2", + "jscs": "^2.9.0", + "jshint": "^2.6.0", + "mocha": "^2.1.0" + }, + "files": [ + "lib" + ], + "homepage": "https://github.com/indutny/elliptic", + "keywords": [ + "EC", + "Elliptic", + "curve", + "Cryptography" + ], + "license": "MIT", + "main": "lib/elliptic.js", + "name": "elliptic", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/indutny/elliptic.git" + }, + "scripts": { + "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", + "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js", + "lint": "npm run jscs && npm run jshint", + "test": "npm run lint && npm run unit", + "unit": "istanbul test _mocha --reporter=spec test/index.js", + "version": "grunt dist && git add dist/" + }, + "version": "6.4.1" +} + +},{}],211:[function(require,module,exports){ + +module.exports = require('./socket'); /** - * @ngdoc function - * @module ng - * @name angular.injector - * @kind function - * - * @description - * Creates an injector object that can be used for retrieving services as well as for - * dependency injection (see {@link guide/di dependency injection}). - * - * @param {Array.} modules A list of module functions or their aliases. See - * {@link angular.module}. The `ng` module must be explicitly added. - * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which - * disallows argument name annotation inference. - * @returns {injector} Injector object. See {@link auto.$injector $injector}. - * - * @example - * Typical usage - * ```js - * // create an injector - * var $injector = angular.injector(['ng']); - * - * // use the injector to kick off your application - * // use the type inference to auto inject arguments, or use implicit injection - * $injector.invoke(function($rootScope, $compile, $document) { - * $compile($document)($rootScope); - * $rootScope.$digest(); - * }); - * ``` - * - * Sometimes you want to get access to the injector of a currently running AngularJS app - * from outside AngularJS. Perhaps, you want to inject and compile some markup after the - * application has been bootstrapped. You can do this using the extra `injector()` added - * to JQuery/jqLite elements. See {@link angular.element}. - * - * *This is fairly rare but could be the case if a third party library is injecting the - * markup.* - * - * In the following example a new block of HTML containing a `ng-controller` - * directive is added to the end of the document body by JQuery. We then compile and link - * it into the current AngularJS scope. + * Exports parser * - * ```js - * var $div = $('
{{content.label}}
'); - * $(document.body).append($div); + * @api public * - * angular.element(document).injector().invoke(function($compile) { - * var scope = angular.element($div).scope(); - * $compile($div)(scope); - * }); - * ``` + */ +module.exports.parser = require('engine.io-parser'); + +},{"./socket":212,"engine.io-parser":222}],212:[function(require,module,exports){ +(function (global){ +/** + * Module dependencies. + */ + +var transports = require('./transports/index'); +var Emitter = require('component-emitter'); +var debug = require('debug')('engine.io-client:socket'); +var index = require('indexof'); +var parser = require('engine.io-parser'); +var parseuri = require('parseuri'); +var parseqs = require('parseqs'); + +/** + * Module exports. */ +module.exports = Socket; /** - * @ngdoc module - * @name auto - * @installation - * @description + * Socket constructor. * - * Implicit module which gets automatically added to each {@link auto.$injector $injector}. + * @param {String|Object} uri or options + * @param {Object} options + * @api public */ -var ARROW_ARG = /^([^(]+?)=>/; -var FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m; -var FN_ARG_SPLIT = /,/; -var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; -var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -var $injectorMinErr = minErr('$injector'); +function Socket (uri, opts) { + if (!(this instanceof Socket)) return new Socket(uri, opts); -function stringifyFn(fn) { - return Function.prototype.toString.call(fn); -} + opts = opts || {}; -function extractArgs(fn) { - var fnText = stringifyFn(fn).replace(STRIP_COMMENTS, ''), - args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS); - return args; -} + if (uri && 'object' === typeof uri) { + opts = uri; + uri = null; + } -function anonFn(fn) { - // For anonymous functions, showing at the very least the function signature can help in - // debugging. - var args = extractArgs(fn); - if (args) { - return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')'; + if (uri) { + uri = parseuri(uri); + opts.hostname = uri.host; + opts.secure = uri.protocol === 'https' || uri.protocol === 'wss'; + opts.port = uri.port; + if (uri.query) opts.query = uri.query; + } else if (opts.host) { + opts.hostname = parseuri(opts.host).host; } - return 'fn'; -} -function annotate(fn, strictDi, name) { - var $inject, - argDecl, - last; + this.secure = null != opts.secure ? opts.secure + : (global.location && 'https:' === location.protocol); - if (typeof fn === 'function') { - if (!($inject = fn.$inject)) { - $inject = []; - if (fn.length) { - if (strictDi) { - if (!isString(name) || !name) { - name = fn.name || anonFn(fn); - } - throw $injectorMinErr('strictdi', - '{0} is not using explicit annotation and cannot be invoked in strict mode', name); - } - argDecl = extractArgs(fn); - forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) { - arg.replace(FN_ARG, function(all, underscore, name) { - $inject.push(name); - }); - }); - } - fn.$inject = $inject; + if (opts.hostname && !opts.port) { + // if no port is specified manually, use the protocol default + opts.port = this.secure ? '443' : '80'; + } + + this.agent = opts.agent || false; + this.hostname = opts.hostname || + (global.location ? location.hostname : 'localhost'); + this.port = opts.port || (global.location && location.port + ? location.port + : (this.secure ? 443 : 80)); + this.query = opts.query || {}; + if ('string' === typeof this.query) this.query = parseqs.decode(this.query); + this.upgrade = false !== opts.upgrade; + this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; + this.forceJSONP = !!opts.forceJSONP; + this.jsonp = false !== opts.jsonp; + this.forceBase64 = !!opts.forceBase64; + this.enablesXDR = !!opts.enablesXDR; + this.timestampParam = opts.timestampParam || 't'; + this.timestampRequests = opts.timestampRequests; + this.transports = opts.transports || ['polling', 'websocket']; + this.transportOptions = opts.transportOptions || {}; + this.readyState = ''; + this.writeBuffer = []; + this.prevBufferLen = 0; + this.policyPort = opts.policyPort || 843; + this.rememberUpgrade = opts.rememberUpgrade || false; + this.binaryType = null; + this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades; + this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false; + + if (true === this.perMessageDeflate) this.perMessageDeflate = {}; + if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) { + this.perMessageDeflate.threshold = 1024; + } + + // SSL options for Node.js client + this.pfx = opts.pfx || null; + this.key = opts.key || null; + this.passphrase = opts.passphrase || null; + this.cert = opts.cert || null; + this.ca = opts.ca || null; + this.ciphers = opts.ciphers || null; + this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? true : opts.rejectUnauthorized; + this.forceNode = !!opts.forceNode; + + // other options for Node.js client + var freeGlobal = typeof global === 'object' && global; + if (freeGlobal.global === freeGlobal) { + if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) { + this.extraHeaders = opts.extraHeaders; + } + + if (opts.localAddress) { + this.localAddress = opts.localAddress; } - } else if (isArray(fn)) { - last = fn.length - 1; - assertArgFn(fn[last], 'fn'); - $inject = fn.slice(0, last); - } else { - assertArgFn(fn, 'fn', true); } - return $inject; + + // set on handshake + this.id = null; + this.upgrades = null; + this.pingInterval = null; + this.pingTimeout = null; + + // set on heartbeat + this.pingIntervalTimer = null; + this.pingTimeoutTimer = null; + + this.open(); } -/////////////////////////////////////// +Socket.priorWebsocketSuccess = false; /** - * @ngdoc service - * @name $injector - * - * @description - * - * `$injector` is used to retrieve object instances as defined by - * {@link auto.$provide provider}, instantiate types, invoke methods, - * and load modules. - * - * The following always holds true: - * - * ```js - * var $injector = angular.injector(); - * expect($injector.get('$injector')).toBe($injector); - * expect($injector.invoke(function($injector) { - * return $injector; - * })).toBe($injector); - * ``` - * - * ## Injection Function Annotation - * - * JavaScript does not have annotations, and annotations are needed for dependency injection. The - * following are all valid ways of annotating function with injection arguments and are equivalent. - * - * ```js - * // inferred (only works if code not minified/obfuscated) - * $injector.invoke(function(serviceA){}); - * - * // annotated - * function explicit(serviceA) {}; - * explicit.$inject = ['serviceA']; - * $injector.invoke(explicit); - * - * // inline - * $injector.invoke(['serviceA', function(serviceA){}]); - * ``` - * - * ### Inference - * - * In JavaScript calling `toString()` on a function returns the function definition. The definition - * can then be parsed and the function arguments can be extracted. This method of discovering - * annotations is disallowed when the injector is in strict mode. - * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the - * argument names. - * - * ### `$inject` Annotation - * By adding an `$inject` property onto a function the injection parameters can be specified. - * - * ### Inline - * As an array of injection names, where the last item in the array is the function to call. + * Mix in `Emitter`. */ +Emitter(Socket.prototype); + /** - * @ngdoc property - * @name $injector#modules - * @type {Object} - * @description - * A hash containing all the modules that have been loaded into the - * $injector. - * - * You can use this property to find out information about a module via the - * {@link angular.Module#info `myModule.info(...)`} method. - * - * For example: - * - * ``` - * var info = $injector.modules['ngAnimate'].info(); - * ``` + * Protocol version. * - * **Do not use this property to attempt to modify the modules after the application - * has been bootstrapped.** + * @api public */ +Socket.protocol = parser.protocol; // this is an int /** - * @ngdoc method - * @name $injector#get - * - * @description - * Return an instance of the service. - * - * @param {string} name The name of the instance to retrieve. - * @param {string=} caller An optional string to provide the origin of the function call for error messages. - * @return {*} The instance. + * Expose deps for legacy compatibility + * and standalone browser access. */ +Socket.Socket = Socket; +Socket.Transport = require('./transport'); +Socket.transports = require('./transports/index'); +Socket.parser = require('engine.io-parser'); + /** - * @ngdoc method - * @name $injector#invoke - * - * @description - * Invoke the method and supply the method arguments from the `$injector`. + * Creates transport of the given type. * - * @param {Function|Array.} fn The injectable function to invoke. Function parameters are - * injected according to the {@link guide/di $inject Annotation} rules. - * @param {Object=} self The `this` for the invoked method. - * @param {Object=} locals Optional object. If preset then any argument names are read from this - * object first, before the `$injector` is consulted. - * @returns {*} the value returned by the invoked `fn` function. + * @param {String} transport name + * @return {Transport} + * @api private */ +Socket.prototype.createTransport = function (name) { + debug('creating transport "%s"', name); + var query = clone(this.query); + + // append engine.io protocol identifier + query.EIO = parser.protocol; + + // transport name + query.transport = name; + + // per-transport options + var options = this.transportOptions[name] || {}; + + // session id if we already have one + if (this.id) query.sid = this.id; + + var transport = new transports[name]({ + query: query, + socket: this, + agent: options.agent || this.agent, + hostname: options.hostname || this.hostname, + port: options.port || this.port, + secure: options.secure || this.secure, + path: options.path || this.path, + forceJSONP: options.forceJSONP || this.forceJSONP, + jsonp: options.jsonp || this.jsonp, + forceBase64: options.forceBase64 || this.forceBase64, + enablesXDR: options.enablesXDR || this.enablesXDR, + timestampRequests: options.timestampRequests || this.timestampRequests, + timestampParam: options.timestampParam || this.timestampParam, + policyPort: options.policyPort || this.policyPort, + pfx: options.pfx || this.pfx, + key: options.key || this.key, + passphrase: options.passphrase || this.passphrase, + cert: options.cert || this.cert, + ca: options.ca || this.ca, + ciphers: options.ciphers || this.ciphers, + rejectUnauthorized: options.rejectUnauthorized || this.rejectUnauthorized, + perMessageDeflate: options.perMessageDeflate || this.perMessageDeflate, + extraHeaders: options.extraHeaders || this.extraHeaders, + forceNode: options.forceNode || this.forceNode, + localAddress: options.localAddress || this.localAddress, + requestTimeout: options.requestTimeout || this.requestTimeout, + protocols: options.protocols || void (0) + }); + + return transport; +}; + +function clone (obj) { + var o = {}; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + o[i] = obj[i]; + } + } + return o; +} + /** - * @ngdoc method - * @name $injector#has - * - * @description - * Allows the user to query if the particular service exists. + * Initializes transport to use and starts probe. * - * @param {string} name Name of the service to query. - * @returns {boolean} `true` if injector has given service. + * @api private */ +Socket.prototype.open = function () { + var transport; + if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') !== -1) { + transport = 'websocket'; + } else if (0 === this.transports.length) { + // Emit error on next tick so it can be listened to + var self = this; + setTimeout(function () { + self.emit('error', 'No transports available'); + }, 0); + return; + } else { + transport = this.transports[0]; + } + this.readyState = 'opening'; + + // Retry with the next transport if the transport is disabled (jsonp: false) + try { + transport = this.createTransport(transport); + } catch (e) { + this.transports.shift(); + this.open(); + return; + } + + transport.open(); + this.setTransport(transport); +}; /** - * @ngdoc method - * @name $injector#instantiate - * @description - * Create a new instance of JS type. The method takes a constructor function, invokes the new - * operator, and supplies all of the arguments to the constructor function as specified by the - * constructor annotation. + * Sets the current transport. Disables the existing one (if any). * - * @param {Function} Type Annotated constructor function. - * @param {Object=} locals Optional object. If preset then any argument names are read from this - * object first, before the `$injector` is consulted. - * @returns {Object} new instance of `Type`. + * @api private */ +Socket.prototype.setTransport = function (transport) { + debug('setting transport %s', transport.name); + var self = this; + + if (this.transport) { + debug('clearing existing transport %s', this.transport.name); + this.transport.removeAllListeners(); + } + + // set up transport + this.transport = transport; + + // set up transport listeners + transport + .on('drain', function () { + self.onDrain(); + }) + .on('packet', function (packet) { + self.onPacket(packet); + }) + .on('error', function (e) { + self.onError(e); + }) + .on('close', function () { + self.onClose('transport close'); + }); +}; + /** - * @ngdoc method - * @name $injector#annotate - * - * @description - * Returns an array of service names which the function is requesting for injection. This API is - * used by the injector to determine which services need to be injected into the function when the - * function is invoked. There are three ways in which the function can be annotated with the needed - * dependencies. - * - * #### Argument names - * - * The simplest form is to extract the dependencies from the arguments of the function. This is done - * by converting the function into a string using `toString()` method and extracting the argument - * names. - * ```js - * // Given - * function MyController($scope, $route) { - * // ... - * } - * - * // Then - * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); - * ``` - * - * You can disallow this method by using strict injection mode. - * - * This method does not work with code minification / obfuscation. For this reason the following - * annotation strategies are supported. - * - * #### The `$inject` property - * - * If a function has an `$inject` property and its value is an array of strings, then the strings - * represent names of services to be injected into the function. - * ```js - * // Given - * var MyController = function(obfuscatedScope, obfuscatedRoute) { - * // ... - * } - * // Define function dependencies - * MyController['$inject'] = ['$scope', '$route']; - * - * // Then - * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); - * ``` - * - * #### The array notation - * - * It is often desirable to inline Injected functions and that's when setting the `$inject` property - * is very inconvenient. In these situations using the array notation to specify the dependencies in - * a way that survives minification is a better choice: - * - * ```js - * // We wish to write this (not minification / obfuscation safe) - * injector.invoke(function($compile, $rootScope) { - * // ... - * }); - * - * // We are forced to write break inlining - * var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) { - * // ... - * }; - * tmpFn.$inject = ['$compile', '$rootScope']; - * injector.invoke(tmpFn); - * - * // To better support inline function the inline annotation is supported - * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) { - * // ... - * }]); - * - * // Therefore - * expect(injector.annotate( - * ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}]) - * ).toEqual(['$compile', '$rootScope']); - * ``` - * - * @param {Function|Array.} fn Function for which dependent service names need to - * be retrieved as described above. - * - * @param {boolean=} [strictDi=false] Disallow argument name annotation inference. + * Probes a transport. * - * @returns {Array.} The names of the services which the function requires. + * @param {String} transport name + * @api private */ + +Socket.prototype.probe = function (name) { + debug('probing transport "%s"', name); + var transport = this.createTransport(name, { probe: 1 }); + var failed = false; + var self = this; + + Socket.priorWebsocketSuccess = false; + + function onTransportOpen () { + if (self.onlyBinaryUpgrades) { + var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; + failed = failed || upgradeLosesBinary; + } + if (failed) return; + + debug('probe transport "%s" opened', name); + transport.send([{ type: 'ping', data: 'probe' }]); + transport.once('packet', function (msg) { + if (failed) return; + if ('pong' === msg.type && 'probe' === msg.data) { + debug('probe transport "%s" pong', name); + self.upgrading = true; + self.emit('upgrading', transport); + if (!transport) return; + Socket.priorWebsocketSuccess = 'websocket' === transport.name; + + debug('pausing current transport "%s"', self.transport.name); + self.transport.pause(function () { + if (failed) return; + if ('closed' === self.readyState) return; + debug('changing transport and sending upgrade packet'); + + cleanup(); + + self.setTransport(transport); + transport.send([{ type: 'upgrade' }]); + self.emit('upgrade', transport); + transport = null; + self.upgrading = false; + self.flush(); + }); + } else { + debug('probe transport "%s" failed', name); + var err = new Error('probe error'); + err.transport = transport.name; + self.emit('upgradeError', err); + } + }); + } + + function freezeTransport () { + if (failed) return; + + // Any callback called by transport should be ignored since now + failed = true; + + cleanup(); + + transport.close(); + transport = null; + } + + // Handle any error that happens while probing + function onerror (err) { + var error = new Error('probe error: ' + err); + error.transport = transport.name; + + freezeTransport(); + + debug('probe transport "%s" failed because of error: %s', name, err); + + self.emit('upgradeError', error); + } + + function onTransportClose () { + onerror('transport closed'); + } + + // When the socket is closed while we're probing + function onclose () { + onerror('socket closed'); + } + + // When the socket is upgraded while we're probing + function onupgrade (to) { + if (transport && to.name !== transport.name) { + debug('"%s" works - aborting "%s"', to.name, transport.name); + freezeTransport(); + } + } + + // Remove all listeners on the transport and on self + function cleanup () { + transport.removeListener('open', onTransportOpen); + transport.removeListener('error', onerror); + transport.removeListener('close', onTransportClose); + self.removeListener('close', onclose); + self.removeListener('upgrading', onupgrade); + } + + transport.once('open', onTransportOpen); + transport.once('error', onerror); + transport.once('close', onTransportClose); + + this.once('close', onclose); + this.once('upgrading', onupgrade); + + transport.open(); +}; + /** - * @ngdoc method - * @name $injector#loadNewModules - * - * @description - * - * **This is a dangerous API, which you use at your own risk!** - * - * Add the specified modules to the current injector. - * - * This method will add each of the injectables to the injector and execute all of the config and run - * blocks for each module passed to the method. - * - * If a module has already been loaded into the injector then it will not be loaded again. - * - * * The application developer is responsible for loading the code containing the modules; and for - * ensuring that lazy scripts are not downloaded and executed more often that desired. - * * Previously compiled HTML will not be affected by newly loaded directives, filters and components. - * * Modules cannot be unloaded. - * - * You can use {@link $injector#modules `$injector.modules`} to check whether a module has been loaded - * into the injector, which may indicate whether the script has been executed already. - * - * @example - * Here is an example of loading a bundle of modules, with a utility method called `getScript`: - * - * ```javascript - * app.factory('loadModule', function($injector) { - * return function loadModule(moduleName, bundleUrl) { - * return getScript(bundleUrl).then(function() { $injector.loadNewModules([moduleName]); }); - * }; - * }) - * ``` + * Called when connection is deemed open. * - * @param {Array=} mods an array of modules to load into the application. - * Each item in the array should be the name of a predefined module or a (DI annotated) - * function that will be invoked by the injector as a `config` block. - * See: {@link angular.module modules} + * @api public */ +Socket.prototype.onOpen = function () { + debug('socket open'); + this.readyState = 'open'; + Socket.priorWebsocketSuccess = 'websocket' === this.transport.name; + this.emit('open'); + this.flush(); + + // we check for `readyState` in case an `open` + // listener already closed the socket + if ('open' === this.readyState && this.upgrade && this.transport.pause) { + debug('starting upgrade probes'); + for (var i = 0, l = this.upgrades.length; i < l; i++) { + this.probe(this.upgrades[i]); + } + } +}; /** - * @ngdoc service - * @name $provide - * - * @description - * - * The {@link auto.$provide $provide} service has a number of methods for registering components - * with the {@link auto.$injector $injector}. Many of these functions are also exposed on - * {@link angular.Module}. - * - * An AngularJS **service** is a singleton object created by a **service factory**. These **service - * factories** are functions which, in turn, are created by a **service provider**. - * The **service providers** are constructor functions. When instantiated they must contain a - * property called `$get`, which holds the **service factory** function. - * - * When you request a service, the {@link auto.$injector $injector} is responsible for finding the - * correct **service provider**, instantiating it and then calling its `$get` **service factory** - * function to get the instance of the **service**. - * - * Often services have no configuration options and there is no need to add methods to the service - * provider. The provider will be no more than a constructor function with a `$get` property. For - * these cases the {@link auto.$provide $provide} service has additional helper methods to register - * services without specifying a provider. - * - * * {@link auto.$provide#provider provider(name, provider)} - registers a **service provider** with the - * {@link auto.$injector $injector} - * * {@link auto.$provide#constant constant(name, obj)} - registers a value/object that can be accessed by - * providers and services. - * * {@link auto.$provide#value value(name, obj)} - registers a value/object that can only be accessed by - * services, not providers. - * * {@link auto.$provide#factory factory(name, fn)} - registers a service **factory function** - * that will be wrapped in a **service provider** object, whose `$get` property will contain the - * given factory function. - * * {@link auto.$provide#service service(name, Fn)} - registers a **constructor function** - * that will be wrapped in a **service provider** object, whose `$get` property will instantiate - * a new object using the given constructor function. - * * {@link auto.$provide#decorator decorator(name, decorFn)} - registers a **decorator function** that - * will be able to modify or replace the implementation of another service. + * Handles a packet. * - * See the individual methods for more information and examples. + * @api private */ +Socket.prototype.onPacket = function (packet) { + if ('opening' === this.readyState || 'open' === this.readyState || + 'closing' === this.readyState) { + debug('socket receive: type "%s", data "%s"', packet.type, packet.data); + + this.emit('packet', packet); + + // Socket is live - any packet counts + this.emit('heartbeat'); + + switch (packet.type) { + case 'open': + this.onHandshake(JSON.parse(packet.data)); + break; + + case 'pong': + this.setPing(); + this.emit('pong'); + break; + + case 'error': + var err = new Error('server error'); + err.code = packet.data; + this.onError(err); + break; + + case 'message': + this.emit('data', packet.data); + this.emit('message', packet.data); + break; + } + } else { + debug('packet received with socket readyState "%s"', this.readyState); + } +}; + /** - * @ngdoc method - * @name $provide#provider - * @description - * - * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions - * are constructor functions, whose instances are responsible for "providing" a factory for a - * service. - * - * Service provider names start with the name of the service they provide followed by `Provider`. - * For example, the {@link ng.$log $log} service has a provider called - * {@link ng.$logProvider $logProvider}. - * - * Service provider objects can have additional methods which allow configuration of the provider - * and its service. Importantly, you can configure what kind of service is created by the `$get` - * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a - * method {@link ng.$logProvider#debugEnabled debugEnabled} - * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the - * console or not. - * - * It is possible to inject other providers into the provider function, - * but the injected provider must have been defined before the one that requires it. - * - * @param {string} name The name of the instance. NOTE: the provider will be available under `name + - 'Provider'` key. - * @param {(Object|function())} provider If the provider is: - * - * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using - * {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created. - * - `Constructor`: a new instance of the provider will be created using - * {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`. + * Called upon handshake completion. * - * @returns {Object} registered provider instance + * @param {Object} handshake obj + * @api private + */ - * @example - * - * The following example shows how to create a simple event tracking service and register it using - * {@link auto.$provide#provider $provide.provider()}. - * - * ```js - * // Define the eventTracker provider - * function EventTrackerProvider() { - * var trackingUrl = '/track'; - * - * // A provider method for configuring where the tracked events should been saved - * this.setTrackingUrl = function(url) { - * trackingUrl = url; - * }; - * - * // The service factory function - * this.$get = ['$http', function($http) { - * var trackedEvents = {}; - * return { - * // Call this to track an event - * event: function(event) { - * var count = trackedEvents[event] || 0; - * count += 1; - * trackedEvents[event] = count; - * return count; - * }, - * // Call this to save the tracked events to the trackingUrl - * save: function() { - * $http.post(trackingUrl, trackedEvents); - * } - * }; - * }]; - * } - * - * describe('eventTracker', function() { - * var postSpy; - * - * beforeEach(module(function($provide) { - * // Register the eventTracker provider - * $provide.provider('eventTracker', EventTrackerProvider); - * })); - * - * beforeEach(module(function(eventTrackerProvider) { - * // Configure eventTracker provider - * eventTrackerProvider.setTrackingUrl('/custom-track'); - * })); - * - * it('tracks events', inject(function(eventTracker) { - * expect(eventTracker.event('login')).toEqual(1); - * expect(eventTracker.event('login')).toEqual(2); - * })); +Socket.prototype.onHandshake = function (data) { + this.emit('handshake', data); + this.id = data.sid; + this.transport.query.sid = data.sid; + this.upgrades = this.filterUpgrades(data.upgrades); + this.pingInterval = data.pingInterval; + this.pingTimeout = data.pingTimeout; + this.onOpen(); + // In case open handler closes socket + if ('closed' === this.readyState) return; + this.setPing(); + + // Prolong liveness of socket on heartbeat + this.removeListener('heartbeat', this.onHeartbeat); + this.on('heartbeat', this.onHeartbeat); +}; + +/** + * Resets ping timeout. * - * it('saves to the tracking url', inject(function(eventTracker, $http) { - * postSpy = spyOn($http, 'post'); - * eventTracker.event('login'); - * eventTracker.save(); - * expect(postSpy).toHaveBeenCalled(); - * expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track'); - * expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track'); - * expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 }); - * })); - * }); - * ``` + * @api private */ +Socket.prototype.onHeartbeat = function (timeout) { + clearTimeout(this.pingTimeoutTimer); + var self = this; + self.pingTimeoutTimer = setTimeout(function () { + if ('closed' === self.readyState) return; + self.onClose('ping timeout'); + }, timeout || (self.pingInterval + self.pingTimeout)); +}; + /** - * @ngdoc method - * @name $provide#factory - * @description - * - * Register a **service factory**, which will be called to return the service instance. - * This is short for registering a service where its provider consists of only a `$get` property, - * which is the given service factory function. - * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to - * configure your service in a provider. - * - * @param {string} name The name of the instance. - * @param {Function|Array.} $getFn The injectable $getFn for the instance creation. - * Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`. - * @returns {Object} registered provider instance + * Pings server every `this.pingInterval` and expects response + * within `this.pingTimeout` or closes connection. * - * @example - * Here is an example of registering a service - * ```js - * $provide.factory('ping', ['$http', function($http) { - * return function ping() { - * return $http.send('/ping'); - * }; - * }]); - * ``` - * You would then inject and use this service like this: - * ```js - * someModule.controller('Ctrl', ['ping', function(ping) { - * ping(); - * }]); - * ``` + * @api private */ +Socket.prototype.setPing = function () { + var self = this; + clearTimeout(self.pingIntervalTimer); + self.pingIntervalTimer = setTimeout(function () { + debug('writing ping packet - expecting pong within %sms', self.pingTimeout); + self.ping(); + self.onHeartbeat(self.pingTimeout); + }, self.pingInterval); +}; /** - * @ngdoc method - * @name $provide#service - * @description - * - * Register a **service constructor**, which will be invoked with `new` to create the service - * instance. - * This is short for registering a service where its provider's `$get` property is a factory - * function that returns an instance instantiated by the injector from the service constructor - * function. - * - * Internally it looks a bit like this: - * - * ``` - * { - * $get: function() { - * return $injector.instantiate(constructor); - * } - * } - * ``` - * - * - * You should use {@link auto.$provide#service $provide.service(class)} if you define your service - * as a type/class. - * - * @param {string} name The name of the instance. - * @param {Function|Array.} constructor An injectable class (constructor function) - * that will be instantiated. - * @returns {Object} registered provider instance - * - * @example - * Here is an example of registering a service using - * {@link auto.$provide#service $provide.service(class)}. - * ```js - * var Ping = function($http) { - * this.$http = $http; - * }; - * - * Ping.$inject = ['$http']; +* Sends a ping packet. +* +* @api private +*/ + +Socket.prototype.ping = function () { + var self = this; + this.sendPacket('ping', function () { + self.emit('ping'); + }); +}; + +/** + * Called on `drain` event * - * Ping.prototype.send = function() { - * return this.$http.get('/ping'); - * }; - * $provide.service('ping', Ping); - * ``` - * You would then inject and use this service like this: - * ```js - * someModule.controller('Ctrl', ['ping', function(ping) { - * ping.send(); - * }]); - * ``` + * @api private */ +Socket.prototype.onDrain = function () { + this.writeBuffer.splice(0, this.prevBufferLen); + + // setting prevBufferLen = 0 is very important + // for example, when upgrading, upgrade packet is sent over, + // and a nonzero prevBufferLen could cause problems on `drain` + this.prevBufferLen = 0; + + if (0 === this.writeBuffer.length) { + this.emit('drain'); + } else { + this.flush(); + } +}; /** - * @ngdoc method - * @name $provide#value - * @description - * - * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a - * number, an array, an object or a function. This is short for registering a service where its - * provider's `$get` property is a factory function that takes no arguments and returns the **value - * service**. That also means it is not possible to inject other services into a value service. - * - * Value services are similar to constant services, except that they cannot be injected into a - * module configuration function (see {@link angular.Module#config}) but they can be overridden by - * an AngularJS {@link auto.$provide#decorator decorator}. - * - * @param {string} name The name of the instance. - * @param {*} value The value. - * @returns {Object} registered provider instance - * - * @example - * Here are some examples of creating value services. - * ```js - * $provide.value('ADMIN_USER', 'admin'); - * - * $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 }); + * Flush write buffers. * - * $provide.value('halfOf', function(value) { - * return value / 2; - * }); - * ``` + * @api private */ +Socket.prototype.flush = function () { + if ('closed' !== this.readyState && this.transport.writable && + !this.upgrading && this.writeBuffer.length) { + debug('flushing %d packets in socket', this.writeBuffer.length); + this.transport.send(this.writeBuffer); + // keep track of current length of writeBuffer + // splice writeBuffer and callbackBuffer on `drain` + this.prevBufferLen = this.writeBuffer.length; + this.emit('flush'); + } +}; /** - * @ngdoc method - * @name $provide#constant - * @description - * - * Register a **constant service** with the {@link auto.$injector $injector}, such as a string, - * a number, an array, an object or a function. Like the {@link auto.$provide#value value}, it is not - * possible to inject other services into a constant. - * - * But unlike {@link auto.$provide#value value}, a constant can be - * injected into a module configuration function (see {@link angular.Module#config}) and it cannot - * be overridden by an AngularJS {@link auto.$provide#decorator decorator}. - * - * @param {string} name The name of the constant. - * @param {*} value The constant value. - * @returns {Object} registered instance - * - * @example - * Here a some examples of creating constants: - * ```js - * $provide.constant('SHARD_HEIGHT', 306); - * - * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']); + * Sends a message. * - * $provide.constant('double', function(value) { - * return value * 2; - * }); - * ``` + * @param {String} message. + * @param {Function} callback function. + * @param {Object} options. + * @return {Socket} for chaining. + * @api public */ +Socket.prototype.write = +Socket.prototype.send = function (msg, options, fn) { + this.sendPacket('message', msg, options, fn); + return this; +}; /** - * @ngdoc method - * @name $provide#decorator - * @description - * - * Register a **decorator function** with the {@link auto.$injector $injector}. A decorator function - * intercepts the creation of a service, allowing it to override or modify the behavior of the - * service. The return value of the decorator function may be the original service, or a new service - * that replaces (or wraps and delegates to) the original service. - * - * You can find out more about using decorators in the {@link guide/decorators} guide. - * - * @param {string} name The name of the service to decorate. - * @param {Function|Array.} decorator This function will be invoked when the service needs to be - * provided and should return the decorated service instance. The function is called using - * the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable. - * Local injection arguments: - * - * * `$delegate` - The original service instance, which can be replaced, monkey patched, configured, - * decorated or delegated to. + * Sends a packet. * - * @example - * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting - * calls to {@link ng.$log#error $log.warn()}. - * ```js - * $provide.decorator('$log', ['$delegate', function($delegate) { - * $delegate.warn = $delegate.error; - * return $delegate; - * }]); - * ``` + * @param {String} packet type. + * @param {String} data. + * @param {Object} options. + * @param {Function} callback function. + * @api private */ +Socket.prototype.sendPacket = function (type, data, options, fn) { + if ('function' === typeof data) { + fn = data; + data = undefined; + } -function createInjector(modulesToLoad, strictDi) { - strictDi = (strictDi === true); - var INSTANTIATING = {}, - providerSuffix = 'Provider', - path = [], - loadedModules = new NgMap(), - providerCache = { - $provide: { - provider: supportObject(provider), - factory: supportObject(factory), - service: supportObject(service), - value: supportObject(value), - constant: supportObject(constant), - decorator: decorator - } - }, - providerInjector = (providerCache.$injector = - createInternalInjector(providerCache, function(serviceName, caller) { - if (angular.isString(caller)) { - path.push(caller); - } - throw $injectorMinErr('unpr', 'Unknown provider: {0}', path.join(' <- ')); - })), - instanceCache = {}, - protoInstanceInjector = - createInternalInjector(instanceCache, function(serviceName, caller) { - var provider = providerInjector.get(serviceName + providerSuffix, caller); - return instanceInjector.invoke( - provider.$get, provider, undefined, serviceName); - }), - instanceInjector = protoInstanceInjector; + if ('function' === typeof options) { + fn = options; + options = null; + } - providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) }; - instanceInjector.modules = providerInjector.modules = createMap(); - var runBlocks = loadModules(modulesToLoad); - instanceInjector = protoInstanceInjector.get('$injector'); - instanceInjector.strictDi = strictDi; - forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); }); + if ('closing' === this.readyState || 'closed' === this.readyState) { + return; + } - instanceInjector.loadNewModules = function(mods) { - forEach(loadModules(mods), function(fn) { if (fn) instanceInjector.invoke(fn); }); - }; + options = options || {}; + options.compress = false !== options.compress; + var packet = { + type: type, + data: data, + options: options + }; + this.emit('packetCreate', packet); + this.writeBuffer.push(packet); + if (fn) this.once('flush', fn); + this.flush(); +}; - return instanceInjector; +/** + * Closes the connection. + * + * @api private + */ - //////////////////////////////////// - // $provider - //////////////////////////////////// +Socket.prototype.close = function () { + if ('opening' === this.readyState || 'open' === this.readyState) { + this.readyState = 'closing'; - function supportObject(delegate) { - return function(key, value) { - if (isObject(key)) { - forEach(key, reverseParams(delegate)); - } else { - return delegate(key, value); - } - }; - } + var self = this; - function provider(name, provider_) { - assertNotHasOwnProperty(name, 'service'); - if (isFunction(provider_) || isArray(provider_)) { - provider_ = providerInjector.instantiate(provider_); - } - if (!provider_.$get) { - throw $injectorMinErr('pget', 'Provider \'{0}\' must define $get factory method.', name); + if (this.writeBuffer.length) { + this.once('drain', function () { + if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + }); + } else if (this.upgrading) { + waitForUpgrade(); + } else { + close(); } - return (providerCache[name + providerSuffix] = provider_); } - function enforceReturnValue(name, factory) { - return /** @this */ function enforcedReturnValue() { - var result = instanceInjector.invoke(factory, this); - if (isUndefined(result)) { - throw $injectorMinErr('undef', 'Provider \'{0}\' must return a value from $get factory method.', name); - } - return result; - }; + function close () { + self.onClose('forced close'); + debug('socket closing - telling transport to close'); + self.transport.close(); } - function factory(name, factoryFn, enforce) { - return provider(name, { - $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn - }); + function cleanupAndClose () { + self.removeListener('upgrade', cleanupAndClose); + self.removeListener('upgradeError', cleanupAndClose); + close(); } - function service(name, constructor) { - return factory(name, ['$injector', function($injector) { - return $injector.instantiate(constructor); - }]); + function waitForUpgrade () { + // wait for upgrade to finish since we can't send packets while pausing a transport + self.once('upgrade', cleanupAndClose); + self.once('upgradeError', cleanupAndClose); } - function value(name, val) { return factory(name, valueFn(val), false); } + return this; +}; - function constant(name, value) { - assertNotHasOwnProperty(name, 'constant'); - providerCache[name] = value; - instanceCache[name] = value; - } +/** + * Called upon transport error + * + * @api private + */ - function decorator(serviceName, decorFn) { - var origProvider = providerInjector.get(serviceName + providerSuffix), - orig$get = origProvider.$get; +Socket.prototype.onError = function (err) { + debug('socket error %j', err); + Socket.priorWebsocketSuccess = false; + this.emit('error', err); + this.onClose('transport error', err); +}; - origProvider.$get = function() { - var origInstance = instanceInjector.invoke(orig$get, origProvider); - return instanceInjector.invoke(decorFn, null, {$delegate: origInstance}); - }; - } +/** + * Called upon transport close. + * + * @api private + */ - //////////////////////////////////// - // Module Loading - //////////////////////////////////// - function loadModules(modulesToLoad) { - assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array'); - var runBlocks = [], moduleFn; - forEach(modulesToLoad, function(module) { - if (loadedModules.get(module)) return; - loadedModules.set(module, true); +Socket.prototype.onClose = function (reason, desc) { + if ('opening' === this.readyState || 'open' === this.readyState || 'closing' === this.readyState) { + debug('socket close with reason: "%s"', reason); + var self = this; - function runInvokeQueue(queue) { - var i, ii; - for (i = 0, ii = queue.length; i < ii; i++) { - var invokeArgs = queue[i], - provider = providerInjector.get(invokeArgs[0]); + // clear timers + clearTimeout(this.pingIntervalTimer); + clearTimeout(this.pingTimeoutTimer); - provider[invokeArgs[1]].apply(provider, invokeArgs[2]); - } - } + // stop event from firing again for transport + this.transport.removeAllListeners('close'); - try { - if (isString(module)) { - moduleFn = angularModule(module); - instanceInjector.modules[module] = moduleFn; - runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); - runInvokeQueue(moduleFn._invokeQueue); - runInvokeQueue(moduleFn._configBlocks); - } else if (isFunction(module)) { - runBlocks.push(providerInjector.invoke(module)); - } else if (isArray(module)) { - runBlocks.push(providerInjector.invoke(module)); - } else { - assertArgFn(module, 'module'); - } - } catch (e) { - if (isArray(module)) { - module = module[module.length - 1]; - } - if (e.message && e.stack && e.stack.indexOf(e.message) === -1) { - // Safari & FF's stack traces don't contain error.message content - // unlike those of Chrome and IE - // So if stack doesn't contain message, we create a new string that contains both. - // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here. - // eslint-disable-next-line no-ex-assign - e = e.message + '\n' + e.stack; - } - throw $injectorMinErr('modulerr', 'Failed to instantiate module {0} due to:\n{1}', - module, e.stack || e.message || e); - } - }); - return runBlocks; - } + // ensure transport won't stay open + this.transport.close(); - //////////////////////////////////// - // internal Injector - //////////////////////////////////// + // ignore further transport communication + this.transport.removeAllListeners(); - function createInternalInjector(cache, factory) { + // set ready state + this.readyState = 'closed'; - function getService(serviceName, caller) { - if (cache.hasOwnProperty(serviceName)) { - if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', - serviceName + ' <- ' + path.join(' <- ')); - } - return cache[serviceName]; - } else { - try { - path.unshift(serviceName); - cache[serviceName] = INSTANTIATING; - cache[serviceName] = factory(serviceName, caller); - return cache[serviceName]; - } catch (err) { - if (cache[serviceName] === INSTANTIATING) { - delete cache[serviceName]; - } - throw err; - } finally { - path.shift(); - } - } - } + // clear session id + this.id = null; + // emit close event + this.emit('close', reason, desc); - function injectionArgs(fn, locals, serviceName) { - var args = [], - $inject = createInjector.$$annotate(fn, strictDi, serviceName); + // clean buffers after, so users can still + // grab the buffers on `close` event + self.writeBuffer = []; + self.prevBufferLen = 0; + } +}; - for (var i = 0, length = $inject.length; i < length; i++) { - var key = $inject[i]; - if (typeof key !== 'string') { - throw $injectorMinErr('itkn', - 'Incorrect injection token! Expected service name as string, got {0}', key); - } - args.push(locals && locals.hasOwnProperty(key) ? locals[key] : - getService(key, serviceName)); - } - return args; - } +/** + * Filters upgrades, returning only those matching client transports. + * + * @param {Array} server upgrades + * @api private + * + */ - function isClass(func) { - // Support: IE 9-11 only - // IE 9-11 do not support classes and IE9 leaks with the code below. - if (msie || typeof func !== 'function') { - return false; - } - var result = func.$$ngIsClass; - if (!isBoolean(result)) { - result = func.$$ngIsClass = /^class\b/.test(stringifyFn(func)); - } - return result; - } +Socket.prototype.filterUpgrades = function (upgrades) { + var filteredUpgrades = []; + for (var i = 0, j = upgrades.length; i < j; i++) { + if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]); + } + return filteredUpgrades; +}; - function invoke(fn, self, locals, serviceName) { - if (typeof locals === 'string') { - serviceName = locals; - locals = null; - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./transport":213,"./transports/index":214,"component-emitter":186,"debug":220,"engine.io-parser":222,"indexof":245,"parseqs":260,"parseuri":261}],213:[function(require,module,exports){ +/** + * Module dependencies. + */ - var args = injectionArgs(fn, locals, serviceName); - if (isArray(fn)) { - fn = fn[fn.length - 1]; - } +var parser = require('engine.io-parser'); +var Emitter = require('component-emitter'); - if (!isClass(fn)) { - // http://jsperf.com/angularjs-invoke-apply-vs-switch - // #5388 - return fn.apply(self, args); - } else { - args.unshift(null); - return new (Function.prototype.bind.apply(fn, args))(); - } - } +/** + * Module exports. + */ +module.exports = Transport; - function instantiate(Type, locals, serviceName) { - // Check if Type is annotated and use just the given function at n-1 as parameter - // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]); - var ctor = (isArray(Type) ? Type[Type.length - 1] : Type); - var args = injectionArgs(Type, locals, serviceName); - // Empty object at position 0 is ignored for invocation with `new`, but required. - args.unshift(null); - return new (Function.prototype.bind.apply(ctor, args))(); - } +/** + * Transport abstract constructor. + * + * @param {Object} options. + * @api private + */ + +function Transport (opts) { + this.path = opts.path; + this.hostname = opts.hostname; + this.port = opts.port; + this.secure = opts.secure; + this.query = opts.query; + this.timestampParam = opts.timestampParam; + this.timestampRequests = opts.timestampRequests; + this.readyState = ''; + this.agent = opts.agent || false; + this.socket = opts.socket; + this.enablesXDR = opts.enablesXDR; + // SSL options for Node.js client + this.pfx = opts.pfx; + this.key = opts.key; + this.passphrase = opts.passphrase; + this.cert = opts.cert; + this.ca = opts.ca; + this.ciphers = opts.ciphers; + this.rejectUnauthorized = opts.rejectUnauthorized; + this.forceNode = opts.forceNode; - return { - invoke: invoke, - instantiate: instantiate, - get: getService, - annotate: createInjector.$$annotate, - has: function(name) { - return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); - } - }; - } + // other options for Node.js client + this.extraHeaders = opts.extraHeaders; + this.localAddress = opts.localAddress; } -createInjector.$$annotate = annotate; - /** - * @ngdoc provider - * @name $anchorScrollProvider - * @this - * - * @description - * Use `$anchorScrollProvider` to disable automatic scrolling whenever - * {@link ng.$location#hash $location.hash()} changes. + * Mix in `Emitter`. */ -function $AnchorScrollProvider() { - var autoScrollingEnabled = true; +Emitter(Transport.prototype); - /** - * @ngdoc method - * @name $anchorScrollProvider#disableAutoScrolling - * - * @description - * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to - * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.
- * Use this method to disable automatic scrolling. - * - * If automatic scrolling is disabled, one must explicitly call - * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the - * current hash. - */ - this.disableAutoScrolling = function() { - autoScrollingEnabled = false; - }; +/** + * Emits an error. + * + * @param {String} str + * @return {Transport} for chaining + * @api public + */ - /** - * @ngdoc service - * @name $anchorScroll - * @kind function - * @requires $window - * @requires $location - * @requires $rootScope - * - * @description - * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the - * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified - * in the - * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#an-indicated-part-of-the-document). - * - * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to - * match any anchor whenever it changes. This can be disabled by calling - * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}. - * - * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a - * vertical scroll-offset (either fixed or dynamic). - * - * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of - * {@link ng.$location#hash $location.hash()} will be used. - * - * @property {(number|function|jqLite)} yOffset - * If set, specifies a vertical scroll-offset. This is often useful when there are fixed - * positioned elements at the top of the page, such as navbars, headers etc. - * - * `yOffset` can be specified in various ways: - * - **number**: A fixed number of pixels to be used as offset.

- * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return - * a number representing the offset (in pixels).

- * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from - * the top of the page to the element's bottom will be used as offset.
- * **Note**: The element will be taken into account only as long as its `position` is set to - * `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust - * their height and/or positioning according to the viewport's size. - * - *
- *
- * In order for `yOffset` to work properly, scrolling should take place on the document's root and - * not some child element. - *
- * - * @example - - -
- Go to bottom - You're at the bottom! -
-
- - angular.module('anchorScrollExample', []) - .controller('ScrollController', ['$scope', '$location', '$anchorScroll', - function($scope, $location, $anchorScroll) { - $scope.gotoBottom = function() { - // set the location.hash to the id of - // the element you wish to scroll to. - $location.hash('bottom'); +Transport.prototype.onError = function (msg, desc) { + var err = new Error(msg); + err.type = 'TransportError'; + err.description = desc; + this.emit('error', err); + return this; +}; - // call $anchorScroll() - $anchorScroll(); - }; - }]); - - - #scrollArea { - height: 280px; - overflow: auto; - } +/** + * Opens the transport. + * + * @api public + */ - #bottom { - display: block; - margin-top: 2000px; - } - -
- * - *
- * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value). - * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details. - * - * @example - - - -
- Anchor {{x}} of 5 -
-
- - angular.module('anchorScrollOffsetExample', []) - .run(['$anchorScroll', function($anchorScroll) { - $anchorScroll.yOffset = 50; // always scroll by 50 extra pixels - }]) - .controller('headerCtrl', ['$anchorScroll', '$location', '$scope', - function($anchorScroll, $location, $scope) { - $scope.gotoAnchor = function(x) { - var newHash = 'anchor' + x; - if ($location.hash() !== newHash) { - // set the $location.hash to `newHash` and - // $anchorScroll will automatically scroll to it - $location.hash('anchor' + x); - } else { - // call $anchorScroll() explicitly, - // since $location.hash hasn't changed - $anchorScroll(); - } - }; - } - ]); - - - body { - padding-top: 50px; - } +Transport.prototype.open = function () { + if ('closed' === this.readyState || '' === this.readyState) { + this.readyState = 'opening'; + this.doOpen(); + } - .anchor { - border: 2px dashed DarkOrchid; - padding: 10px 10px 200px 10px; - } + return this; +}; - .fixed-header { - background-color: rgba(0, 0, 0, 0.2); - height: 50px; - position: fixed; - top: 0; left: 0; right: 0; - } +/** + * Closes the transport. + * + * @api private + */ - .fixed-header > a { - display: inline-block; - margin: 5px 15px; - } - -
- */ - this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) { - var document = $window.document; +Transport.prototype.close = function () { + if ('opening' === this.readyState || 'open' === this.readyState) { + this.doClose(); + this.onClose(); + } - // Helper function to get first anchor from a NodeList - // (using `Array#some()` instead of `angular#forEach()` since it's more performant - // and working in all supported browsers.) - function getFirstAnchor(list) { - var result = null; - Array.prototype.some.call(list, function(element) { - if (nodeName_(element) === 'a') { - result = element; - return true; - } - }); - return result; - } + return this; +}; - function getYOffset() { +/** + * Sends multiple packets. + * + * @param {Array} packets + * @api private + */ - var offset = scroll.yOffset; +Transport.prototype.send = function (packets) { + if ('open' === this.readyState) { + this.write(packets); + } else { + throw new Error('Transport not open'); + } +}; - if (isFunction(offset)) { - offset = offset(); - } else if (isElement(offset)) { - var elem = offset[0]; - var style = $window.getComputedStyle(elem); - if (style.position !== 'fixed') { - offset = 0; - } else { - offset = elem.getBoundingClientRect().bottom; - } - } else if (!isNumber(offset)) { - offset = 0; - } +/** + * Called upon open + * + * @api private + */ - return offset; - } +Transport.prototype.onOpen = function () { + this.readyState = 'open'; + this.writable = true; + this.emit('open'); +}; - function scrollTo(elem) { - if (elem) { - elem.scrollIntoView(); +/** + * Called with data. + * + * @param {String} data + * @api private + */ - var offset = getYOffset(); +Transport.prototype.onData = function (data) { + var packet = parser.decodePacket(data, this.socket.binaryType); + this.onPacket(packet); +}; - if (offset) { - // `offset` is the number of pixels we should scroll UP in order to align `elem` properly. - // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the - // top of the viewport. - // - // IF the number of pixels from the top of `elem` to the end of the page's content is less - // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some - // way down the page. - // - // This is often the case for elements near the bottom of the page. - // - // In such cases we do not need to scroll the whole `offset` up, just the difference between - // the top of the element and the offset, which is enough to align the top of `elem` at the - // desired position. - var elemTop = elem.getBoundingClientRect().top; - $window.scrollBy(0, elemTop - offset); - } - } else { - $window.scrollTo(0, 0); - } - } +/** + * Called with a decoded packet. + */ - function scroll(hash) { - // Allow numeric hashes - hash = isString(hash) ? hash : isNumber(hash) ? hash.toString() : $location.hash(); - var elm; +Transport.prototype.onPacket = function (packet) { + this.emit('packet', packet); +}; - // empty hash, scroll to the top of the page - if (!hash) scrollTo(null); +/** + * Called upon close. + * + * @api private + */ - // element with given id - else if ((elm = document.getElementById(hash))) scrollTo(elm); +Transport.prototype.onClose = function () { + this.readyState = 'closed'; + this.emit('close'); +}; - // first anchor with given name :-D - else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm); +},{"component-emitter":186,"engine.io-parser":222}],214:[function(require,module,exports){ +(function (global){ +/** + * Module dependencies + */ - // no element and hash === 'top', scroll to the top of the page - else if (hash === 'top') scrollTo(null); - } +var XMLHttpRequest = require('xmlhttprequest-ssl'); +var XHR = require('./polling-xhr'); +var JSONP = require('./polling-jsonp'); +var websocket = require('./websocket'); - // does not scroll when user clicks on anchor link that is currently on - // (no url change, no $location.hash() change), browser native does scroll - if (autoScrollingEnabled) { - $rootScope.$watch(function autoScrollWatch() {return $location.hash();}, - function autoScrollWatchAction(newVal, oldVal) { - // skip the initial scroll if $location.hash is empty - if (newVal === oldVal && newVal === '') return; +/** + * Export transports. + */ - jqLiteDocumentLoaded(function() { - $rootScope.$evalAsync(scroll); - }); - }); - } +exports.polling = polling; +exports.websocket = websocket; - return scroll; - }]; -} +/** + * Polling transport polymorphic constructor. + * Decides on xhr vs jsonp based on feature detection. + * + * @api private + */ -var $animateMinErr = minErr('$animate'); -var ELEMENT_NODE = 1; -var NG_ANIMATE_CLASSNAME = 'ng-animate'; +function polling (opts) { + var xhr; + var xd = false; + var xs = false; + var jsonp = false !== opts.jsonp; -function mergeClasses(a,b) { - if (!a && !b) return ''; - if (!a) return b; - if (!b) return a; - if (isArray(a)) a = a.join(' '); - if (isArray(b)) b = b.join(' '); - return a + ' ' + b; -} + if (global.location) { + var isSSL = 'https:' === location.protocol; + var port = location.port; -function extractElementNode(element) { - for (var i = 0; i < element.length; i++) { - var elm = element[i]; - if (elm.nodeType === ELEMENT_NODE) { - return elm; + // some user agents have empty `location.port` + if (!port) { + port = isSSL ? 443 : 80; } - } -} -function splitClasses(classes) { - if (isString(classes)) { - classes = classes.split(' '); + xd = opts.hostname !== location.hostname || port !== opts.port; + xs = opts.secure !== isSSL; } - // Use createMap() to prevent class assumptions involving property names in - // Object.prototype - var obj = createMap(); - forEach(classes, function(klass) { - // sometimes the split leaves empty string values - // incase extra spaces were applied to the options - if (klass.length) { - obj[klass] = true; - } - }); - return obj; -} + opts.xdomain = xd; + opts.xscheme = xs; + xhr = new XMLHttpRequest(opts); -// if any other type of options value besides an Object value is -// passed into the $animate.method() animation then this helper code -// will be run which will ignore it. While this patch is not the -// greatest solution to this, a lot of existing plugins depend on -// $animate to either call the callback (< 1.2) or return a promise -// that can be changed. This helper function ensures that the options -// are wiped clean incase a callback function is provided. -function prepareAnimateOptions(options) { - return isObject(options) - ? options - : {}; + if ('open' in xhr && !opts.forceJSONP) { + return new XHR(opts); + } else { + if (!jsonp) throw new Error('JSONP disabled'); + return new JSONP(opts); + } } -var $$CoreAnimateJsProvider = /** @this */ function() { - this.$get = noop; -}; - -// this is prefixed with Core since it conflicts with -// the animateQueueProvider defined in ngAnimate/animateQueue.js -var $$CoreAnimateQueueProvider = /** @this */ function() { - var postDigestQueue = new NgMap(); - var postDigestElements = []; +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./polling-jsonp":215,"./polling-xhr":216,"./websocket":218,"xmlhttprequest-ssl":219}],215:[function(require,module,exports){ +(function (global){ - this.$get = ['$$AnimateRunner', '$rootScope', - function($$AnimateRunner, $rootScope) { - return { - enabled: noop, - on: noop, - off: noop, - pin: noop, +/** + * Module requirements. + */ - push: function(element, event, options, domOperation) { - if (domOperation) { - domOperation(); - } +var Polling = require('./polling'); +var inherit = require('component-inherit'); - options = options || {}; - if (options.from) { - element.css(options.from); - } - if (options.to) { - element.css(options.to); - } +/** + * Module exports. + */ - if (options.addClass || options.removeClass) { - addRemoveClassesPostDigest(element, options.addClass, options.removeClass); - } +module.exports = JSONPPolling; - var runner = new $$AnimateRunner(); +/** + * Cached regular expressions. + */ - // since there are no animations to run the runner needs to be - // notified that the animation call is complete. - runner.complete(); - return runner; - } - }; +var rNewline = /\n/g; +var rEscapedNewline = /\\n/g; +/** + * Global JSONP callbacks. + */ - function updateData(data, classes, value) { - var changed = false; - if (classes) { - classes = isString(classes) ? classes.split(' ') : - isArray(classes) ? classes : []; - forEach(classes, function(className) { - if (className) { - changed = true; - data[className] = value; - } - }); - } - return changed; - } +var callbacks; - function handleCSSClassChanges() { - forEach(postDigestElements, function(element) { - var data = postDigestQueue.get(element); - if (data) { - var existing = splitClasses(element.attr('class')); - var toAdd = ''; - var toRemove = ''; - forEach(data, function(status, className) { - var hasClass = !!existing[className]; - if (status !== hasClass) { - if (status) { - toAdd += (toAdd.length ? ' ' : '') + className; - } else { - toRemove += (toRemove.length ? ' ' : '') + className; - } - } - }); +/** + * Noop. + */ - forEach(element, function(elm) { - if (toAdd) { - jqLiteAddClass(elm, toAdd); - } - if (toRemove) { - jqLiteRemoveClass(elm, toRemove); - } - }); - postDigestQueue.delete(element); - } - }); - postDigestElements.length = 0; - } +function empty () { } +/** + * JSONP Polling constructor. + * + * @param {Object} opts. + * @api public + */ - function addRemoveClassesPostDigest(element, add, remove) { - var data = postDigestQueue.get(element) || {}; +function JSONPPolling (opts) { + Polling.call(this, opts); - var classesAdded = updateData(data, add, true); - var classesRemoved = updateData(data, remove, false); + this.query = this.query || {}; - if (classesAdded || classesRemoved) { + // define global callbacks array if not present + // we do this here (lazily) to avoid unneeded global pollution + if (!callbacks) { + // we need to consider multiple engines in the same page + if (!global.___eio) global.___eio = []; + callbacks = global.___eio; + } - postDigestQueue.set(element, data); - postDigestElements.push(element); + // callback identifier + this.index = callbacks.length; - if (postDigestElements.length === 1) { - $rootScope.$$postDigest(handleCSSClassChanges); - } - } - } - }]; -}; + // add callback to jsonp global + var self = this; + callbacks.push(function (msg) { + self.onData(msg); + }); + + // append to query string + this.query.j = this.index; + + // prevent spurious errors from being emitted when the window is unloaded + if (global.document && global.addEventListener) { + global.addEventListener('beforeunload', function () { + if (self.script) self.script.onerror = empty; + }, false); + } +} /** - * @ngdoc provider - * @name $animateProvider - * - * @description - * Default implementation of $animate that doesn't perform any animations, instead just - * synchronously performs DOM updates and resolves the returned runner promise. - * - * In order to enable animations the `ngAnimate` module has to be loaded. - * - * To see the functional implementation check out `src/ngAnimate/animate.js`. + * Inherits from Polling. */ -var $AnimateProvider = ['$provide', /** @this */ function($provide) { - var provider = this; - var classNameFilter = null; - var customFilter = null; - this.$$registeredAnimations = Object.create(null); - - /** - * @ngdoc method - * @name $animateProvider#register - * - * @description - * Registers a new injectable animation factory function. The factory function produces the - * animation object which contains callback functions for each event that is expected to be - * animated. - * - * * `eventFn`: `function(element, ... , doneFunction, options)` - * The element to animate, the `doneFunction` and the options fed into the animation. Depending - * on the type of animation additional arguments will be injected into the animation function. The - * list below explains the function signatures for the different animation methods: - * - * - setClass: function(element, addedClasses, removedClasses, doneFunction, options) - * - addClass: function(element, addedClasses, doneFunction, options) - * - removeClass: function(element, removedClasses, doneFunction, options) - * - enter, leave, move: function(element, doneFunction, options) - * - animate: function(element, fromStyles, toStyles, doneFunction, options) - * - * Make sure to trigger the `doneFunction` once the animation is fully complete. - * - * ```js - * return { - * //enter, leave, move signature - * eventFn : function(element, done, options) { - * //code to run the animation - * //once complete, then run done() - * return function endFunction(wasCancelled) { - * //code to cancel the animation - * } - * } - * } - * ``` - * - * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to). - * @param {Function} factory The factory function that will be executed to return the animation - * object. - */ - this.register = function(name, factory) { - if (name && name.charAt(0) !== '.') { - throw $animateMinErr('notcsel', 'Expecting class selector starting with \'.\' got \'{0}\'.', name); - } +inherit(JSONPPolling, Polling); - var key = name + '-animation'; - provider.$$registeredAnimations[name.substr(1)] = key; - $provide.factory(key, factory); - }; +/* + * JSONP only supports binary as base64 encoded strings + */ - /** - * @ngdoc method - * @name $animateProvider#customFilter - * - * @description - * Sets and/or returns the custom filter function that is used to "filter" animations, i.e. - * determine if an animation is allowed or not. When no filter is specified (the default), no - * animation will be blocked. Setting the `customFilter` value will only allow animations for - * which the filter function's return value is truthy. - * - * This allows to easily create arbitrarily complex rules for filtering animations, such as - * allowing specific events only, or enabling animations on specific subtrees of the DOM, etc. - * Filtering animations can also boost performance for low-powered devices, as well as - * applications containing a lot of structural operations. - * - *
- * **Best Practice:** - * Keep the filtering function as lean as possible, because it will be called for each DOM - * action (e.g. insertion, removal, class change) performed by "animation-aware" directives. - * See {@link guide/animations#which-directives-support-animations- here} for a list of built-in - * directives that support animations. - * Performing computationally expensive or time-consuming operations on each call of the - * filtering function can make your animations sluggish. - *
- * - * **Note:** If present, `customFilter` will be checked before - * {@link $animateProvider#classNameFilter classNameFilter}. - * - * @param {Function=} filterFn - The filter function which will be used to filter all animations. - * If a falsy value is returned, no animation will be performed. The function will be called - * with the following arguments: - * - **node** `{DOMElement}` - The DOM element to be animated. - * - **event** `{String}` - The name of the animation event (e.g. `enter`, `leave`, `addClass` - * etc). - * - **options** `{Object}` - A collection of options/styles used for the animation. - * @return {Function} The current filter function or `null` if there is none set. - */ - this.customFilter = function(filterFn) { - if (arguments.length === 1) { - customFilter = isFunction(filterFn) ? filterFn : null; - } +JSONPPolling.prototype.supportsBinary = false; - return customFilter; - }; +/** + * Closes the socket. + * + * @api private + */ - /** - * @ngdoc method - * @name $animateProvider#classNameFilter - * - * @description - * Sets and/or returns the CSS class regular expression that is checked when performing - * an animation. Upon bootstrap the classNameFilter value is not set at all and will - * therefore enable $animate to attempt to perform an animation on any element that is triggered. - * When setting the `classNameFilter` value, animations will only be performed on elements - * that successfully match the filter expression. This in turn can boost performance - * for low-powered devices as well as applications containing a lot of structural operations. - * - * **Note:** If present, `classNameFilter` will be checked after - * {@link $animateProvider#customFilter customFilter}. If `customFilter` is present and returns - * false, `classNameFilter` will not be checked. - * - * @param {RegExp=} expression The className expression which will be checked against all animations - * @return {RegExp} The current CSS className expression value. If null then there is no expression value - */ - this.classNameFilter = function(expression) { - if (arguments.length === 1) { - classNameFilter = (expression instanceof RegExp) ? expression : null; - if (classNameFilter) { - var reservedRegex = new RegExp('[(\\s|\\/)]' + NG_ANIMATE_CLASSNAME + '[(\\s|\\/)]'); - if (reservedRegex.test(classNameFilter.toString())) { - classNameFilter = null; - throw $animateMinErr('nongcls', '$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME); - } - } - } - return classNameFilter; - }; +JSONPPolling.prototype.doClose = function () { + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } - this.$get = ['$$animateQueue', function($$animateQueue) { - function domInsert(element, parentElement, afterElement) { - // if for some reason the previous element was removed - // from the dom sometime before this code runs then let's - // just stick to using the parent element as the anchor - if (afterElement) { - var afterNode = extractElementNode(afterElement); - if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) { - afterElement = null; - } - } - if (afterElement) { - afterElement.after(element); - } else { - parentElement.prepend(element); - } - } + if (this.form) { + this.form.parentNode.removeChild(this.form); + this.form = null; + this.iframe = null; + } - /** - * @ngdoc service - * @name $animate - * @description The $animate service exposes a series of DOM utility methods that provide support - * for animation hooks. The default behavior is the application of DOM operations, however, - * when an animation is detected (and animations are enabled), $animate will do the heavy lifting - * to ensure that animation runs with the triggered DOM operation. - * - * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't - * included and only when it is active then the animation hooks that `$animate` triggers will be - * functional. Once active then all structural `ng-` directives will trigger animations as they perform - * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`, - * `ngShow`, `ngHide` and `ngMessages` also provide support for animations. - * - * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives. - * - * To learn more about enabling animation support, click here to visit the - * {@link ngAnimate ngAnimate module page}. - */ - return { - // we don't call it directly since non-existant arguments may - // be interpreted as null within the sub enabled function + Polling.prototype.doClose.call(this); +}; - /** - * - * @ngdoc method - * @name $animate#on - * @kind function - * @description Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...) - * has fired on the given element or among any of its children. Once the listener is fired, the provided callback - * is fired with the following params: - * - * ```js - * $animate.on('enter', container, - * function callback(element, phase) { - * // cool we detected an enter animation within the container - * } - * ); - * ``` - * - *
- * **Note**: Generally, the events that are fired correspond 1:1 to `$animate` method names, - * e.g. {@link ng.$animate#addClass addClass()} will fire `addClass`, and {@link ng.ngClass} - * will fire `addClass` if classes are added, and `removeClass` if classes are removed. - * However, there are two exceptions: - * - *
    - *
  • if both an {@link ng.$animate#addClass addClass()} and a - * {@link ng.$animate#removeClass removeClass()} action are performed during the same - * animation, the event fired will be `setClass`. This is true even for `ngClass`.
  • - *
  • an {@link ng.$animate#animate animate()} call that adds and removes classes will fire - * the `setClass` event, but if it either removes or adds classes, - * it will fire `animate` instead.
  • - *
- * - *
- * - * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param {DOMElement} container the container element that will capture each of the animation events that are fired on itself - * as well as among its children - * @param {Function} callback the callback function that will be fired when the listener is triggered. - * - * The arguments present in the callback function are: - * * `element` - The captured DOM element that the animation was fired on. - * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends). - * * `data` - an object with these properties: - * * addClass - `{string|null}` - space-separated CSS classes to add to the element - * * removeClass - `{string|null}` - space-separated CSS classes to remove from the element - * * from - `{Object|null}` - CSS properties & values at the beginning of the animation - * * to - `{Object|null}` - CSS properties & values at the end of the animation - * - * Note that the callback does not trigger a scope digest. Wrap your call into a - * {@link $rootScope.Scope#$apply scope.$apply} to propagate changes to the scope. - */ - on: $$animateQueue.on, +/** + * Starts a poll cycle. + * + * @api private + */ - /** - * - * @ngdoc method - * @name $animate#off - * @kind function - * @description Deregisters an event listener based on the event which has been associated with the provided element. This method - * can be used in three different ways depending on the arguments: - * - * ```js - * // remove all the animation event listeners listening for `enter` - * $animate.off('enter'); - * - * // remove listeners for all animation events from the container element - * $animate.off(container); - * - * // remove all the animation event listeners listening for `enter` on the given element and its children - * $animate.off('enter', container); - * - * // remove the event listener function provided by `callback` that is set - * // to listen for `enter` on the given `container` as well as its children - * $animate.off('enter', container, callback); - * ``` - * - * @param {string|DOMElement} event|container the animation event (e.g. enter, leave, move, - * addClass, removeClass, etc...), or the container element. If it is the element, all other - * arguments are ignored. - * @param {DOMElement=} container the container element the event listener was placed on - * @param {Function=} callback the callback function that was registered as the listener - */ - off: $$animateQueue.off, +JSONPPolling.prototype.doPoll = function () { + var self = this; + var script = document.createElement('script'); - /** - * @ngdoc method - * @name $animate#pin - * @kind function - * @description Associates the provided element with a host parent element to allow the element to be animated even if it exists - * outside of the DOM structure of the AngularJS application. By doing so, any animation triggered via `$animate` can be issued on the - * element despite being outside the realm of the application or within another application. Say for example if the application - * was bootstrapped on an element that is somewhere inside of the `` tag, but we wanted to allow for an element to be situated - * as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind - * that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association. - * - * Note that this feature is only active when the `ngAnimate` module is used. - * - * @param {DOMElement} element the external element that will be pinned - * @param {DOMElement} parentElement the host parent element that will be associated with the external element - */ - pin: $$animateQueue.pin, + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } - /** - * - * @ngdoc method - * @name $animate#enabled - * @kind function - * @description Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This - * function can be called in four ways: - * - * ```js - * // returns true or false - * $animate.enabled(); - * - * // changes the enabled state for all animations - * $animate.enabled(false); - * $animate.enabled(true); - * - * // returns true or false if animations are enabled for an element - * $animate.enabled(element); - * - * // changes the enabled state for an element and its children - * $animate.enabled(element, true); - * $animate.enabled(element, false); - * ``` - * - * @param {DOMElement=} element the element that will be considered for checking/setting the enabled state - * @param {boolean=} enabled whether or not the animations will be enabled for the element - * - * @return {boolean} whether or not animations are enabled - */ - enabled: $$animateQueue.enabled, + script.async = true; + script.src = this.uri(); + script.onerror = function (e) { + self.onError('jsonp poll error', e); + }; - /** - * @ngdoc method - * @name $animate#cancel - * @kind function - * @description Cancels the provided animation and applies the end state of the animation. - * Note that this does not cancel the underlying operation, e.g. the setting of classes or - * adding the element to the DOM. - * - * @param {animationRunner} animationRunner An animation runner returned by an $animate function. - * - * @example - - - angular.module('animationExample', ['ngAnimate']).component('cancelExample', { - templateUrl: 'template.html', - controller: function($element, $animate) { - this.runner = null; + var insertAt = document.getElementsByTagName('script')[0]; + if (insertAt) { + insertAt.parentNode.insertBefore(script, insertAt); + } else { + (document.head || document.body).appendChild(script); + } + this.script = script; - this.addClass = function() { - this.runner = $animate.addClass($element.find('div'), 'red'); - var ctrl = this; - this.runner.finally(function() { - ctrl.runner = null; - }); - }; + var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent); - this.removeClass = function() { - this.runner = $animate.removeClass($element.find('div'), 'red'); - var ctrl = this; - this.runner.finally(function() { - ctrl.runner = null; - }); - }; + if (isUAgecko) { + setTimeout(function () { + var iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + document.body.removeChild(iframe); + }, 100); + } +}; - this.cancel = function() { - $animate.cancel(this.runner); - }; - } - }); - - -

- - -
- -
-

CSS-Animated Text
-

-
- - - - - .red-add, .red-remove { - transition: all 4s cubic-bezier(0.250, 0.460, 0.450, 0.940); - } +/** + * Writes with a hidden iframe. + * + * @param {String} data to send + * @param {Function} called upon flush. + * @api private + */ - .red, - .red-add.red-add-active { - color: #FF0000; - font-size: 40px; - } +JSONPPolling.prototype.doWrite = function (data, fn) { + var self = this; - .red-remove.red-remove-active { - font-size: 10px; - color: black; - } + if (!this.form) { + var form = document.createElement('form'); + var area = document.createElement('textarea'); + var id = this.iframeId = 'eio_iframe_' + this.index; + var iframe; - -
- */ - cancel: function(runner) { - if (runner.cancel) { - runner.cancel(); - } - }, + form.className = 'socketio'; + form.style.position = 'absolute'; + form.style.top = '-1000px'; + form.style.left = '-1000px'; + form.target = id; + form.method = 'POST'; + form.setAttribute('accept-charset', 'utf-8'); + area.name = 'd'; + form.appendChild(area); + document.body.appendChild(form); - /** - * - * @ngdoc method - * @name $animate#enter - * @kind function - * @description Inserts the element into the DOM either after the `after` element (if provided) or - * as the first child within the `parent` element and then triggers an animation. - * A promise is returned that will be resolved during the next digest once the animation - * has completed. - * - * @param {DOMElement} element the element which will be inserted into the DOM - * @param {DOMElement} parent the parent element which will append the element as - * a child (so long as the after element is not present) - * @param {DOMElement=} after the sibling element after which the element will be appended - * @param {object=} options an optional collection of options/styles that will be applied to the element. - * The object can have the following properties: - * - * - **addClass** - `{string}` - space-separated CSS classes to add to element - * - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to` - * - **removeClass** - `{string}` - space-separated CSS classes to remove from element - * - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from` - * - * @return {Runner} the animation runner - */ - enter: function(element, parent, after, options) { - parent = parent && jqLite(parent); - after = after && jqLite(after); - parent = parent || after.parent(); - domInsert(element, parent, after); - return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options)); - }, + this.form = form; + this.area = area; + } - /** - * - * @ngdoc method - * @name $animate#move - * @kind function - * @description Inserts (moves) the element into its new position in the DOM either after - * the `after` element (if provided) or as the first child within the `parent` element - * and then triggers an animation. A promise is returned that will be resolved - * during the next digest once the animation has completed. - * - * @param {DOMElement} element the element which will be moved into the new DOM position - * @param {DOMElement} parent the parent element which will append the element as - * a child (so long as the after element is not present) - * @param {DOMElement=} after the sibling element after which the element will be appended - * @param {object=} options an optional collection of options/styles that will be applied to the element. - * The object can have the following properties: - * - * - **addClass** - `{string}` - space-separated CSS classes to add to element - * - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to` - * - **removeClass** - `{string}` - space-separated CSS classes to remove from element - * - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from` - * - * @return {Runner} the animation runner - */ - move: function(element, parent, after, options) { - parent = parent && jqLite(parent); - after = after && jqLite(after); - parent = parent || after.parent(); - domInsert(element, parent, after); - return $$animateQueue.push(element, 'move', prepareAnimateOptions(options)); - }, + this.form.action = this.uri(); - /** - * @ngdoc method - * @name $animate#leave - * @kind function - * @description Triggers an animation and then removes the element from the DOM. - * When the function is called a promise is returned that will be resolved during the next - * digest once the animation has completed. - * - * @param {DOMElement} element the element which will be removed from the DOM - * @param {object=} options an optional collection of options/styles that will be applied to the element. - * The object can have the following properties: - * - * - **addClass** - `{string}` - space-separated CSS classes to add to element - * - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to` - * - **removeClass** - `{string}` - space-separated CSS classes to remove from element - * - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from` - * - * @return {Runner} the animation runner - */ - leave: function(element, options) { - return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() { - element.remove(); - }); - }, + function complete () { + initIframe(); + fn(); + } - /** - * @ngdoc method - * @name $animate#addClass - * @kind function - * - * @description Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon - * execution, the addClass operation will only be handled after the next digest and it will not trigger an - * animation if element already contains the CSS class or if the class is removed at a later step. - * Note that class-based animations are treated differently compared to structural animations - * (like enter, move and leave) since the CSS classes may be added/removed at different points - * depending if CSS or JavaScript animations are used. - * - * @param {DOMElement} element the element which the CSS classes will be applied to - * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces) - * @param {object=} options an optional collection of options/styles that will be applied to the element. - * The object can have the following properties: - * - * - **removeClass** - `{string}` - space-separated CSS classes to remove from element - * - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to` - * - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from` - * - * @return {Runner} animationRunner the animation runner - */ - addClass: function(element, className, options) { - options = prepareAnimateOptions(options); - options.addClass = mergeClasses(options.addclass, className); - return $$animateQueue.push(element, 'addClass', options); - }, + function initIframe () { + if (self.iframe) { + try { + self.form.removeChild(self.iframe); + } catch (e) { + self.onError('jsonp polling iframe removal error', e); + } + } - /** - * @ngdoc method - * @name $animate#removeClass - * @kind function - * - * @description Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon - * execution, the removeClass operation will only be handled after the next digest and it will not trigger an - * animation if element does not contain the CSS class or if the class is added at a later step. - * Note that class-based animations are treated differently compared to structural animations - * (like enter, move and leave) since the CSS classes may be added/removed at different points - * depending if CSS or JavaScript animations are used. - * - * @param {DOMElement} element the element which the CSS classes will be applied to - * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces) - * @param {object=} options an optional collection of options/styles that will be applied to the element. - * The object can have the following properties: - * - * - **addClass** - `{string}` - space-separated CSS classes to add to element - * - **from** - `{Object}` - CSS properties & values at the beginning of animation. Must have matching `to` - * - **to** - `{Object}` - CSS properties & values at end of animation. Must have matching `from` - * - * @return {Runner} the animation runner - */ - removeClass: function(element, className, options) { - options = prepareAnimateOptions(options); - options.removeClass = mergeClasses(options.removeClass, className); - return $$animateQueue.push(element, 'removeClass', options); - }, + try { + // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) + var html = '