├── LICENSE
├── README.md
├── build.sh
├── build
├── assets
│ ├── Blockchair.png
│ ├── QQ.png
│ ├── apple-touch-icon-180x180.png
│ ├── discord.svg
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── logo.png
│ ├── mineros.png
│ ├── qskg.png
│ ├── twitter.png
│ └── twitter.svg
└── font
│ ├── GothamCondensed-Medium-Latin1-2.woff
│ ├── GothamCondensed-Medium-Latin1-2.woff2
│ ├── GothamCondensed-Medium.woff
│ └── GothamCondensed-Medium.woff2
├── critical.js
├── index.html
├── script.js
├── style.css
└── web_miner
├── cn.min.js
├── miner.js
└── worker.js
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 M5M400
4 | Copyright (c) 2019-2020 MoneroOcean
5 | Copyright (c) 2019-2020 C3Pool
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | C3Pool-UI is a lightweight, low resource pool UI for nodejs-pool (by C3Pool ). It is javascript based and is self contained within 4 files + favicon. When minified, total disk size is 76KB with no external dependencies.
2 |
3 | Compatibility
4 | C3Pool-UI requires ECMAScript 5 (Chrome 23, Firefox 21, IE 10, Safari 6, Opera 15). In theory IE9 could work, but Microsoft browsers have already taken up too much of my life.
5 |
6 | Tor in high-security mode blocks svg elements and this UI is entirely svg-based. Tor's other security modes work fine.
7 |
8 | A very optimized font file is used and does not support accents or special characters. See the Language and Localization section to increase compatibility.
9 |
10 | Hosting
11 | C3Pool-UI just needs the web server of your choice to serve favicon.ico and index.html which is a good candidate for Gzip compression.
12 |
13 | The static files are best served on CDN and can have a long cache. This speeds up load times, increases your concurrency and will have some downages go unnoticed.
14 |
15 | Language and Localization
16 | C3Pool-UI automatically localizes decimals, thousand seperators, percent and time formats based on the users browser settings. Language used in the UI has been organized into a single point of configuration to make translation easier.
17 |
18 | There is also an optional font pack provided that extends glyph support to Latin W01 & W02: Albanian (sq), Croatian (hr), Czech (cs), Danish (da), Dutch (nl), English (en), Estonian (et), Finnish (fi), French (fr), German (de), Hungarian (hu), Icelandic (is), Italian (it), Latvian (lv), Lithuanian (lt), Norwegian (nn), Polish (pl), Portuguese (pt), Romanian (ro), Slovak (sk), Slovenian (sl), Spanish (es), Swedish (sv), Turkish (tr), Welsh (cy), Chinese(CN).
19 |
20 | For additional language support you can substitute your own font with the necessary glyphs in the stylesheet. Any condensed sans-serif font will work fine as a substitute and you can optimize the font file for your needs.
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -x
2 | # sudo npm install -g uglifycss uglify-js html-minifier
3 |
4 | uglifycss --output build/style_min.css style.css &&\
5 | uglifyjs --output build/script_min.js script.js web_miner/miner.js &&\
6 | uglifyjs --output build/worker.js web_miner/worker.js &&\
7 | cp web_miner/cn.min.js build/cn.min.js &&\
8 | html-minifier --output build/index-raw.html index.html --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --remove-tag-whitespace --use-short-doctype --minify-css true --minify-js true &&\
9 | node critical.js &&\
10 | rm build/index-raw.html &&\
11 | echo OK
--------------------------------------------------------------------------------
/build/assets/Blockchair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/Blockchair.png
--------------------------------------------------------------------------------
/build/assets/QQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/QQ.png
--------------------------------------------------------------------------------
/build/assets/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/build/assets/discord.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/build/assets/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/favicon-16x16.png
--------------------------------------------------------------------------------
/build/assets/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/favicon-32x32.png
--------------------------------------------------------------------------------
/build/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/favicon.ico
--------------------------------------------------------------------------------
/build/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/logo.png
--------------------------------------------------------------------------------
/build/assets/mineros.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/mineros.png
--------------------------------------------------------------------------------
/build/assets/qskg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/qskg.png
--------------------------------------------------------------------------------
/build/assets/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/assets/twitter.png
--------------------------------------------------------------------------------
/build/assets/twitter.svg:
--------------------------------------------------------------------------------
1 | Twitter_Logo_Blue
--------------------------------------------------------------------------------
/build/font/GothamCondensed-Medium-Latin1-2.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/font/GothamCondensed-Medium-Latin1-2.woff
--------------------------------------------------------------------------------
/build/font/GothamCondensed-Medium-Latin1-2.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/font/GothamCondensed-Medium-Latin1-2.woff2
--------------------------------------------------------------------------------
/build/font/GothamCondensed-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/font/GothamCondensed-Medium.woff
--------------------------------------------------------------------------------
/build/font/GothamCondensed-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/C3Pool/C3Pool-UI/86f048ce837d4d24513bdfbb33dfe0277aef8369/build/font/GothamCondensed-Medium.woff2
--------------------------------------------------------------------------------
/critical.js:
--------------------------------------------------------------------------------
1 | // npm i -D critical@latest
2 |
3 | "use strict";
4 |
5 | var critical = require('critical');
6 |
7 | critical.generate({
8 | inline: true,
9 | base: 'build',
10 | src: './index-raw.html',
11 | dest: './index.html',
12 | minify: false,
13 | width: 1024,
14 | height: 768
15 | });
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 猫池 - 国内首家CPU挖矿综合服务平台
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 猫池 - C3Pool
20 |
21 |
22 |
30 |
31 |
32 |
39 |
40 | --
发现区块
41 | --
矿工
42 | --
已支付
43 |
44 |
45 |
46 |
47 |
54 |
55 |
56 | --
--
57 |
58 | --
--
59 |
60 |
61 |
62 |
63 |
79 |
90 |
91 |
92 |
95 |
--------------------------------------------------------------------------------
/script.js:
--------------------------------------------------------------------------------
1 | var mde = 'l',
2 | $Q = {
3 | pool: {
4 | nme: 'C3Pool', //also sets the cookie prefix
5 | },
6 | clr: {
7 | main: '208b8b', //C1
8 | secondary: '818181', //C2
9 | 'back-l': 'e8e8e8', //C0 - light
10 | 'back-d': '313131' //C0 - dark
11 | },
12 | cur: {
13 | nme: 'Monero',
14 | sym: 'XMR',
15 | conf: 30, // blocks needed to mature
16 | port: 18081,
17 | reg: /^[4|8]{1}([A-Za-z0-9]{105}|[A-Za-z0-9]{94})$/ //address regex
18 | },
19 | api: 'https://api.c3pool.com/',
20 | fiat_name: 'usd',
21 | fiat_symbol: '$',
22 | news: true, //enable news (motd) alerts on homepage
23 | email: true, //enable email notifications
24 | timer: 60, //refresh timer in seconds
25 | pending_days: 30, //time in days pending will reach 0
26 | graph: {
27 | hrs: 72, //max chart length in hours
28 | pplns: false, //show pplns window on chart
29 | },
30 | pay: {
31 | min_auto: 0.003, //minimum for automatic threshold
32 | def_auto: 0.005, //minimum for automatic threshold
33 | max_fee: 0.0001, //max fee (for min_auto)
34 | zero_fee_pay: 4, //theshold that makes fee to be zero
35 | dec_auto: 4 //decimal places for threshold
36 | }
37 | },
38 | $$ = {
39 | calc: {
40 | '1': 'Per Day',
41 | '7': 'Per Week',
42 | '30': 'Per Month',
43 | '365': 'Per Year',
44 | },
45 | page_sizes: [15, 50, 100],
46 | hlp: {
47 | head: 'Welcome to ' + $Q.pool.nme,
48 | text: 'Getting started is easy and this pool has a large and friendly community that are happy to help you. The pool operator can be reached in the Discord , Twitter or at c3pool@outlook.com . Please be patient and someone will get back to you. Most of the time help can be found quicker in the chat. The pool has a quite stable and knowlegable community - you can join the chat and seek help and a friendly chat there :)'
49 | },
50 | msg: {
51 | addr_invalid: {head: 'Invalid '+$Q.cur.nme+' Address', text: 'Double check that your address is complete.'},
52 | addr_nodata: {head: 'No Data', text: ''}
53 | },
54 | nav:{
55 | home: 'Home',
56 | coins: 'Coins',
57 | blocks: 'Blocks',
58 | payments: 'Payments',
59 | help: 'Help'
60 | },
61 | pay:{
62 | DashPending: {lbl: ' ' + $Q.cur.sym + ' Pending', var: 'due', tooltip: 'Total due pool owes you'},
63 | DashPaid: {lbl: $Q.cur.sym + ' Paid', var: 'paid', tooltip: 'Amount pool already paid to you'}
64 | },
65 | wm:{
66 | on: 'Web mining: -- ',
67 | off: 'Run Web Miner',
68 | },
69 | sts: function() { return {
70 | MinerWorkerCount: '
',
71 | MinerHashes: 'Your Hashrate',
72 | MinerShares: 'Shares (Hashes: -- )',
73 | MinerCalc: ' ',
74 | }},
75 | stsw: function() { return { // For worker
76 | MinerHashes: 'Total Hashes',
77 | MinerShares: 'Valid / Invalid Shares',
78 | }},
79 | tbl: {
80 | coins: [
81 | {name: 'name', lbl: 'Name', cls: 'min'},
82 | {name: 'algo', lbl: 'Algo', cls: 'min'},
83 | {name: 'profit', lbl: 'Profit', 'tooltip':'Profit per hash in percent', cls: 'min'},
84 | {name: 'eff', lbl: 'Effort', 'tooltip':'Current block effort in percent', cls: 'min'},
85 | {name: 'reward_perc', lbl: 'Reward', 'tooltip':'Block reward in percent', cls: 'min'},
86 | {name: 'accounts', lbl: 'Accounts', 'tooltip':'Account (Wallet) Count', cls: 'min'},
87 | {name: 'poolhashrate', lbl: 'Hashrate', 'tooltip':'Pool hashrate', cls: 'min'},
88 | {name: 'worldhashrate', lbl: 'World Hash', 'tooltip':'Coin world hashrate', cls: 'min'},
89 | {name: 'height', lbl: 'Top Height', cls: 'min'},
90 | {name: 'pplns', lbl: 'PPLNS', 'tooltip':'Share in last block PPLNS window in percent', cls: 'min'},
91 | {name: 'notes', lbl: 'Notes', cls: 'trunc'},
92 | ],
93 | blocks: [
94 | {name: 'num', lbl: '#', cls: 'min'},
95 | {name: 'tme', lbl: 'Found', cls: 'min'},
96 | {name: 'coin', lbl: 'Coin', cls: 'min'},
97 | {name: 'eff', lbl: 'Effort', cls: 'min'},
98 | {name: 'reward', lbl: 'Raw reward', 'tooltip':'Raw block reward in native coin units', cls: 'min'},
99 | {name: 'payment', lbl: 'Payment ('+$Q.cur.sym+')', cls: 'min'},
100 | {name: 'bheight', lbl: 'Height', cls: 'min'},
101 | {name: 'hash', lbl: 'Hash', typ: 'block', cls: 'trunc'},
102 | ],
103 | poolpay: [
104 | {name: 'tme', lbl: 'Payment Sent', cls: 'min'},
105 | {name: 'payees', lbl: 'Payees', cls: 'min'},
106 | {name: 'amnt', lbl: 'Amount ('+$Q.cur.sym+')', cls: 'min'},
107 | {name: 'fee', lbl: 'Fee ('+$Q.cur.sym+')', cls: 'min'},
108 | {name: 'hash', lbl: 'Tx Hash', typ: 'tx', cls: 'trunc'},
109 | ],
110 | pay: [
111 | {name: 'tme', lbl: 'Payment Sent', cls: 'min'},
112 | {name: 'amnt', lbl: 'Amount ('+$Q.cur.sym+')', cls: 'min'},
113 | {name: 'hash', lbl: 'Tx Hash', typ: 'tx', cls: 'trunc'},
114 | ]
115 | },
116 | trn:{
117 | avgeff: 'Avg Effort',
118 | conf: 'Confirmed',
119 | eff: 'Effort',
120 | eml_on: 'Email Alerts On',
121 | eml_off: 'Email Alerts Off',
122 | min: 'Minimum',
123 | que: 'Payment Queued',
124 | rcnt: 'Recent',
125 | set: 'Update threshold',
126 | updt: 'Threshold updated',
127 | vwpy: 'Show Your Payments'
128 | },
129 | faq: [
130 |
131 | // Advanced worker configuration
132 |
133 | { q: 'What are available pool addresses?',
134 | a: 'We recommend using mine.c3pool.com as primary mining address because it will direct you to the closest alive pool server with the lowest latency. Other pool node servers you can use as backup:'+
135 | ''+
136 | 'asia.c3pool.com : ASIA '+
137 | 'us.c3pool.com : USA '+
138 | ' '
139 | },
140 |
141 | { q: 'Why xmrig miner shows so high ping to C3Pool pool nodes?',
142 | a: 'xmrig miner includes time needed to verify your share into ping number it reports. '+
143 | 'Pool uses external share validator for non-critical shares (the ones that cannot be used to find a block), '+
144 | 'so that is why ping reported by xmrig is high. Critical shares are validated locally, '+
145 | 'so that guarantees that there will be no external share validator delay for them and no orphaned blocks because of this. '+
146 | 'So for our pool usual ping utility provides more accurate results.'
147 | },
148 |
149 | { q: 'What are available pool ports?',
150 | a: 'Pool support many ports that are only different by their starting difficulty. Please select them based on your miner speed:'+
151 | ''+
152 | '80 : 1000 diff (Firewall bypass) '+
153 | '443 : 1000 diff (Firewall bypass) '+
154 | '13333 : 25000 diff (auto-adjust) '+
155 | '14444 : 25000 diff (auto-adjust) '+
156 | '15555 : 50000 diff (auto-adjust) '+
157 | '17777 : 50000 diff (auto-adjust) '+
158 | '19999 : 100000 diff (auto-adjust) '+
159 | '23333 : 1000000 diff (Proxy/NiceHash) '+
160 | '33333 : 15000 diff (SSL) '+
161 | '43333 : 2G diff (ETH port) '+
162 | '53333 : 2G diff (ETH port/SSL/TLS) '+
163 | ' '
164 | },
165 |
166 | // Pool UI
167 |
168 | { q: 'When payments happen?',
169 | a: 'Payments happen automatically in couple of hours when your total due reaches your payment threshold. By default payment threshold is 0.3 XMR but your can lower it in home page miner options.'
170 | },
171 |
172 | { q: 'What does raw hashrate means?',
173 | a: 'Raw hashrate is hashrate your miner produces on algo it mines. Pay hashrate is hashrate that is used to determine how much you will be payed (it is raw hashrate multiplied by profit factors from the coins page).'
174 | },
175 |
176 | { q: 'How set or update your email for notifications?',
177 | a: 'Go to home page miner options, put your new email into Change email TO field and press Email alerts On/Off button. You must correctly fill Change email FROM field if you have email previously set. If you can not remember your previous email please contact pool operator providing your XMR wallet address so he can reset your email address.'
178 | },
179 |
180 | { q: 'Is it possible to open pool home page on specific XMR address?',
181 | a: 'Yes. You can use https://c3pool.com/#/dashboard?addr="xmr_address" link for that. Moreover you can use this address to start web mining immediately without need to click the button: https://c3pool.com/#/dashboard?addr="xmr_address"&web_miner .'
182 | },
183 |
184 | // Algo switching
185 |
186 | { q: 'How pool determines the most profitable coin to mine for my algo switching miner?',
187 | a: 'During login your algo switching miner will report hashrates it can do for all algorithms it support. Pool use that data to offer your miner a coin with the best profit that is determined by multiplication of hashrate of your miner and current coin hash profit.'
188 | },
189 |
190 | { q: 'Can I mine coins supported here using miner that does not support algo switching?',
191 | a: 'Yes. You can do that if you add name of your coin algorithm at the end of miner password field after ~ character, like this: worker_name~k12 . The list of supported algorithms can be found at coins page .'
192 | },
193 |
194 | { q: 'Do I need to have altcoin wallets to mine them here?',
195 | a: 'No. Only Monero wallet is needed because pool does all payments in Monero (XMR).'
196 | },
197 |
198 | { q: 'Am I payed only for the coin blocks I mine?',
199 | a: 'No. Pool pays you your share from every block we find as before. Your pay share like before is based on amount of hashes you submitted in the PPLNS window on the moment block is found. In particulair that means that your are payed even after you stopped mining as long as your shares are within PPLNS window.'
200 | },
201 |
202 | // Solving issues
203 |
204 | { q: 'Can I have payment if I have less than ' + $Q.pay.min_auto + ' XMR?',
205 | a: 'Sorry, no. Minimum payment of ' + $Q.pay.min_auto + ' XMR is hardcoded in the pool code and it is too much mess to workaround it. Please consider to accumulate ' + $Q.pay.min_auto + ' XMR to get payment.'
206 | },
207 |
208 | { q: 'Is there a way to change my wallet address (move total amount due from on wallet to another)?',
209 | a: 'Generally, no. However it can be reviewed on case by case basis if there is enough evidence that you are asking to move money from wallet you own. That includes you knowing email address for that wallet (if it is set); stopping ALL mining activity for at least one week to your old wallet; … other checks that we will not disclose now.'
210 | },
211 |
212 | { q: 'Why my miner recieves pool errors about throttled shares?',
213 | a: 'Because you are connecting too many miners with too low diff. Either increase miner diff or use mining proxy.'
214 | },
215 |
216 | { q: 'What is miner ban policy on this pool?',
217 | a: 'In case of invalid shares pool can use temporary IP based bans that will be automatically removed. '+
218 | 'Permanent XMR address ban can be only issued if we get enough evidence that any wallet address on the pool is used for malware/botnet activities. By enough evidence we mean at least several reports from different sources. And by address ban we mean that workers that try to use this address will be rejected. We do not plan to freeze already mined funds (total due), so they can be retrieved by setting lower payment threshold in home page miner options as usual.'
219 | },
220 | { q: 'Why some of my worker names are replaced by all_other_workers worker?',
221 | a: 'This is because you use too many worker names and to avoid DB / network channel overloads all extra miners are joined under all_other_workers worker name.'
222 | },
223 |
224 | { q: 'Why is the web miner not working (always shows zero hashrate)?',
225 | a: 'Try to use your browser's incognito mode or another browser. Also maybe your are blocked by your malware or antivirus software or by your ISP.'
226 | },
227 |
228 | { q: 'How can I uninstall miner installed using the C3Pool miner setup scripts?',
229 | a: 'On Windows run this command: powershell -Command "$wc = New-Object System.Net.WebClient; $tempfile = [System.IO.Path]::GetTempFileName(); $tempfile += '.bat'; $wc.DownloadFile('https://raw.githubusercontent.com/C3Pool/xmrig_setup/master/uninstall_c3pool_miner.bat', $tempfile); & $tempfile; Remove-Item -Force $tempfile" '+
230 | 'On Linux run this command: curl -s -L https://raw.githubusercontent.com/C3Pool/xmrig_setup/master/uninstall_c3pool_miner.sh | bash -s '
231 | },
232 |
233 | // Fees and donations
234 |
235 | { q: 'Are pool mining fees are really zero?',
236 | a: 'Yes, mining fee is zero. However please note that there is also withdrawal tx fee (that became also zero after 4.0 XMR). There is also small 0.4% -0.6% TradeOgre exchange fee. Also web mining fee is 3% (payed to web miner software developer).'
237 | },
238 |
239 | { q: 'Can I split/donate hashrate of my worker between several Monero addresses?',
240 | a: 'Yes. In your miner config add %percent2%xmr_wallet_address2 after your xmr_wallet_address1 address and pool will split percent2 percent of your hashrate to xmr_wallet_address2 . For example if you want to donate 0.1% of your hashrate to support Monero developers then just add %0.1%44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A after your Monero wallet address. This split happens on per worker basis, so one of your workers can has split enabled and other can work without split.'
241 | },
242 |
243 | { q: 'Are you accepting cryptocurrency donations? What are pool wallet view keys?',
244 | a: 'Yes. Why not =) Every bit helps especially with zero fee mining policy we use. If for some reason you feel grateful to a degree to donate some crypto then here are addresses you can use for that. These wallets are also used by the pool to recieve block rewards, so you can double check we not skimming any blocks by using wallet view keys listed below:'+
245 | ''+
246 | 'XMR : 43987ATFjfFXp9yBojQoifVPK4CerTF7Zaoo4eDY2p6AEp5uewT3PsY7hYHEHvbRivKcexmSaDdXscnnNtveV56pJpCa9uV '+
247 | 'BTC : 3Q4QT5WKMzCh4WqsGF2nKxc8XoLuLLuMqk '+
248 | ' '
249 | },
250 | ]
251 | };
252 |
253 | var COINS = {
254 | 18081: {
255 | name: "XMR",
256 | divisor: 1000000000000,
257 | url: "https://xmrchain.net",
258 | time: 120,
259 | },
260 | 18181: {
261 | name: "XMC",
262 | divisor: 1000000000000,
263 | url: "http://explorer.monero-classic.org",
264 | time: 120,
265 | },
266 | 19734: {
267 | name: "SUMO",
268 | divisor: 1000000000,
269 | url: "https://explorer.sumokoin.com",
270 | time: 240,
271 | },
272 | 12211: {
273 | name: "RYO",
274 | divisor: 1000000000,
275 | url: "https://explorer.ryo-currency.com",
276 | time: 240,
277 | },
278 | 18981: {
279 | name: "GRFT",
280 | divisor: 10000000000,
281 | url: "https://blockexplorer.graft.network",
282 | time: 120,
283 | },
284 | 38081: {
285 | name: "MSR",
286 | divisor: 1000000000000,
287 | url: "https://explorer.getmasari.org",
288 | time: 60,
289 | },
290 | 48782: {
291 | name: "LTHN",
292 | divisor: 100000000,
293 | url: "https://lethean.io/explorer",
294 | time: 120,
295 | },
296 | 34568: {
297 | name: "WOW",
298 | divisor: 100000000000,
299 | url: "http://explore.wownero.com",
300 | time: 300,
301 | },
302 | 19281: {
303 | name: "XMV",
304 | divisor: 100000000000,
305 | url: "https://explorer.monerov.online",
306 | time: 60,
307 | unit: "G",
308 | factor: 16,
309 | },
310 | 9231: {
311 | name: "XEQ",
312 | divisor: 10000,
313 | url: "https://explorer.equilibria.network",
314 | time: 120,
315 | },
316 | 19950: {
317 | name: "XWP",
318 | divisor: 1000000000000,
319 | url: "https://explorer.xwp.one",
320 | time: 15,
321 | unit: "G",
322 | factor: 32,
323 | },
324 | 8766: {
325 | name: "RVN",
326 | divisor: 100000000,
327 | url: "https://ravencoin.network",
328 | time: 60,
329 | unit: "H",
330 | factor: 0xFFFFFFFFFFFFFFFF / 0xFF000000,
331 | },
332 | 8545: {
333 | name: "ETH",
334 | divisor: 1000000000000000000,
335 | url: "https://etherscan.io/",
336 | time: 13,
337 | unit: "H",
338 | factor: 1,
339 | },
340 | 11181: {
341 | name: "AEON",
342 | divisor: 1000000000000,
343 | url: "https://aeonblockexplorer.com",
344 | time: 240,
345 | },
346 | 17750: {
347 | name: "XHV",
348 | divisor: 1000000000000,
349 | url: "https://explorer.havenprotocol.org",
350 | time: 120,
351 | },
352 | 20206: {
353 | name: "DERO",
354 | divisor: 1000000000000,
355 | url: "https://explorer.dero.io",
356 | time: 27,
357 | },
358 | 25182: {
359 | name: "TUBE",
360 | divisor: 1000000000,
361 | url: "https://explorer.bittube.cash",
362 | time: 15,
363 | unit: "G",
364 | factor: 40,
365 | },
366 | 11812: {
367 | name: "XLA",
368 | divisor: 100,
369 | url: "https://explorer.scalaproject.io",
370 | time: 120,
371 | },
372 | 33124: {
373 | name: "XTNC",
374 | divisor: 1000000000,
375 | url: "https://explorer.xtendcash.com",
376 | time: 120,
377 | unit: "G",
378 | factor: 32,
379 | },
380 | 11898: {
381 | name: "TRTL",
382 | divisor: 100,
383 | url: "https://explorer.turtlecoin.lol",
384 | time: 30,
385 | },
386 | 13007: {
387 | name: "IRD",
388 | divisor: 100000000,
389 | url: "https://explorer.ird.cash",
390 | time: 175,
391 | },
392 | 19994: {
393 | name: "ARQ",
394 | divisor: 1000000000,
395 | url: "https://explorer.arqma.com",
396 | time: 120,
397 | },
398 | 16000: {
399 | name: "CCX",
400 | divisor: 1000000,
401 | url: "https://explorer.conceal.network",
402 | time: 120,
403 | },
404 | };
405 |
406 | /*--------------------------------------*/
407 | /*-----End of Customization Section------- (You can customize the rest, but shouldn't need to) */
408 | /*--------------------------------------*/
409 |
410 | var addr = UrlVars().addr || '',
411 | pref = 'LNA',
412 | mport = $Q.cur.port, // shortcut
413 | cookieprefix = $Q.pool.nme.replace(/[ ,;]/g, ''),
414 | resizeTimer,
415 | updateTimer = $Q.timer,
416 | updateCounter,
417 | outoffocus = 0,
418 | now = Rnd((new Date()).getTime() / 1000),
419 | width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
420 | netpop_open = '',
421 | miner_setup_open = false,
422 | blocks_page_size = 15,
423 | poolpay_page_size = 15,
424 | blocks_port = mport,
425 | $WM = { //Web Miner
426 | enabled: false,
427 | addr: '',
428 | prev_hashes: 0,
429 | status_timer: false,
430 | update_sec: 2,
431 | },
432 | $A = {}, //Account Memory
433 | $C = { //Selector Cache
434 | TogMode: '',
435 | Timer: '',
436 | NetStats: '',
437 | Addr: '',
438 | Stage: '',
439 | DashPayBtn: '',
440 | AddrField: '',
441 | TimerPie: '',
442 | TimerText: '',
443 | TimerRefresh: ''
444 | },
445 | $U = { //Update Times
446 | netstats: 0,
447 | poolstats: 0,
448 | news: 0
449 | },
450 | $P = {}, //Promise cache
451 | $L ={ //Localization
452 | perc: '9 %',
453 | thou: ',',
454 | dec: '.',
455 | tme: 'G:i'
456 | },
457 | $D = { //Data Digests
458 | news: {},
459 | coins: [[]],
460 | blocks: [],
461 | poolpay: [],
462 | poolstats: {},
463 | pay: {},
464 | netstats: {},
465 | hashconv: {
466 | TH: 1000000000000,
467 | GH: 1000000000,
468 | MH: 1000000,
469 | KH: 1000,
470 | H: 1
471 | },
472 | miner_hash_avg:0, //Average miner graph number is stored here
473 | },
474 | $I = { //Icons
475 | l: ' ',
476 | d: ' ',
477 | settings: ' ',
478 | loadico: ' ',
479 | arrow: ' ',
480 | check: ' ',
481 | sort: ' ',
482 | refresh: ' ',
483 | x: ' ',
484 | delete: ' ',
485 | };
486 | $I.load = ''+$I.loadico+'
';
487 |
488 | //Event Binding
489 | window.addEventListener('resize', function(){Resize()});
490 |
491 | document.body.addEventListener('change', function(e){
492 | var id = [
493 | '#HeadMenu select', '#TblPagBox', '#AddrField', '#AddrRecent select', '#MinerCalcHsh', '#MinerCalcUnit', '#MinerCalcFld',
494 | '#HashSelect', '#PageSize', '#BlockType', '#AutoPayFld'
495 | ];
496 | for(var i = 0; i < id.length; i++){
497 | var el = e.target.matches(id[i]);
498 | if(el){
499 | if(id[i] === '#HeadMenu select'){
500 | Navigate(document.querySelector(id[i]).value);
501 | }else if(id[i] === '#TblPagBox'){
502 | var pge = parseInt(e.target.value.replace(/\D/g,''));
503 | switch (e.target.getAttribute('data-func')) {
504 | case 'blocks': dta_Blocks(pge); break;
505 | case 'poolpay': dta_Payments(pge); break;
506 | }
507 | }else if(id[i] === '#AddrField' || id[i] === '#AddrRecent select'){
508 | addr = document.querySelector(id[i]).value;
509 | SaveAddr(addr, 'add');
510 | }else if(id[i] === '#MinerCalcHsh' || id[i] === '#MinerCalcUnit' || id[i] === '#MinerCalcFld'){
511 | Dash_calc();
512 | }else if(id[i] === '#HashSelect'){
513 | Dash_load('refresh');
514 | }else if(id[i] === '#PageSize'){
515 | var ps = parseInt(document.querySelector(id[i]).value);
516 | switch (document.getElementById('TblPagBox').getAttribute('data-func')) {
517 | case 'blocks': blocks_page_size = ps; dta_Blocks(1); break;
518 | case 'poolpay': poolpay_page_size = ps; dta_Payments(1); break;
519 | }
520 | }else if(id[i] === '#BlockType'){
521 | blocks_port = parseInt(document.querySelector(id[i]).value);
522 | dta_Blocks(1);
523 | }else if(id[i] === '#AutoPayFld'){
524 | AutoPayCheck();
525 | }
526 | }
527 | }
528 | }, false);
529 | document.body.addEventListener('click', function(e){
530 | var id = [
531 | '#TogMode','#Timer', '#DashPayBtn', '#NetGraphClose', '#NewsClose', '#AutoPayBtn', '#PaymentHistoryBtn', '#WebMinerBtn',
532 | '#PaymentHistoryBtnClose', '#EmailSubscribeBtn', '#AddrDelete', '#WorkerPopClose', '#WorkerSortName', '#WorkerSortRate',
533 | '#MinerSetupShowBtn', '#MinerSetupHideBtn', '#WinCmdTextArea', '#LinCmdTextArea',
534 | '.nav', '.PagBtn', '.Worker', '.blockgroup', '.helptitle', '.helptitle2'
535 | ];
536 | for(var i = 0; i < id.length; i++){
537 | var el = e.target.closest(id[i]);
538 | if(el){
539 | if(id[i] === '#TogMode'){
540 | mde = (mde === 'd') ? 'l' : 'd';
541 | SwitchMode();
542 | SavePref('mode', mde.toUpperCase());
543 | }else if(id[i] === '#Timer'){
544 | TimerLoading('on');
545 | setTimeout(function(){
546 | TimerUpdateData();
547 | }, 1500);
548 | }else if(id[i] === '#DashPayBtn'){
549 | MinerPayments();
550 | }else if(id[i] === '#NetGraphClose'){
551 | netpop_open = '';
552 | document.getElementById('GPop').classList.add('hide');
553 | }else if(id[i] === '#NewsClose'){
554 | document.getElementById('News').className = 'hide';
555 | setCookie('News', $D.news.created);
556 | }else if(id[i] === '#AutoPayBtn'){
557 | AutoPay();
558 | }else if(id[i] === '#PaymentHistoryBtn'){
559 | MinerPaymentHistory(1);
560 | }else if(id[i] === '#PaymentHistoryBtnClose'){
561 | MinerPayments('back');
562 | }else if(id[i] === '#EmailSubscribeBtn'){
563 | EmailSubscribe();
564 | }else if(id[i] === '#WebMinerBtn'){
565 | WebMiner();
566 | }else if(id[i] === '#MinerSetupShowBtn'){
567 | MinerSetupScriptsBtn(true);
568 | }else if(id[i] === '#MinerSetupHideBtn'){
569 | MinerSetupScriptsBtn(false);
570 | }else if(id[i] === '#WinCmdTextArea'){
571 | document.getElementById('WinCmdTextArea').select();
572 | document.execCommand("copy");
573 | }else if(id[i] === '#LinCmdTextArea'){
574 | document.getElementById('LinCmdTextArea').select();
575 | document.execCommand("copy");
576 | }else if(id[i] === '#AddrDelete'){
577 | SaveAddr($C.AddrField.value, 'del');
578 | }else if(id[i] === '#WorkerPopClose'){
579 | Workers_detail();
580 | }else if(id[i] === '#WorkerSortName'){
581 | SavePref('sort', 'N'+el.getAttribute('data-ord'));
582 | Workers_init();
583 | }else if(id[i] === '#WorkerSortRate'){
584 | SavePref('sort', 'R'+el.getAttribute('data-ord'));
585 | Workers_init();
586 | }else if(id[i] === '.nav'){
587 | var tar = el.getAttribute('data-tar');
588 | if (tar == 'old') {
589 | window.location.href = 'https://c3pool.com/oldui';
590 | } else {
591 | Navigate(tar);
592 | }
593 | }else if(id[i] === '.PagBtn'){
594 | var p = parseInt(el.getAttribute('data-page'));
595 | switch (el.getAttribute('data-func')) {
596 | case 'blocks': dta_Blocks(p); break;
597 | case 'poolpay': dta_Payments(p); break;
598 | case 'pay': MinerPaymentHistory(p); break;
599 | }
600 | }else if(id[i] === '.Worker'){
601 | Workers_detail(el.getAttribute('data-key'));
602 | }else if(id[i] === '.helptitle'){
603 | var b = el.querySelector('.btnback'), b_cl = 'btnback', c_cl = 'helpcontent', t_cl = 'helpteaser';
604 | if(b.classList.contains('rot90')){
605 | c_cl += ' hide';
606 | }else{
607 | b_cl += ' rot90';
608 | t_cl += ' hide';
609 | }
610 | b.className = b_cl;
611 | el.parentNode.querySelector('.helpcontent').className = c_cl;
612 | el.parentNode.querySelector('.helpteaser').className = t_cl;
613 | }else if(id[i] === '.helptitle2'){
614 | var b = el.querySelector('.btnback'), b_cl = 'btnback', c_cl = 'helpcontent';
615 | if(b.classList.contains('rot90')){
616 | c_cl += ' hide';
617 | }else{
618 | b_cl += ' rot90';
619 | }
620 | b.className = b_cl;
621 | el.parentNode.querySelector('.helpcontent').className = c_cl;
622 | }else{
623 | return;
624 | }
625 | return;
626 | }
627 | }
628 | }, false);
629 | document.body.addEventListener('keyup', function(e){
630 | if(e.target.closest('#TblPagBox')){
631 | PaginationBoxWidth();
632 | return;
633 | }
634 | });
635 | document.getElementById('Timer').onmouseover = function(e){
636 | $C.TimerRefresh.classList.remove('hide');
637 | };
638 | document.getElementById('Timer').onmouseout = function(e){
639 | $C.TimerRefresh.classList.add('hide');
640 | };
641 |
642 | function init(){
643 | Localize();
644 |
645 | //Cache Selectors
646 | var k = Object.keys($C), i = k.length;
647 | while(i--){
648 | $C[k[i]] = document.getElementById(k[i]);
649 | }
650 |
651 | //Populate Icons
652 | $C.TogMode.innerHTML = $I.d;
653 | $C.TimerRefresh.innerHTML = $I.refresh;
654 | document.getElementById('TimerLoader').innerHTML = $I.load;
655 | document.querySelector('#HeadMenu .select-point').innerHTML = $I.arrow;
656 | document.getElementById('AddrDelete').innerHTML = $I.delete;
657 | document.querySelector('#AddrRecent .select-point').innerHTML = $I.arrow;
658 | document.getElementById('DashPendingLbl').innerHTML = $$.pay.DashPending.lbl;
659 | document.getElementById('DashPaidLbl').innerHTML = $$.pay.DashPaid.lbl;
660 | Dash_btn('loading');
661 | TimerLoading('on');
662 |
663 | //Load Menu
664 | var i = 0, mn = '', ft = '';
665 | for(var m in $$.nav){
666 | mn += ''+$$.nav[m]+' ';
667 | if(i !== 0) ft += ' · ';
668 | ft += ''+$$.nav[m]+' ';
669 | i++;
670 | }
671 | ft += ' · Old UI ';
672 | document.querySelector('#HeadMenu select').innerHTML = mn;
673 | document.getElementById('FootR').innerHTML = ft;
674 |
675 | //User Memory from Cookie
676 | var cka = getCookie('Addr'),
677 | ckp = getCookie('Pref'),
678 | cookie_addr = '';
679 |
680 | if(cka){
681 | if(cka.indexOf('#') >= 0){ //multi address
682 | var ck_arr = cka.split('#');
683 | for(var i = 0; i < ck_arr.length; i++){
684 | if(i === 0) cookie_addr = ck_arr[i];
685 | $A[ck_arr[i]] = {};
686 | }
687 | }else{ //single address
688 | cookie_addr = cka;
689 | $A[cka] = {};
690 | }
691 | }
692 | if(ckp) pref = ckp;
693 |
694 | if(addr){
695 | //override from URL param
696 | }else if(cookie_addr){
697 | //first addr from cookie
698 | addr = cookie_addr;
699 | }
700 | if(addr){
701 | $C.AddrField.value = addr;
702 | $C.AddrField.blur();
703 | }else{
704 | $C.AddrField.setAttribute('placeholder', 'Your '+$Q.cur.nme+' Address...');
705 | }
706 |
707 | if(mde === 'l' && pref && pref.charAt(0) === 'D'){
708 | mde = 'd';
709 | SwitchMode();
710 | }
711 | Dash_init();
712 | TimerUpdateData();
713 | }
714 | function ErrAlert(tar, err){
715 | var n = document.querySelector('#NetGraph svg'),
716 | m = document.querySelector('#MinerGraph svg'),
717 | w = document.getElementById('MinerWorkers'),
718 | a = document.querySelectorAll('.GAlert');
719 |
720 | if(tar === 'X'){
721 | $C.TimerText.innerHTML = updateTimer;
722 | if(n != null) n.classList.remove('o3');
723 | if(m != null) m.classList.remove('o3');
724 | if(w != null) w.classList.remove('o3');
725 | if(a != null && a.parentNode != null) a.parentNode.removeChild(a);
726 | }else{
727 | var msg = '',
728 | iserr = 'C4',
729 | err_msg = 'Try refreshing, check your connection; otherwise we'll be back up soon.';
730 |
731 | if(tar === 'NetStats'){
732 | msg = 'Network API Connection Error';
733 | if(n != null) n.classList.add('o3');
734 |
735 | }else if(tar === 'MinerGraph'){
736 | if(err === 'NoData'){
737 | iserr = 'C2',
738 | msg = 'No Data Available';
739 | err_msg = 'Stats will appear when miner is active.';
740 | }else{
741 | msg = 'Miner API Connection Error';
742 | }
743 | if(m != null) m.classList.add('o3');
744 | if(w != null) w.classList.add('o3');
745 | }else{
746 | return false;
747 | }
748 | if(iserr === 'C4'){
749 | $C.TimerText.innerHTML = ''+$I.x+'
';
750 | $C.TimerRefresh.classList.add('hide');
751 | }
752 | if(msg){
753 | var t = document.getElementById(tar);
754 | if(t != null) t.innerHTML += '';
755 | }
756 | }
757 | }
758 | function LoadTimer(){
759 | clearInterval(updateCounter);
760 | TimerLoading('off');
761 | updateCounter = setInterval(function(){
762 | if(document.hasFocus()){
763 | if(outoffocus > 120){
764 | //if returning after long absence
765 | updateTimer = 0;
766 | outoffocus = 0;
767 | }else{
768 | updateTimer--;
769 | }
770 | }else{
771 | if(outoffocus < 122) outoffocus++;
772 | }
773 | if(updateTimer <= 0){
774 | TimerLoading('on');
775 | clearInterval(updateCounter);
776 | setTimeout(function(){
777 | TimerUpdateData();
778 | }, 1500);
779 | }else{
780 | var clr = (mde === 'd') ? $Q.clr['back-d'] : $Q.clr['back-l'],
781 | grd = 'linear-gradient('+(-90 + (360 * updateTimer / $Q.timer))+'deg, transparent 50%, #208b8b';
782 |
783 | if(updateTimer < ($Q.timer / 2)) grd = 'linear-gradient('+(90 + (360 * updateTimer / $Q.timer))+'deg, transparent 50%, #'+clr;
784 | $C.TimerPie.style.backgroundImage = grd+' 50%),linear-gradient(90deg, #'+clr+' 50%, transparent 50%)';
785 | $C.TimerText.innerHTML = updateTimer;
786 | }
787 | }, 1000);
788 | }
789 | function TimerLoading(sts){
790 | var l = document.getElementById('TimerLoader');
791 | if(sts === 'on'){
792 | l.classList.remove('hide');
793 | }else{
794 | l.classList.add('hide');
795 | }
796 | }
797 | function TimerUpdateData(){
798 | switch (document.querySelector('#HeadMenu select').value) {
799 | case 'home': {
800 | var l = document.getElementById('MinerHashes');
801 | if (l) {
802 | var typ = (l.innerHTML !== '--') ? 'refresh' : '';
803 | Dash_load(typ);
804 | }
805 | } break;
806 | case 'coins': dta_Coins(); break;
807 | case 'blocks': dta_Blocks(parseInt(document.getElementById('TblPagBox').value.replace(/\D/g,''))); break;
808 | case 'payments': dta_Payments(parseInt(document.getElementById('TblPagBox').value.replace(/\D/g,''))); break;
809 | }
810 |
811 | api('netstats').then(function(){
812 | api('poolstats').then(function(){
813 | ErrAlert('X');
814 | document.getElementById('WorldHash').innerHTML = HashConvStr(difficultyToHashRate($D.netstats.difficulty, mport));
815 | document.getElementById('PoolHash').innerHTML = '' + HashConvStr($D.poolstats.hashRate) + ' ';
816 | document.getElementById('CurrEffort').innerHTML =
817 | '' +
818 | Rnd(100 * $D.poolstats.roundHashes / $D.netstats.difficulty, 2, 'txt') + "% ";
819 | document.getElementById('BlockCount').innerHTML =
820 | '' +
821 | ($D.poolstats.totalBlocksFound + $D.poolstats.totalAltBlocksFound) + ' ';
822 | document.getElementById('AccountCount').innerHTML = $D.poolstats.miners;
823 | document.getElementById('PaymentsMade').innerHTML = '' + $D.poolstats.totalPayments + ' ';
824 | updateTimer = $Q.timer;
825 | $C.TimerText.innerHTML = updateTimer;
826 | LoadTimer();
827 | }).catch(function(err){ErrAlert('NetStats', '')});
828 | }).catch(function(err){ErrAlert('NetStats', '')});
829 |
830 | if($Q.news){
831 | var n = document.getElementById('News'), c = document.getElementById('NewsCard'), h = 'clearfix';
832 | if(n != null && c.innerHTML === ''){
833 | api('news').then(function(){
834 | if($D.news && $D.news.created){
835 | if(getCookie('News') == $D.news.created){
836 | h = 'hide';
837 | }else{
838 | c.innerHTML = ''+escapeHtml($D.news.subject)+'
('+AgoTooltip($D.news.created, 'y')+')
'+
839 | ''+escapeHtml($D.news.body)+'
'+
840 | ''+$I.x+'
';
841 | }
842 | n.className = h;
843 | }
844 | });
845 | }
846 | }
847 |
848 | }
849 | function Resize(){
850 | clearTimeout(resizeTimer);
851 | resizeTimer = setTimeout(function(){
852 | width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
853 | Graph_Miner_init();
854 | Workers_init();
855 | var p = document.getElementById('MinerPaymentsPage');
856 | if(p != null) MinerPaymentHistory(p.value);
857 | }, 250);
858 | }
859 | function SwitchMode(){
860 | var $CL = ['C0','C0fl','C0bk','C0st','C3','C3fl','FLD'],
861 | $clr = {l: {f: '454545', b: 'efefef'}, d: {f: 'b3b3b3', b: '1b1b1b'}},
862 | bt = (mde === 'd') ? 'l' : 'd',
863 | i = $CL.length;
864 |
865 | $C.TogMode.innerHTML = $I[bt];
866 | while(i--){
867 | document.querySelectorAll('.'+$CL[i]+bt).forEach(function(x){
868 | x.classList.add($CL[i]+mde);
869 | x.classList.remove($CL[i]+bt);
870 | });
871 | }
872 | document.querySelector('meta[name=theme-color]').setAttribute('content', '#'+$clr[mde].b);
873 | }
874 | function SaveAddr(adr, m){
875 | var fin = '', fst = '', j = 0, val = '';
876 | if(m === 'add'){
877 | if(!$A[adr] || isEmpty($A[adr])) $A[adr] = {};
878 | }else if(m === 'del'){
879 | delete $A[adr];
880 | }else{
881 | return;
882 | }
883 | Dash_reset();
884 | for(var k in $A){
885 | if($A.hasOwnProperty(k) && j < 25){
886 | if(j === 0){
887 | fst = k;
888 | fin += k;
889 | }else{
890 | fin += '#'+k;
891 | }
892 | j++;
893 | }
894 | }
895 | setCookie('Addr', fin);
896 | $C.AddrField.value = (m === 'del') ? fst : adr;
897 | Dash_init();
898 | Dash_load();
899 | MultipleAddress();
900 | }
901 | function SavePref(col, val){
902 | var m = (pref[0] === 'D') ? 'D' : 'L',
903 | s = (pref[1] === 'R') ? 'R' : 'N',
904 | o = (pref[2] === 'D') ? 'D' : 'A',
905 | so = s+o;
906 |
907 | if(col === 'mode'){
908 | m = val;
909 | }else if(col === 'sort'){
910 | so = val;
911 | }
912 | pref = m+so;
913 | setCookie('Pref', m+so);
914 | }
915 | function MultipleAddress(){
916 | var numadr = numObj($A),
917 | r = document.getElementById('AddrRecent'),
918 | h = 'hide';
919 |
920 | if(numadr > 1){
921 | ins = ''+$$.trn.rcnt+' ';
922 | for(var k in $A){
923 | if($A.hasOwnProperty(k) && k !== addr){
924 | ins += ''+k.substring(0, 3)+'...'+k.substr(k.length - 4)+' ';
925 | }
926 | }
927 | r.querySelector('select').innerHTML = ins;
928 | h = '';
929 | }
930 | r.parentNode.className = h;
931 | document.getElementById('AddrDelete').parentNode.className = h;
932 | }
933 | function Navigate(tar){
934 | $C.Stage.className = '';
935 | document.querySelectorAll('.nav').forEach(function(x){
936 | x.classList.remove('o5');
937 | });
938 | setTimeout(function(){
939 | var n = '', m = 'StageFade', h = '', d = 'LR85 C3l';
940 | if(tar && ['coins','blocks','payments','help'].indexOf(tar) >= 0){
941 | n = 'short';
942 | m += ' short';
943 | if (tar != 'coins' && tar != 'help') {
944 | h += '';
945 | } else {
946 | h += '';
947 | }
948 | h += '
'+$I.load+'
';
949 | d += ' hide';
950 | }else{
951 | tar = 'home';
952 | }
953 |
954 | $C.Stage.className = m;
955 | $C.Stage.innerHTML = h;
956 | $C.Addr.className = d;
957 |
958 | switch (tar) {
959 | case 'coins': dta_Coins(); break;
960 | case 'blocks': dta_Blocks(1); break;
961 | case 'payments': dta_Payments(1); break;
962 | case 'help': dta_Help(); break;
963 | default:
964 | Dash_init();
965 | Dash_load();
966 | }
967 |
968 | document.querySelector('#HeadMenu select').value = tar;
969 | document.querySelector('#FootR .nav[data-tar="'+tar+'"]').classList.add('o5');
970 | }, 300);
971 | }
972 | //Dash
973 | function Dash_init(){
974 | var $S = ['SplitL', 'SplitR'],
975 | ins = ''+
976 | '
'+
977 | '
'+
978 | '
'+
979 | '
';
980 |
981 | miner_setup_open = false;
982 |
983 | $C.Stage.innerHTML = ins;
984 |
985 | ins = '';
986 | for(var j = 0; j < 2; j++){
987 | ins += '';
988 | var i = 0;
989 | var sts = $$.sts();
990 | for(var k in sts){
991 | if((j === 0 && i < 2) || (j === 1 && i >= 2)){
992 | ins += '
'+
993 | '
--
'+
994 | '
'+
995 | '
'+sts[k]+'
'+
996 | '
';
997 | }
998 | i++;
999 | }
1000 | ins += '
';
1001 | }
1002 | document.getElementById('MinerDash').innerHTML = ins;
1003 | WebMinerSetBtn();
1004 | var f = document.getElementById('MinerCalcFld'),
1005 | h = document.getElementById('MinerCalcHsh'),
1006 | u = document.getElementById('MinerCalcUnit'),
1007 | hs = document.getElementById('HashSelect');
1008 |
1009 | ins = '';
1010 | for(var k in $$.calc){
1011 | ins += ''+$$.calc[k]+' ';
1012 | }
1013 | f.innerHTML = ins;
1014 | f.className = 'FrmElem txttny C0'+mde+' C1bk';
1015 | ins = '';
1016 | for(var k in $D.hashconv){
1017 | ins += ''+k+'/s ';
1018 | }
1019 | u.innerHTML = ins;
1020 | u.value = 'H';
1021 | u.className = 'FrmElem txttny C0'+mde+' C1bk';
1022 | h.className = 'FrmElem txttny C0'+mde+' C1bk';
1023 | hs.className = 'FrmElem txttny C0'+mde+' C1bk';
1024 | hs.innerHTML = 'Pay Raw ';
1025 | }
1026 | function Dash_load(typ){
1027 | var m = document.getElementById('MinerGraph'),
1028 | l = document.getElementById('WorkerList'),
1029 | g = document.getElementById('MinerDash');
1030 |
1031 | if(addr){
1032 | if($Q.cur.reg.test(addr)){
1033 | $C.AddrField.classList.remove('C4');
1034 | if(typ !== 'refresh'){
1035 | Dash_btn('loading');
1036 | l.innerHTML = $I.load;
1037 | }
1038 | api('account').then(function(){
1039 | if (!is_home_page()) return;
1040 | if($A[addr] && $A[addr].hashes){
1041 | g.classList.remove('hide');
1042 | for(var k in $$.pay){
1043 | var val = $A[addr][$$.pay[k].var], dec = 6;
1044 | if(val > 99999){
1045 | dec = 4;
1046 | }else if(val > 9999){
1047 | dec = 5;
1048 | }
1049 | document.getElementById(k).innerHTML = '' + Rnd(val, dec, 'txt') + ' ';
1050 | }
1051 | document.getElementById('MinerHashes').innerHTML = (now - $A[addr].last) < 10*60
1052 | ? '' + HashConvStr($A[addr][document.getElementById('HashSelect').value == 'raw' ? 'hash' : 'hash2']) + ' '
1053 | : AgoTooltip($A[addr].last, 'y');
1054 | document.getElementById('MinerShares').innerHTML = '' + $A[addr].shares + ' ';
1055 | document.getElementById('TotalHashes').innerHTML = Num($A[addr].hashes);
1056 |
1057 | if(typ !== 'refresh') Dash_btn('loaded');
1058 | Graph_Miner_init();
1059 | MultipleAddress();
1060 |
1061 | api('workers', addr).then(function(){
1062 | if (!is_home_page()) return;
1063 | var wcn = ($A[addr].wrkrs && numObj($A[addr].wrkrs) > 0) ? numObj($A[addr].wrkrs) : 0,
1064 | plr = (wcn === 1) ? '' : 's';
1065 |
1066 | document.getElementById('MinerWorkerCount').innerHTML = wcn+' Worker'+plr;
1067 | l.classList.remove('hide');
1068 | Workers_init();
1069 | }).catch(function(err){console.log(err)});
1070 | }else{
1071 | Dash_reset();
1072 | m.innerHTML =
1073 | 'Address Not Found
' +
1074 | 'If you've submitted your first share, be patient, it may take a minute or two to update. ' +
1075 | 'If your shares are being rejected, visit the
help section. ' +
1076 | 'You can also try to run web miner in this browser using
button but it will not give you full performance of standalone miner.
' +
1077 | 'You can also see generic CPU miner setup script that is good enough in most cases by pressing the button below.
' +
1078 | 'Standalone miner reference setup info:
' +
1079 | 'Pool:
mine.c3pool.com ' +
1080 | 'Port:
13333 ' +
1081 | 'User: ' + addr + '
' +
1082 | 'For top profit algo switching mining use
our version of XMRig miner ' +
1083 | 'and
algo switching mining proxy if your have many miners.
' +
1084 | '
';
1085 | l.classList.add('hide');
1086 | WebMinerSetBtn();
1087 | MinerSetupScriptsBtn(miner_setup_open);
1088 | }
1089 | }).catch(function(err){console.log(err)});
1090 | }else{
1091 | Dash_reset();
1092 | $C.AddrField.classList.add('C4');
1093 | m.innerHTML = ''+$$.msg.addr_invalid.head+'
'+$$.msg.addr_invalid.text+'
';
1094 | }
1095 | }else{
1096 | Dash_reset();
1097 | m.innerHTML =
1098 | 'Welcome to ' + $Q.pool.nme +'
' +
1099 | 'Visit the
help section to get setup, then enter your '+$Q.cur.nme+' address above. ' +
1100 | 'After you've submitted a share, your stats will appear here.
' +
1101 | 'Standalone miner reference setup info:
' +
1102 | 'Pool:
mine.c3pool.com ' +
1103 | 'Port:
13333 ' +
1104 | 'User:
Your XMR wallet address ' +
1105 | 'For top profit algo switching mining use
our version of XMRig miner ' +
1106 | 'and
algo switching mining proxy if your have many miners.
' +
1107 | '
';
1108 | }
1109 | }
1110 | function Dash_reset(){
1111 | Dash_btn('inactive');
1112 | var $R = {
1113 | WorkerList: {v: ''},
1114 | MinerGraph: {v: ''},
1115 | MinerPayments: {r: 'Opened', v: ''},
1116 | },
1117 | k = Object.keys($R);
1118 | for(var i = 0; i < k.length; i++){
1119 | var id = k[i], el = document.getElementById(id);
1120 | el.innerHTML = $R[id].v;
1121 | if($R[id].r) el.classList.remove($R[id].r);
1122 | }
1123 | for(var k in $$.pay){
1124 | var e = document.getElementById(k);
1125 | if(e) e.innerHTML = $$.pay[k].def || '--';
1126 | }
1127 | for(var k in $$.sts()){
1128 | var e = document.getElementById(k);
1129 | if(e) e.innerHTML = '--';
1130 | }
1131 |
1132 | }
1133 | function Dash_btn(m){
1134 | var b = $C.DashPayBtn, c = 'nopoint C2fl o5', h = $I.settings;
1135 | if(m === 'loading'){
1136 | c = 'nopoint';
1137 | h = $I.load;
1138 | }else if(m === 'loaded'){
1139 | c = 'C1fl hov';
1140 | }else if(m === 'closer'){
1141 | c = 'C1fl';
1142 | h = ''+$I.x+'
';
1143 | }
1144 | b.className = c;
1145 | b.innerHTML = h;
1146 | }
1147 | function Dash_calc(){
1148 | var f = document.getElementById('MinerCalcFld'),
1149 | f_val = f.value || 1,
1150 | h = document.getElementById('MinerCalcHsh'),
1151 | h_raw = 0,
1152 | h_val = h.value || 0,
1153 | u = document.getElementById('MinerCalcUnit'),
1154 | u_val = u.value || 'H';
1155 |
1156 | if(h_val && h_val > 0){
1157 | h_raw = h_val * $D.hashconv[u_val];
1158 | }else{
1159 | h_raw = $D.miner_hash_avg;
1160 | }
1161 |
1162 | var hs = HashConv(h_raw);
1163 |
1164 | h_val = hs.num;
1165 | u_val = hs.unit.replace('/s', '');
1166 |
1167 | h.value = h_val;
1168 | u.value = u_val;
1169 | f.value = f_val;
1170 |
1171 | api('netstats').then(function(){
1172 | api('poolstats').then(function(){
1173 | var t = h_raw / difficultyToHashRate($D.netstats.difficulty, mport) * (24*60*60) / COINS[mport].time * $D.poolstats.minBlockRewards[mport] * f.value;
1174 | var fiat = $Q.fiat_symbol + Rnd(t * $D.poolstats.price[$Q.fiat_name], 2, 'txt');
1175 | document.getElementById('MinerCalc').innerHTML = Rnd(t, 4, 'txt')+' '+$Q.cur.sym + " (" + fiat + ")";
1176 | });
1177 | });
1178 | }
1179 | //Workers
1180 | function Workers_init(){ ///check this, getting called alot
1181 | var l = document.getElementById('WorkerList');
1182 | if($A[addr] && $A[addr].wrkrs && l){
1183 | var numwrk = numObj($A[addr].wrkrs),
1184 | i = 0,
1185 | d = '',
1186 | ky = '',
1187 | blkclss = '',
1188 | ins = ''+
1189 | '
'+$I.sort+'
'+
1190 | '
'+$I.sort+'
'+
1191 | '
'+
1192 | '';
1193 |
1194 | srt = (pref.charAt(1) === 'R') ? 'rate' : 'name',
1195 | ord = 'A',
1196 | s = [];
1197 |
1198 | if(['A','D'].indexOf(pref.charAt(2)) >= 0) ord = pref.charAt(2);
1199 |
1200 | for(i = 0; i < numwrk; i++){
1201 | s.push([i, $A[addr].wrkrs[i][srt]]);
1202 | }
1203 | if(srt === 'name'){
1204 | s.sort(function(a, b){return a[1].toLowerCase().localeCompare(b[1].toLowerCase())});
1205 | if(ord === 'D') s.reverse();
1206 | }else if(srt === 'rate'){
1207 | if(ord === 'D'){
1208 | s.sort(function(a, b){return -(a[1] - b[1])});
1209 | }else{
1210 | s.sort(function(a, b){return a[1] - b[1]});
1211 | }
1212 | }
1213 | if(numwrk < 8) blkclss = ' WBlockFewGrid';
1214 | for(i = 0; i < numwrk; i++){
1215 | ky = s[i][0];
1216 | ins += '
'+
1217 | '
'+
1218 | '
--
--
'+
1219 | '
'+
1220 | '
'+
1221 | '
';
1222 | }
1223 | l.innerHTML = ins+'
';
1224 | MinerSetupScriptsBtn(miner_setup_open);
1225 |
1226 | if(numwrk > 0){
1227 | var bwid = document.getElementById('WName-0').clientWidth;
1228 | for(i = 0; i < numwrk; i++){
1229 | document.getElementById('WName-'+s[i][0]).innerHTML = Truncate($A[addr].wrkrs[s[i][0]].name, Rnd(bwid / 6.25));
1230 | }
1231 | }
1232 | if(numwrk > 1){
1233 | document.getElementById('WorkerSortGroup').classList.remove('hide');
1234 | Workers_sort(srt, ord, 'n');
1235 | }
1236 |
1237 | var cnt = 0;
1238 | var hshx = document.getElementById('HashSelect').value == 'raw' ? "hsh" : "hsh2";
1239 | for(i = 0; i < s.length; i++){
1240 | var k = s[i][0],
1241 | d = $A[addr].wrkrs[k],
1242 | hsh = (d && d.stats && d.stats[0] && d.stats[0][hshx]) ? d.stats[0][hshx] : 0;
1243 |
1244 | if(hsh > 0){
1245 | document.getElementById('WRate-'+k).innerHTML = HashConvStr(hsh);
1246 | if(d.stats) Graph_Worker(k);
1247 | }else{
1248 | document.querySelector('.Worker[data-key="'+k+'"]').classList.add('C4','C4br');
1249 | }
1250 | cnt++;
1251 | if(numwrk > 1 && cnt === numwrk) Workers_sort(srt, ord, 'y');
1252 | }
1253 | }
1254 | }
1255 | function Workers_sort(srt, ord, sts){
1256 | var n = document.getElementById('WorkerSortName'),
1257 | n_cl = 'C2bk C0fl'+mde+' hov',
1258 | n_in = $I.sort,
1259 | r = document.getElementById('WorkerSortRate'),
1260 | r_cl = 'C2bk C0fl'+mde+' hov',
1261 | r_in = $I.load,
1262 | ordV = (ord === 'D') ? 'A' : 'D',
1263 | orot = (ord === 'D') ? 'rot90' : 'rot270';
1264 |
1265 | if(sts === 'y'){
1266 | if(srt === 'rate'){
1267 | r_cl = 'C1bk C0fl'+mde+' hov '+orot;
1268 | r_in = $I.arrow;
1269 | }else if(srt === 'name'){
1270 | r_in = $I.sort;
1271 | }
1272 | }else{
1273 | if(srt === 'rate') r_cl = 'C1bk C0fl'+mde+' nopoint';
1274 | }
1275 | if(srt === 'rate'){
1276 | r.setAttribute('data-ord', ordV);
1277 | }else if(srt === 'name'){
1278 | n.setAttribute('data-ord', ordV);
1279 | n_cl = 'C1bk C0fl'+mde+' hov '+orot;
1280 | n_in = $I.arrow;
1281 | }
1282 | n.className = n_cl;
1283 | n.innerHTML = n_in;
1284 | r.className = r_cl;
1285 | r.innerHTML = r_in;
1286 | }
1287 | function Workers_detail(xid){
1288 | if(xid){
1289 | var w = document.querySelector('.Worker[data-key="'+xid+'"]'),
1290 | sts = (w.querySelector('#WorkerPop') != null) ? 'remove' : '';
1291 | }
1292 |
1293 | removeElement('WorkerPop');
1294 | document.querySelectorAll('.Worker').forEach(function(x){
1295 | x.classList.remove('C1');
1296 | x.classList.add('C3'+mde);
1297 | });
1298 |
1299 | if(xid && sts !== 'remove'){
1300 | w.classList.add('C1');
1301 | w.classList.remove('C3'+mde);
1302 | w.innerHTML += '
';
1303 |
1304 | var d = $A[addr].wrkrs[xid],
1305 | p = document.getElementById('WorkerPop');
1306 |
1307 | p.innerHTML = $I.load;
1308 | api('workerdetail', xid, d.name).then(function(){
1309 | var avg = 0,
1310 | havg = 0,
1311 | maxtime = 99999999999999999,
1312 | timestart = maxtime,
1313 | cnt = numObj($A[addr].wrkrs[xid].stats),
1314 | i = cnt;
1315 |
1316 | var hshx = document.getElementById('HashSelect').value == 'raw' ? "hsh" : "hsh2";
1317 | while(i--){
1318 | avg = avg + parseInt($A[addr].wrkrs[xid].stats[i][hshx]);
1319 | SynchTime($A[addr].wrkrs[xid].stats[i].tme);
1320 | if($A[addr].wrkrs[xid].stats[i].tme < timestart) timestart = $A[addr].wrkrs[xid].stats[i].tme;
1321 | }
1322 | p.innerHTML = ''+$I.x+'
'+
1323 | '' + HashConvStr(Rnd(avg / cnt, 0)) + '
'+
1324 | ''+AgoTooltip(d.last, 'y')+'
'+
1325 | '
'+
1326 | 'Avg '+(timestart == maxtime ? "n/a" : AgoTooltip(timestart))+'
'+
1327 | 'Last Share
'+
1328 | '
'+
1329 | ''+Num(d.hashes)+'
'+
1330 | ''+Num(d.val)+' / '+Num(d.inv)+'
'+
1331 | '
'+
1332 | ''+$$.stsw().MinerHashes+'
'+
1333 | ''+$$.stsw().MinerShares+'
';
1334 | }).catch(function(err){console.log(err)});
1335 | }
1336 | }
1337 | //Miner Payments
1338 | function MinerPayments(typ){
1339 | typ = typ || '';
1340 | if(addr && $A[addr] && $A[addr].hashes && $A[addr].hashes > 0){
1341 | var m = document.getElementById('MinerPayments'), n = document.getElementById('NewsBody');
1342 | if(typ !== 'back' && (m.classList.contains('Opened') || m.classList.contains('OpenedBig'))){
1343 | if(n) n.classList.remove('hide');
1344 | m.className = '';
1345 | m.innerHTML = '';
1346 | Dash_btn('loaded');
1347 | return;
1348 | }else{
1349 | if(n) n.classList.add('hide');
1350 | m.className = 'Opened';
1351 | m.innerHTML = '
'+$I.load+'
';
1352 | Dash_btn('closer');
1353 | }
1354 | }else{
1355 | return;
1356 | }
1357 |
1358 | api('user').then(function(){
1359 | var ins = '';
1360 | ins += ''+
1361 | '
'+
1362 | ''+
1363 | ' '+
1364 | '
Auto pay ' + $Q.cur.sym + ' threshold '+
1365 | ' '+
1366 | ''+
1367 | ''+$$.trn.set+'
'+
1368 | '
' + fee_txt($A[addr].threshold) + ' '+
1369 | ' '+
1370 | '
'+
1371 | '
'+
1372 | '
';
1373 | if ($Q.email) {
1374 | var email_enabled = $A[addr].email,
1375 | check = $I[email_enabled ? 'check' : 'x'],
1376 | lbl = $$.trn[email_enabled ? 'eml_on' : 'eml_off'];
1377 | ins += ''+
1378 | '
'+
1379 | '
'+
1380 | '
Change email FROM '+
1381 | '
'+
1382 | '
'+
1383 | '
'+
1384 | '
Change email TO '+
1385 | '
'+
1386 | '
'+
1387 | '
'+
1388 | '
'+check+'
'+
1389 | '
'+lbl+' '+
1390 | '
'+
1391 | '
and change email '+
1392 | '
'+
1393 | '
'+
1394 | '
';
1395 | }
1396 | ins += ''+
1397 | '
'+$$.trn.vwpy+'
'+
1398 | '
';
1399 |
1400 | document.getElementById('MinerPaymentsStage').innerHTML = ins;
1401 | document.getElementById('AutoPayFld').value = Rnd($A[addr].threshold, $Q.pay.dec_auto, 'txt');
1402 | });
1403 | }
1404 | function EmailSubscribe(){
1405 | var ic = document.querySelector('#EmailSubscribeBtn .DiscIcon'),
1406 | txt = document.getElementById('EmailSubscribeLbl');
1407 | ic.classList.add('preload');
1408 | ic.innerHTML = $I.load;
1409 | var status = $A[addr].email;
1410 | var new_status = status ? 0 : 1;
1411 | api('subscribeEmail', {'username':addr, 'enabled':new_status, 'from':document.getElementById('EmailFROM').value, 'to':document.getElementById('EmailTO').value}).then(function(){
1412 | $A[addr].email = new_status;
1413 | var ico = $I[new_status ? 'check' : 'x'],
1414 | lbl = $$.trn[new_status ? 'eml_on' : 'eml_off'];
1415 | ic.classList.remove('preload');
1416 | ic.innerHTML = ico;
1417 | txt.innerHTML = lbl;
1418 | }).catch(function(err){
1419 | if (err != "Connection") {
1420 | ic.classList.remove('preload');
1421 | ic.innerHTML = $I[status ? 'check' : 'x'];
1422 | alert(err);
1423 | }
1424 | });
1425 | }
1426 | function AutoPay(s){
1427 | var c = AutoPayCheck(),
1428 | b = document.getElementById('AutoPayBtn');
1429 |
1430 | if(c === 'OK'){
1431 | b.classList.remove('C1bk','C4bk','C5bk');
1432 | b.innerHTML = $I.load;
1433 | api('updateThreshold', {'username':addr, 'threshold':NumInput(document.getElementById('AutoPayFld').value)}).then(function(){
1434 | b.classList.add('C5bk');
1435 | b.innerHTML = $$.trn.updt;
1436 | });
1437 | }
1438 | }
1439 | function escapeHtml(unsafe) {
1440 | return unsafe
1441 | .replace(/&/g, "&")
1442 | .replace(//g, ">")
1444 | .replace(/"/g, """)
1445 | .replace(/'/g, "'");
1446 | }
1447 | function resize_texareas() {
1448 | var textareaList = document.getElementsByTagName("textarea");
1449 | for(var i = 0; i < textareaList.length; i++){
1450 | var ta = textareaList[i];
1451 | ta.style.height = (ta.scrollHeight + 2) + "px";
1452 | }
1453 | }
1454 |
1455 | function MinerSetupScriptsBtn(show){
1456 | miner_setup_open = show;
1457 | var s = document.getElementById('MinerSetupScripts');
1458 | if (show) {
1459 | var lin_cmd = escapeHtml("curl -s -L https://raw.githubusercontent.com/C3Pool/xmrig_setup/master/setup_c3pool_miner.sh | bash -s " + addr);
1460 | var lin_hlp = escapeHtml('Copy and execute under Linux shell. User with passwordless sudo access is recommended.');
1461 | var win_cmd = escapeHtml("powershell -Command \"$wc = New-Object System.Net.WebClient; $tempfile = [System.IO.Path]::GetTempFileName(); $tempfile += '.bat'; $wc.DownloadFile('https://raw.githubusercontent.com/C3Pool/xmrig_setup/master/setup_c3pool_miner.bat', $tempfile); & $tempfile " + addr + "; Remove-Item -Force $tempfile\"");
1462 | var win_hlp = escapeHtml('Copy and execute under "Command Prompt". Run "Command Prompt" as Administrator is recommended if possible.');
1463 | s.innerHTML = 'Hide Miner Setup Scripts
' +
1464 | '
' +
1465 | '' +
1466 | '
Windows setup command '+
1467 | '
' +
1468 | '' +
1469 | '
Linux setup command ';
1470 | resize_texareas();
1471 | } else {
1472 | s.innerHTML = 'Show Miner Setup Scripts
';
1473 | }
1474 | }
1475 | var web_miner_start = false; // one time check the first time web miner button is shown
1476 | function WebMinerSetBtn(){
1477 | if (web_miner_start === false) {
1478 | web_miner_start = true;
1479 | if (addr && UrlVars().web_miner && $WM.enabled === false) {
1480 | WebMiner();
1481 | return;
1482 | }
1483 | }
1484 | var w = document.getElementById('WebMinerBtn');
1485 | if ($WM.enabled) {
1486 | w.innerHTML = $$.wm.on;
1487 | w.classList.add('glow');
1488 | } else {
1489 | w.innerHTML = $$.wm.off;
1490 | w.classList.remove('glow');
1491 | }
1492 |
1493 | }
1494 | function WebMiner(){
1495 | $WM.enabled = !$WM.enabled;
1496 | WebMinerSetBtn();
1497 | if ($WM.enabled && addr) {
1498 | var threads = navigator.hardwareConcurrency || 4;
1499 | console.log("Starting " + threads + " threads of web miner for " + addr + " address (web_miner worker name)");
1500 | startMining("c3pool.com", addr, "web_miner", navigator.hardwareConcurrency || 4, "");
1501 | $WM.addr = addr;
1502 | $WM.status_timer = setInterval(function () {
1503 | if (addr !== $WM.addr) {
1504 | console.log("Removing web miner timer");
1505 | clearInterval($WM.status_timer);
1506 | $WM.status_timer = false;
1507 | $WM.enabled = false;
1508 | WebMinerSetBtn();
1509 | return;
1510 | }
1511 | // for the definition of sendStack/receiveStack, see miner.js
1512 | while (sendStack.length > 0) console.log(sendStack.pop());
1513 | while (receiveStack.length > 0) console.log(receiveStack.pop());
1514 | var h = document.getElementById('WebMinerHash');
1515 | if (h) h.innerHTML = HashConvStr((totalhashes - $WM.prev_hash) / $WM.update_sec);
1516 | $WM.prev_hash = totalhashes;
1517 | console.log("Calculated " + totalhashes + " hashes");
1518 | }, $WM.update_sec * 1000);
1519 | } else {
1520 | stopMining();
1521 | if ($WM.status_timer) {
1522 | console.log("Removing web miner timer");
1523 | clearInterval($WM.status_timer);
1524 | $WM.status_timer = false;
1525 | }
1526 | }
1527 | }
1528 |
1529 | function fee_txt(threshold) {
1530 | var fee = Math.max(0, $Q.pay.max_fee - ( (threshold - $Q.pay.min_auto) * ($Q.pay.max_fee / ($Q.pay.zero_fee_pay - $Q.pay.min_auto))));
1531 | var percent = 100 * (fee / threshold);
1532 | return '+' + Rnd(fee, 4, 'txt') + ' (' + Rnd(percent, 2, 'txt') + '%) ' + $Q.cur.sym + ' tx fee';
1533 | }
1534 |
1535 | function AutoPayCheck(){
1536 | var b = document.getElementById('AutoPayBtn'),
1537 | b_ins = $$.trn.set,
1538 | f = document.getElementById('AutoPayFld'),
1539 | val_num = NumInput(f.value),
1540 | r = 'err';
1541 |
1542 | b.classList.remove('C1bk','C4bk','C5bk','o5');
1543 | f.classList.remove('C4','C4br');
1544 | if(val_num < $Q.pay.min_auto){
1545 | b.classList.add('C4bk');
1546 | b_ins = $Q.pay.min_auto+' '+$Q.cur.sym+' '+$$.trn.min;
1547 | f.classList.add('C4', 'C4br');
1548 | }else if(val_num >= $Q.pay.min_auto){
1549 | b.classList.add('C1bk');
1550 | r = 'OK';
1551 | var l = document.getElementById('AutoPayFeeLbl');
1552 | l.innerHTML = fee_txt(val_num);
1553 | }else{
1554 | b.classList.add('C1bk', 'o5');
1555 | }
1556 | b.innerHTML = b_ins;
1557 | f.value = Rnd(val_num, $Q.pay.dec_auto, 'txt');
1558 | return r;
1559 | }
1560 | function MinerPaymentHistory(pge){
1561 | pge = (pge > 1) ? pge : 1;
1562 | document.getElementById('MinerPayments').className = 'OpenedBig';
1563 | document.getElementById('PaymentHistory').innerHTML = 'Close Payment History
'+
1564 | '
'+$I.load+'
'+
1565 | ' ';
1566 |
1567 | api('pay', pge, 10).then(function(){
1568 | Tbl('MinerPaymentsTable', 'pay', pge, 10);
1569 | }).catch(function(err){console.log(err)});
1570 | }
1571 |
1572 | //Other Pages
1573 |
1574 | function dta_Coins(){
1575 | api('poolstats').then(function(){ api('netstats').then(function(){
1576 | $D.coins[0] = [];
1577 | var active_ports = {};
1578 | $D.poolstats.activePorts.forEach(function(port) { active_ports[port] = 1; });
1579 | Object.keys(COINS).sort(function (a, b) { return (COINS[a].name < COINS[b].name) ? -1 : 1 }).forEach(function(port) {
1580 | if (!(port in $D.netstats) || !(port in $D.poolstats.coinComment)) return;
1581 | var coin = COINS[port];
1582 | var port_hashrate = $D.poolstats.portHash[port] ? $D.poolstats.portHash[port] : 0;
1583 | var hash_factor = coin.factor ? coin.factor : 1;
1584 | var table_coin = {
1585 | name: coin.name,
1586 | algo: $D.poolstats.portCoinAlgo[port],
1587 | profit: Number.parseFloat($D.poolstats.coinProfit[port] / $D.poolstats.coinProfit[mport] * 100).toPrecision(3) + '%',
1588 | shares: $D.poolstats.currentEfforts[port],
1589 | diff: $D.netstats[port].difficulty,
1590 | reward_perc: Rnd($D.poolstats.minBlockRewards[port] / $D.poolstats.minBlockRewards[mport] * 100, 2, 'txt') + '%',
1591 | accounts: $D.poolstats.portMinerCount[port] ? $D.poolstats.portMinerCount[port] : 0,
1592 | poolhashrate: '' + HashConvStr(port_hashrate * hash_factor, coin.unit) + ' ',
1594 | worldhashrate: HashConvStr($D.netstats[port].difficulty / coin.time * hash_factor, coin.unit),
1595 | height: '' + $D.netstats[port].height + ' ',
1596 | pplns: Rnd(($D.poolstats.pplnsPortShares[port] ? $D.poolstats.pplnsPortShares[port] : 0) * 100, 2, 'txt') + '%',
1597 | notes: '' + escapeHtml($D.poolstats.coinComment[port]) + '
',
1598 | };
1599 | if (!active_ports[port]) ['name', 'algo', 'profit', 'reward_perc', 'accounts', 'poolhashrate', 'worldhashrate', 'pplns'].forEach(function(key) {
1600 | table_coin[key] = '' + table_coin[key] + ' ';
1601 | });
1602 | $D.coins[0].push(table_coin);
1603 | });
1604 | document.getElementById('PageTopL').innerHTML = 'Current PPLNS window length: ' + Rnd($D.poolstats.pplnsWindowTime / 3600, 2, 'txt') + ' hours';
1605 | Tbl('PageBot', 'coins', 0, 0);
1606 | }).catch(function(err){console.log(err)}); }).catch(function(err){console.log(err)});
1607 | }
1608 |
1609 | function dta_Blocks(pge){
1610 | api('poolstats').then(function(){ api('netstats').then(function(){
1611 | var bins = 'Altcoins ';
1612 | Object.keys(COINS).sort(function (a, b) { return (COINS[a].name < COINS[b].name) ? -1 : 1 }).forEach(function(port) {
1613 | var coin = COINS[port];
1614 | bins += '' + coin.name + ' ';
1615 | });
1616 | var blocks_found = blocks_port ? $D.poolstats.altBlocksFound[blocks_port] : $D.poolstats.totalAltBlocksFound;
1617 | document.getElementById('PageTopL').innerHTML = Num(blocks_found)+' ' + bins + ' Blocks ';
1618 | document.getElementById('PageBot').innerHTML = $I.load;
1619 | api('blocks', pge, blocks_page_size).then(function(){
1620 | Tbl('PageBot', 'blocks', pge, blocks_page_size);
1621 | var eff = 0, bnum = 0;
1622 | if ($D.blocks[pge]) $D.blocks[pge].forEach(function(b) { eff += b.shares / b.diff; ++ bnum; });
1623 | var eff_perc = bnum ? Rnd(eff / bnum * 100) : 0;
1624 | document.getElementById('BlockEffort').innerHTML = '('+Perc(eff_perc)+' effort on this page)'
1625 | }).catch(function(err){console.log(err)});
1626 | }).catch(function(err){console.log(err)}); }).catch(function(err){console.log(err)});
1627 | }
1628 | function dta_Payments(pge){
1629 | document.getElementById('PageBot').innerHTML = $I.load;
1630 | api('poolstats').then(function(){
1631 | document.getElementById('PageTopL').innerHTML = Num($D.poolstats.totalPayments)+' Payments to '+Num($D.poolstats.totalMinersPaid)+' Miners';
1632 | api('poolpay', pge, poolpay_page_size).then(function(){
1633 | Tbl('PageBot', 'poolpay', pge, poolpay_page_size);
1634 | }).catch(function(err){console.log(err)});
1635 | }).catch(function(err){console.log(err)});
1636 | }
1637 | function dta_Help(){
1638 | document.getElementById('PageTopL').innerHTML = $$.hlp.head;
1639 | var ins = '' + $$.hlp.text + '
'+
1640 | ''+
1641 | '
Step 1 - Install Wallet & Create Address
'+$I.arrow+'
'+
1642 | '
Start here if you need a Monero address and wallet.
'+
1643 | '
'+
1644 | '
The Official Monero Wallet is recommended. Monero Outreach's Wallet Guide has a list of other wallet options including paper wallets.
'+
1645 | '
'+
1646 | '
'+
1647 | ''+
1648 | '
Step 2 - Install Mining Software
'+$I.arrow+'
'+
1649 | '
Install the software needed to mine Monero.
'+
1650 | '
'+
1651 | '
Select the miner that best suits your hardware and follow their installation instructions. If you need help, visit Discord .
' +
1652 | '
C3 XMRig : for top profit algo switching mining on CPU and GPU (Nvidia, AMD)
' +
1653 | '
XMRig : for mining on CPU and GPU (Nvidia, AMD)
' +
1654 | '
XMR-Stak/RX : for mining on CPU
' +
1655 | '
mm.js : for algo switching miner wrapper (advanced)
' +
1656 | '
Use algo switching mining proxy if you have many miners.
' +
1657 | '
'+
1658 | '
'+
1659 | ''+
1660 | '
Step 3 - Configure Settings
'+$I.arrow+'
'+
1661 | '
Select a pool server and port and configure you miner.
'+
1662 | '
'+
1663 | '
Each mining software will have it's own config, but they will all ask for the same information:
'+
1664 | '
Your Monero Address Often this will be labeled username, but check the instructions.
'+
1665 | '
Pool Address The miner will want a url and a port, like this: mine.c3pool.com:13333
'+
1666 | '
'+
1667 | ''+
1668 | 'Port descriptions:
'+
1669 | '13333 : Old CPU/GPU15555 : Modern CPU/GPU23333 : CPU/GPU farm33333 : SSL/TLS80 : Very old CPU (1000 diff)43333 : ETH PORT (2G diff)53333 : ETH SSL/TLS PORT (2G diff) '+
1670 | ' '+
1671 | ''+
1672 | 'If you can't get through firewall, try these (specify +128000 difficulty after your Monero Address):
'+
1673 | '80 : Firewall bypass443 : Firewall bypass w/SSL/TLS '+
1674 | ' '+
1675 | '
'+
1676 | '
Optional Fields You can also set worker names or fixed difficulty through the configuration.
'+
1677 | '
Standard wallet address(e.g. xmrig.exe -u 43T...sUW -p worker1 )
'+
1678 | '
Fixed difficulty of 128000 for the worker(e.g. xmrig.exe -u 43T...sUW+128000 -p worker1)
'+
1679 | '
'+
1680 | '
'+
1681 | ''+
1682 | '
Step 4 - Start Mining
'+$I.arrow+'
'+
1683 | '
Launch the miner and learn more.
'+
1684 | '
'+
1685 | '
This pool uses PPLNS to determine payouts. It helps to combat pool hopping and ensures a good payout for miners.
'+
1686 | '
' + Perc(0) + ' (yes, Zero!) Pool Fee
'+
1687 | '
' + $Q.pay.min_auto + ' XMR Minimum Payout
'+
1688 | '
' + $Q.cur.conf + ' Block Confirmation Time
'+
1689 | '
'+
1690 | '
'+
1691 | ''+
1692 | '
'+
1693 | '
Check if you have your question answered here.
'+
1694 | '
';
1695 |
1696 | $$.faq.forEach(function(faq) {
1697 | ins += '
'+
1698 | '
' + faq.q + '
'+$I.arrow+'
'+
1699 | '
' + faq.a + '
'+
1700 | '
';
1701 | });
1702 | ins += '
'+
1703 | '
';
1704 |
1705 | document.getElementById('PageBot').innerHTML = ins;
1706 | }
1707 | //Data
1708 | var api = function(m, key, xid){
1709 | now = Rnd((new Date()).getTime() / 1000);
1710 | key = key || 0;
1711 | xid = xid || '';
1712 |
1713 | var i = 0,
1714 | url = '',
1715 | start = now - (3600 * GraphLib_Duration());
1716 |
1717 | if(m === 'news' && now > ($U[m] + 3600)){
1718 | url = 'pool/motd';
1719 | }else if(m === 'blocks'){
1720 | if (blocks_port == mport) {
1721 | url = 'pool/blocks?page='+(key - 1)+'&limit='+xid;
1722 | } else if (blocks_port) {
1723 | url = 'pool/coin_altblocks/' + blocks_port + '?page='+(key - 1)+'&limit='+xid;
1724 | } else {
1725 | url = 'pool/altblocks?page='+(key - 1)+'&limit='+xid;
1726 | }
1727 | }else if(m === 'netstats' && now > ($U[m] + 180)){
1728 | url = 'network/stats';
1729 | }else if(m === 'poolpay'){
1730 | url = 'pool/payments?page='+((key - 1) * xid)+'&limit='+xid;
1731 | }else if(m === 'poolstats' && now > ($U[m] + 180)){
1732 | url = 'pool/stats';
1733 | }else if(m === 'account'){
1734 | url = 'miner/'+addr+'/stats';
1735 | }else if(m === 'pay'){
1736 | url = 'miner/'+addr+'/payments?page='+(key - 1)+'&limit='+xid;
1737 | }else if(m === 'workers' && (isEmpty($A[addr].wrkrs) || now > ($A[addr].wrkrs_updt + 120))){
1738 | url = 'miner/'+addr+'/chart/hashrate/allWorkers';
1739 | }else if(m === 'workerdetail'){
1740 | url = 'miner/'+addr+'/stats/'+xid;
1741 | }else if(m === 'user' && addr){
1742 | url = 'user/'+addr;
1743 | }else if(m === 'updateThreshold'){
1744 | url = 'user/updateThreshold';
1745 | }else if(m === 'subscribeEmail'){
1746 | url = 'user/subscribeEmail';
1747 | }
1748 |
1749 | var method = 'GET', params = '';
1750 | if (['updateThreshold','subscribeEmail'].indexOf(m) >= 0){
1751 | method = 'POST';
1752 | params = JSON.stringify(key);
1753 | }
1754 |
1755 | if (url) {
1756 | if (typeof $P[url] !== 'undefined') return $P[url];
1757 | if (typeof $U[url] !== 'undefined' && method != "POST" && now < $U[url] + 10) url = '';
1758 | }
1759 |
1760 | return $P[url] = new Promise(function (resolve, reject){
1761 | var xhr = new XMLHttpRequest();
1762 | xhr.onreadystatechange = function(){
1763 | if(xhr.readyState !== 4) return;
1764 | if(xhr.status >= 200 && xhr.status < 300){
1765 | var d = (xhr.responseText) ? JSON.parse(xhr.responseText) : '';
1766 | if(d){
1767 | var dcnt = numObj(d);
1768 | //Update Data Times
1769 | if(['netstats','poolstats','news'].indexOf(m) >= 0) $U[m] = now;
1770 | //Process Data
1771 | if(m === 'news'){
1772 | $D[m] = d;
1773 | }else if(['blocks','pay','poolpay'].indexOf(m) >= 0){
1774 | $D[m][key] = [];
1775 | for(i = 0; i < dcnt; i++){
1776 | var v = d[i];
1777 | switch (m) {
1778 | case 'blocks': $D[m][key][i] = v; break;
1779 | case 'pay': $D[m][key][i] = {
1780 | 'ts': v.ts * 1000,
1781 | 'hash': v.txnHash,
1782 | 'amnt': Rnd((v.amount / COINS[mport].divisor), 8)
1783 | }; break;
1784 | case 'poolpay': $D[m][key][i] = {
1785 | 'ts': v.ts,
1786 | 'hash': v.hash,
1787 | 'payees': v.payees,
1788 | 'amnt': Rnd((v.value / COINS[mport].divisor), 8, 'txt'),
1789 | 'fee': Rnd((v.fee / COINS[mport].divisor), 8, 'txt')
1790 | }; break;
1791 | }
1792 | }
1793 | }else if(m === 'netstats'){
1794 | $D[m] = d;
1795 | }else if(m === 'poolstats'){
1796 | $D[m] = d.pool_statistics;
1797 | // unify processing of altBlocksFound later
1798 | $D[m].altBlocksFound[mport] = d.pool_statistics.totalBlocksFound;
1799 | }else if(m === 'account'){
1800 | if(d && d.totalHashes && d.totalHashes > 0){
1801 | if (!$A[addr] || !$A[addr].wrkrs) $A[addr] = {
1802 | stats: {},
1803 | wrkrs: {},
1804 | wrkrs_updt: 0,
1805 | email: 0,
1806 | threshold: ''
1807 | };
1808 | $A[addr].due = Rnd(d.amtDue / COINS[mport].divisor, 8);
1809 | $A[addr].paid = Rnd(d.amtPaid / COINS[mport].divisor, 8);
1810 | $A[addr].hashes = d.totalHashes;
1811 | $A[addr].hash = d.hash;
1812 | $A[addr].hash2 = d.hash2;
1813 | $A[addr].last = d.lastHash;
1814 | $A[addr].shares = Num(d.validShares);
1815 | $A[addr].bad_shares = Num(d.invalidShares);
1816 | }
1817 | }else if(m === 'workers'){
1818 | $A[addr].wrkrs = {};
1819 | var i = 0;
1820 | for (var wname in d) {
1821 | if (wname === 'global') {
1822 | $A[addr].stats = api_GraphFormat(d[wname], numObj(d[wname]), start);
1823 | continue;
1824 | }
1825 | $A[addr].wrkrs[i] = {};
1826 | $A[addr].wrkrs[i].name = wname;
1827 | $A[addr].wrkrs[i].stats = api_GraphFormat(d[wname], numObj(d[wname]), start);
1828 | var stats0 = $A[addr].wrkrs[i].stats[0];
1829 | $A[addr].wrkrs[i].rate = (stats0 && stats0.hsh2) ? stats0.hsh2 : 0; // for sorting
1830 | ++ i;
1831 | }
1832 | $A[addr].wrkrs_updt = now;
1833 | }else if(m === 'workerdetail'){
1834 | $A[addr].wrkrs[key].last = d.lts;
1835 | $A[addr].wrkrs[key].hashes = d.totalHash;
1836 | $A[addr].wrkrs[key].val = (d.validShares > 0) ? d.validShares : 0;
1837 | $A[addr].wrkrs[key].inv = (d.invalidShares > 0) ? d.invalidShares : 0;
1838 | }else if(m === 'user' && d){
1839 | $A[addr].email = d.email_enabled ? 1 : 0;
1840 | var threshold = d.payout_threshold;
1841 | $A[addr].threshold = Rnd(threshold ? threshold / COINS[mport].divisor : $Q.pay.def_auto, 8);
1842 | }
1843 | delete $P[url];
1844 | $U[url] = now;
1845 | resolve(key);
1846 | }else{
1847 | delete $P[url];
1848 | reject('Data');
1849 | console.log(xhr);
1850 | }
1851 | }else{
1852 | delete $P[url];
1853 | var msg;
1854 | if (xhr.responseText) try {
1855 | var json = JSON.parse(xhr.responseText);
1856 | if (json.error) msg = json.error;
1857 | } catch(err) {}
1858 | reject(msg ? msg : 'Connection');
1859 | console.log(xhr);
1860 | }
1861 | };
1862 | if(url){
1863 | xhr.open(method, $Q.api+url, true);
1864 | xhr.setRequestHeader('Content-Type', 'application/json');
1865 |
1866 | if(method === 'POST'){
1867 | xhr.send(params);
1868 | }else{
1869 | xhr.send();
1870 | }
1871 | //console.log('Lookup: '+m+':'+url+' '+method);
1872 | }else{
1873 | //console.log('Skipped: '+m+':'+url);
1874 | delete $P[url];
1875 | resolve(key);
1876 | }
1877 | });
1878 | };
1879 | function api_GraphFormat(d, cnt, start){
1880 | var interval = 15*60,
1881 | r = {},
1882 | r_key = 0,
1883 | r_now = now,
1884 | r_avg = 0,
1885 | r_avg2 = 0,
1886 | r_cnt = 0;
1887 | var prev_tme = now;
1888 | d.sort(function (a, b) { return a.ts < b.ts ? 1 : -1; });
1889 | for (var i = 0; i < cnt; i++) {
1890 | var tme = Rnd(d[i].ts / 1000);
1891 | if (tme < start) break;
1892 | var hsh = (d[i] && d[i].hs && d[i].hs > 0) ? parseInt(d[i].hs) : 0;
1893 | var hsh2 = (d[i] && d[i].hs2 && d[i].hs2 > 0) ? parseInt(d[i].hs2) : 0;
1894 | if (prev_tme - tme < interval) {
1895 | r_avg += hsh;
1896 | r_avg2 += hsh2;
1897 | ++ r_cnt;
1898 | } else {
1899 | r[r_key++] = {'tme':prev_tme, 'hsh': r_cnt ? r_avg / r_cnt : hsh, 'hsh2': r_cnt ? r_avg2 / r_cnt : hsh2};
1900 | if (i < 200 && prev_tme - tme > 2*interval) {
1901 | r[r_key++] = {'tme':prev_tme-1, 'hsh':0, 'hsh2':0};
1902 | r[r_key++] = {'tme':tme+1, 'hsh':0, 'hsh2':0};
1903 | }
1904 | r_avg = 0;
1905 | r_avg2 = 0;
1906 | r_cnt = 0;
1907 | prev_tme = tme;
1908 | }
1909 | }
1910 | for (var i = 0; i < r_key; i++) {
1911 | if (r[i].hsh == 0) continue;
1912 | var r_avg = 0;
1913 | var r_avg2 = 0;
1914 | var r_cnt = 0;
1915 | for (var j = -10; j <= 10; j++) {
1916 | if (i+j < 0 || i+j >= r_key) continue;
1917 | r_avg += r[i+j].hsh;
1918 | r_avg2 += r[i+j].hsh2;
1919 | ++ r_cnt;
1920 | }
1921 | r[i].hsh = r_avg / r_cnt;
1922 | r[i].hsh2 = r_avg2 / r_cnt;
1923 | }
1924 | return r;
1925 | }
1926 | //DataTable
1927 | function Tbl(tar, typ, pge, lim){
1928 | var txt = (width > 900) ? 'txt' : 'txtsmall',
1929 | row = 'ROW0',
1930 | ins = (lim ? '' : '') + '
';
2006 | if (lim) ins +=
2007 | '
'+$I.arrow+'
'+
2008 | '
'+$I.arrow+'
'+
2009 | '
';
2010 |
2011 | document.getElementById(tar).innerHTML = ins;
2012 | if (!$D[typ][pge] || !lim) return;
2013 | var pgs = 0;
2014 | if(tar === 'PageBot'){
2015 | var size, page_size;
2016 | if (typ === 'poolpay') {
2017 | size = $D.poolstats.totalPayments;
2018 | page_size = poolpay_page_size;
2019 | } else if (typ === 'blocks') {
2020 | size = blocks_count;
2021 | page_size = blocks_page_size;
2022 | }
2023 | var ps_ins = "";
2024 | $$.page_sizes.forEach(function(ps){
2025 | ps_ins += '' + ps + ' ';
2026 | });
2027 | pgs = Math.ceil(size / page_size);
2028 | document.getElementById('PageTopR').innerHTML =
2029 | 'Page '+
2030 | ' '+
2031 | 'of '+Num(pgs)+' '+
2032 | '(' + ps_ins + ' per page) ';
2033 | PaginationBoxWidth();
2034 | }
2035 | if(rows > 0){
2036 | var BL = document.getElementById(tar+'-WBL'),
2037 | BR = document.getElementById(tar+'-WBR');
2038 |
2039 | if(pge > 1){
2040 | BL.className = 'WingBtnL PagBtn rot180 C1bk C0fl'+mde;
2041 | BL.setAttribute('data-page', pge - 1);
2042 | BL.setAttribute('data-func', typ);
2043 | }
2044 | if((pgs && pge < pgs) || (!pgs && rows == lim)){
2045 | BR.className = 'WingBtnR PagBtn C1bk C0fl'+mde;
2046 | BR.setAttribute('data-page', pge + 1);
2047 | BR.setAttribute('data-func', typ);
2048 | }
2049 | }
2050 | }
2051 | function PaginationBoxWidth(){
2052 | var b = document.getElementById('TblPagBox'),
2053 | val = b.value.replace(/\D/g,''),
2054 | tot = parseInt(b.getAttribute('data-tot')),
2055 | wid = 18;
2056 |
2057 | if(val > 999){
2058 | wid = (val > 9999) ? 50 : 42;
2059 | if(val > tot) val = tot;
2060 | val = Num(val);
2061 | }else if(val > 99){
2062 | wid = 32;
2063 | }else if(val > 9){
2064 | wid = 24;
2065 | }
2066 | b.style.width = wid+'px';
2067 | b.value = val;
2068 | }
2069 | //Graphing
2070 | function is_home_page() {
2071 | return document.querySelector('#HeadMenu select').value == 'home';
2072 | }
2073 | function Graph_Miner_init(){
2074 | var m = document.getElementById('MinerGraph');
2075 | if(m != null && addr && $A[addr] && $A[addr].hashes){
2076 | m.innerHTML = $I.load;
2077 | if(isEmpty($A[addr].stats)){
2078 | var addr2 = addr;
2079 | api('workers').then(function(){
2080 | if (is_home_page() && addr === addr2) Graph_Miner();
2081 | }).catch(function(err){console.log(err)});
2082 | }else{
2083 | Graph_Miner();
2084 | }
2085 | }
2086 | }
2087 | function Graph_Miner(){
2088 | var ins = '',
2089 | height = 150,
2090 | height_pad = 140,
2091 | timefirst = 999999999999999,
2092 | graphhrs = GraphLib_Duration(),
2093 | timestart = now - (3600 * graphhrs),
2094 | padR = 65,
2095 | right_x = width - padR,
2096 | $H = $A[addr].stats,
2097 | i = 0,
2098 | cnt = numObj($H),
2099 | points = [],
2100 | pts = '',
2101 | avg = 0,
2102 | max = 0,
2103 | yL = 0,
2104 | xR = right_x,
2105 | yR = 0;
2106 |
2107 | var hshx = document.getElementById('HashSelect').value == 'raw' ? "hsh" : "hsh2";
2108 |
2109 | i = cnt;
2110 | while(i--){
2111 | avg = avg + $H[i][hshx];
2112 | if($H[i][hshx] > max) max = $H[i][hshx];
2113 | if($H[i].tme < timefirst) timefirst = $H[i].tme;
2114 | }
2115 | if(max > 0){
2116 | if(timefirst >= timestart) timestart = timefirst;
2117 | max = max * 1.2;
2118 | avg = avg / cnt;
2119 |
2120 | //Create Points
2121 | for(i = 0; i < cnt; i++){
2122 | var x = Rnd(right_x - (now - $H[i].tme) * (right_x / (now - timestart)), 1),
2123 | y = Rnd(height_pad - ($H[i][hshx]) / max * height_pad, 1);
2124 |
2125 | points.push({'x':x, 'y':y, 'tme':$H[i].tme, 'hsh':$H[i][hshx]});
2126 | if(i === 0){
2127 | yL = y;
2128 | }else if(i === (cnt - 1)){
2129 | yR = y;
2130 | }
2131 | }
2132 |
2133 | ins = ''+
2134 | ''+
2135 | ' '+
2136 | ' ';
2137 |
2138 | //Grid Lines
2139 | ins += GraphLib_Grid('line', 5, max, 0, height_pad, width, 'C2');
2140 |
2141 | //Miner Hash Line & Fill
2142 | ins += ' ';
2143 |
2144 | //Miner Hash Lables with Vertical Adjust
2145 | var hsh = HashConv($H[0][hshx]), hs_y = yL + 2, lb_y = yL + 11;
2146 | if(yL > (height_pad * .8)){
2147 | hs_y = yL;
2148 | lb_y = yL - 17;
2149 | }
2150 | ins += ''+Rnd(hsh.num, 1, 'txt')+' '+hsh.unit+' '+
2151 | 'Your Hash ';
2152 |
2153 | //Miner Hash Dots
2154 | for (var i = 0; i < points.length; i++){
2155 | if(i !== 0 && points[i].x > 50){
2156 | ins += ' '+
2157 | ' ';
2158 | }
2159 | }
2160 |
2161 | //MinerHash Avg
2162 | var avg_y = Rnd(height_pad - avg / max * height_pad, 2),
2163 | txt = HashConvStr(avg) + ' Avg ' + Ago(timestart),
2164 | txt_w = txt.length * 5.4;
2165 | if (hshx === "hsh2") $D.miner_hash_avg = avg;
2166 |
2167 | ins += ' '+
2168 | ' '+
2169 | ''+txt+' ';
2170 |
2171 | //Grid Labels
2172 | ins += GraphLib_Grid('lbl', 5, max, 0, height_pad, width, 'C2');
2173 | ins += '0 ';
2174 |
2175 | //Block Tool Tip
2176 | ins += GraphLib_ToolTipSetup();
2177 | ins += ' ';
2178 | document.getElementById('MinerGraph').innerHTML = ins;
2179 | Dash_calc();
2180 | api('account').then(function(){api('poolstats').then(function(){
2181 | var pending_factor = Math.max(($Q.pending_days*24*60*60 - (now - $A[addr].last)) / ($Q.pending_days*24*60*60), 0);
2182 | document.getElementById('PendingPay').innerHTML = Rnd(
2183 | $D.poolstats.pending * $D.miner_hash_avg / $D.poolstats.hashRate * pending_factor,
2184 | 6, 'txt');
2185 | }); });
2186 | GraphLib_ToolTipListener();
2187 | }else{
2188 | ErrAlert('MinerGraph', 'NoData');
2189 | ins = ''+$$.msg.addr_nodata.head+'
';
2190 | }
2191 | }
2192 | function Graph_Worker(xid){
2193 | var WorkerChart = document.querySelector('.WorkerChart[data-worker="'+xid+'"]'),
2194 | width = WorkerChart.clientWidth,
2195 | width3 = width + 3,
2196 | height = 26,
2197 | height3 = 29,
2198 | i = 0,
2199 | max = 0,
2200 | $W = $A[addr].wrkrs[xid].stats,
2201 | wcnt = numObj($W),
2202 | points = [],
2203 | yL = 0,
2204 | yR = 0,
2205 | mintime = 99999999999,
2206 | ins = ''+
2207 | ''+
2208 | ' '+
2209 | ' ';
2210 |
2211 | var hshx = document.getElementById('HashSelect').value == 'raw' ? "hsh" : "hsh2";
2212 |
2213 | for(i = 0; i < wcnt; i++){
2214 | if($W[i][hshx] > max) max = $W[i][hshx];
2215 | if($W[i].tme < mintime) mintime = $W[i].tme;
2216 | }
2217 | if(max > 0){
2218 | for(i = 0; i < wcnt; i++){
2219 | var x = Rnd(width - (now - $W[i].tme) * (width / (now - mintime)), 1),
2220 | y = Rnd(height - $W[i][hshx] * (height / max), 1);
2221 |
2222 | points.push({'x':x, 'y':y});
2223 | if(i === 0){
2224 | yR = y;
2225 | }else if(i === (wcnt - 1)){
2226 | yL = y;
2227 | }
2228 | }
2229 | ins += ' ';
2230 | }
2231 | WorkerChart.innerHTML = ins+' ';
2232 | }
2233 | function GraphLib_Duration(){
2234 | var h = $Q.graph.hrs;
2235 | if(width < 600){
2236 | h = h / 2.5;
2237 | }else if(width < 800){
2238 | h = h / 2;
2239 | }else if(width < 1200){
2240 | h = h / 1.5;
2241 | }
2242 | return h;
2243 | }
2244 | function GraphLib_Grid(m, num, max, min, h, w, cls){
2245 | var r = '';
2246 | if(max > 0){
2247 | var yrt = (max - min) / num, clss = (cls === 'C2') ? '' : mde;
2248 | for(var y = (num - 1); y >= 1; y--){
2249 | var ylc = Rnd(h - (yrt * y / ((max - min) / h)), 1);
2250 | if(m === 'line'){
2251 | r += ' ';
2252 | }else if(m === 'lbl'){
2253 | r += '' + HashConvStr(yrt * y) + ' ';
2254 | }
2255 | }
2256 | }
2257 | return r;
2258 | }
2259 | function GraphLib_ToolTip(el, sts){
2260 | var svg = el.closest('svg.chart'),
2261 | $R = {Tip_Val: {x: 0, y: 999, i: ''}, Tip_Tme: {x: 0, y: 999, i: ''}, Tip_ValBx:{x: 0, y: 999, w: ''}, Tip_TmeBx:{x: 0, y: 999}};
2262 | t_x = parseFloat(el.getAttribute('cx')),
2263 | t_y = parseFloat(el.getAttribute('cy')) + 2,
2264 | tme = parseInt(el.getAttribute('data-tme')),
2265 | t_v = '',
2266 | offset = 0;
2267 |
2268 | if(sts === 'open'){
2269 | if(el.getAttribute('data-eff')){
2270 | t_v = el.getAttribute('data-eff')+'%';
2271 | offset = 9;
2272 | }else if(el.getAttribute('data-hsh')){
2273 | t_v = HashConvStr(el.getAttribute('data-hsh'));
2274 | }
2275 |
2276 | var tmeago = Ago(tme, 'y')+' '+Time(tme),
2277 | v_wid = t_v.length * 6 + offset,
2278 | t_wid = tmeago.length * 5.9 - 3;
2279 |
2280 | $R = {
2281 | 'Tip_Val':{'x':(t_x - (v_wid / 2) - 6), 'y':t_y, 'i':t_v},
2282 | 'Tip_ValBx':{'x':(t_x - v_wid - 6), 'y':(t_y - 11), 'w':v_wid},
2283 | 'Tip_Tme':{'x':(t_x + 7 + (t_wid / 2)), 'y':t_y, 'i':tmeago},
2284 | 'Tip_TmeBx':{'x':(t_x + 7), 'y':(t_y - 11), 'w':t_wid}
2285 | };
2286 | }
2287 | for(var k in $R){
2288 | var e = svg.querySelector('.'+k);
2289 |
2290 | if(e){
2291 | e.setAttribute('x', $R[k].x);
2292 | e.setAttribute('y', $R[k].y);
2293 |
2294 | if($R[k].w) e.setAttribute('width', $R[k].w);
2295 | if($R[k].i) e.innerHTML = $R[k].i;
2296 | }
2297 | }
2298 | }
2299 | function GraphLib_ToolTipSetup(){
2300 | return ' '+
2301 | ' '+
2302 | ' '+
2303 | ' ';
2304 | }
2305 | function GraphLib_ToolTipListener(){
2306 | var b = document.getElementsByClassName('ToolTip');
2307 | for(i = 0; i < b.length; i++){
2308 | b[i].addEventListener('mouseenter', function(){
2309 | GraphLib_ToolTip(this, 'open');
2310 | }, false);
2311 | b[i].addEventListener('mouseleave', function(){
2312 | GraphLib_ToolTip(this, 'close');
2313 | }, false);
2314 | }
2315 | }
2316 | function GraphLib_Bezier(p){
2317 | var h = '';
2318 | if(p && p.length > 0){
2319 | var r = [];
2320 | h = 'M'+p[0].x+', '+p[0].y+' ';
2321 | for (var i = 0; i < p.length - 1; i++) {
2322 | var a = [], b = [];
2323 | //a.push({x:p[Math.max(i - 1, 0)].x, y:p[Math.max(i - 1, 0)].y});
2324 | //a.push({x:p[i].x, y:p[i].y});
2325 | //a.push({x:p[i + 1].x, y: p[i + 1].y});
2326 | //a.push({x:p[Math.min(i + 2, p.length - 1)].x, y:p[Math.min(i + 2, p.length - 1)].y});
2327 | //b.push({x:((-a[0].x + 6 * a[1].x + a[2].x) / 6), y:((-a[0].y + 6 * a[1].y + a[2].y) / 6)});
2328 | //b.push({x:((a[1].x + 6 * a[2].x - a[3].x) / 6), y:((a[1].y + 6 * a[2].y - a[3].y) / 6)});
2329 | //b.push({x:a[2].x, y:a[2].y});
2330 | //r.push(b);
2331 | r.push({x:p[i + 1].x, y: p[i + 1].y});
2332 | }
2333 | for(var i = 0; i < r.length; i++){
2334 | //h += 'C'+Rnd(r[i][0].x, 1)+','+Rnd(r[i][0].y, 1)+' '+Rnd(r[i][1].x, 1)+','+Rnd(r[i][1].y, 1)+' '+Rnd(r[i][2].x, 1)+','+Rnd(r[i][2].y, 1)+' ';
2335 | h += 'L'+Rnd(r[i].x, 1)+','+Rnd(r[i].y, 1)+' ';
2336 | }
2337 | }
2338 | return h;
2339 | }
2340 | //Helpers
2341 | function Localize(){
2342 | var brwlng = window.navigator.userLanguage || window.navigator.language;
2343 | if(brwlng){
2344 | var b = brwlng.split('-');
2345 |
2346 | if(brwlng === 'fr-CA' || ['AL','AR','AT','BY','BE','BO','BR','BG','CL','CO','CR','CU','CY','CZ','DK','EC','EE','FI','FR','DE','GR','GL','HU','IS','ID','IT','LV','LB','LT','MA','NL','NO','PE','PL','PT','RO','RU','RS','SK','SI','ES','SE','CH','TR','UA','UY','VE','VN'].indexOf(b[1]) > -1){
2347 | $L.dec = ',';
2348 | }else if(['IE','MY','PH','SG','TW'].indexOf(b[1]) > -1){
2349 | $L.dec = '·';
2350 | }
2351 | if(brwlng === 'fr-BE' || brwlng === 'fr-CA' || ['AL','AU','BG','CZ','EE','FI','FR','HU','LV','LT','NO','PE','PL','PT','RU','SK','ZA','SE','CH','UA','LK'].indexOf(b[1]) > -1){
2352 | $L.thou = ' ';
2353 | }else if(brwlng === 'de-BE' || ['AR','AT','BA','BR','CL','CO','CR','HR','DK','DE','GR','ID','IT','NL','RO','SI','ES','TR','VN'].indexOf(b[1]) > -1){
2354 | $L.thou = '.';
2355 | }
2356 | if(b[0] === 'en' || b[0] === 'he' || ['CN','CZ','IT','RU'].indexOf(b[1]) > -1){
2357 | $L.perc = '9%';
2358 | }else if(b[1] === 'TR'){
2359 | $L.perc = '%9';
2360 | }
2361 | if(b[0] === 'fr'){
2362 | $L.tme = 'ghi';
2363 | }else if(b[1] === 'DE'){
2364 | $L.tme = 'g.i';
2365 | }else if(brwlng === 'en-CA' || ['AU','BD','EG','IE','IN','MY','MT','MX','NZ','PK','PH','GB','US'].indexOf(b[1]) > -1){
2366 | $L.tme = 'g:i A';
2367 | }
2368 | }
2369 | var tz = new Date().getTimezoneOffset();
2370 | if (tz >= -120 && tz <= 0) {
2371 | $Q.fiat_name = "eur";
2372 | $Q.fiat_symbol = "€"; // EUR symbol
2373 | }
2374 | }
2375 | function isEmpty(o){
2376 | return (o && Object.entries(o).length === 0 && o.constructor === Object) ? true : false;
2377 | }
2378 | function numObj(o){
2379 | return (o && typeof o === 'object' && o !== null) ? Object.keys(o).length : 0;
2380 | }
2381 | function Ago(tme, lbl){
2382 | var t = now - parseInt(tme), r = 0;
2383 | if(t < 60){
2384 | t = t+' Sec';
2385 | }else if(t <= 3600){
2386 | t = Rnd(t / 60)+' Min';
2387 | }else if(t <= 86400){
2388 | r = Rnd(t / 60 / 60);
2389 | t = r+' Hr';
2390 | if(r > 1) t += 's';
2391 | }else{
2392 | r = Rnd(t / 60 / 60 / 24);
2393 | t = r+' Day';
2394 | if(r > 1) t += 's';
2395 | }
2396 | if(lbl === 'y') t += ' Ago';
2397 | return t;
2398 | }
2399 | function Time(tme){
2400 | var r = '';
2401 | if(tme <= 1) return r;
2402 | r = $L.tme;
2403 | var date = new Date(tme * 1000),
2404 | hr24 = date.getHours(),
2405 | hr12 = hr24,
2406 | min = '0'+date.getMinutes(),
2407 | ap = 'am';
2408 | if(hr12 >= 12){
2409 | hr12 = hr12 - 12;
2410 | ap = ' pm';
2411 | }
2412 | r = r.replace('g', hr12);
2413 | r = r.replace('G', hr24);
2414 | r = r.replace('i', min.substr(-2));
2415 | r = r.replace('A', ap);
2416 | return [date.getFullYear(), date.getMonth()+1, date.getDate()].join('/')+' '+r;
2417 | }
2418 | function AgoTooltip(tme, lbl){
2419 | return ''+Ago(tme, lbl)+' ';
2420 | }
2421 | function Perc(n){
2422 | return $L.perc.replace('9', n);
2423 | }
2424 | function Num(n){
2425 | n = n || 0;
2426 | return n.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1'+$L.thou);
2427 | }
2428 | function NumInput(n){
2429 | n = n || 0;
2430 | if(n.indexOf($L.dec) !== -1){
2431 | var na = n.split($L.dec);
2432 | n = na[0].replace(/[^\d]/g, '')+'.'+na[1].replace(/[^\d]/g, '');
2433 | }else{
2434 | n = n.replace(/[^\d]/g, '')+'.0';
2435 | }
2436 | return parseFloat(n);
2437 | }
2438 | function Rnd(n, dec, m){
2439 | if(dec >= 1){
2440 | var d = Math.pow(10, dec);
2441 | n = Math.round(n * d) / d;
2442 | if(m === 'txt'){
2443 | n = n.toFixed(dec);
2444 | if($L.dec !== '.') n = n.replace('.', $L.dec);
2445 | }
2446 | }else{
2447 | n = Math.round(n);
2448 | }
2449 | return n;
2450 | }
2451 | function hashToLink(hash, port, type) {
2452 | if (hash == undefined) return 'none';
2453 | var url = port in COINS ? COINS[port].url : "";
2454 | if (port == 11898) {
2455 | return '' + hash + ' ';
2456 | } else if (port == 11812) {
2457 | return '' + hash + ' ';
2458 | } else if (port == 8545) {
2459 | return '' + hash + ' ';
2460 | } else {
2461 | return '' + hash + ' ';
2462 | }
2463 | };
2464 | function difficultyToHashRate(hashrate, port) {
2465 | return Math.floor(port in COINS ? hashrate / COINS[port].time : 0);
2466 | };
2467 | function HashConv(h){
2468 | h = (h > 0) ? h : 0;
2469 | var u = '/s';
2470 | for(var k in $D.hashconv){
2471 | if(h >= $D.hashconv[k]){
2472 | h = h / $D.hashconv[k];
2473 | u = k+u;
2474 | break;
2475 | }
2476 | }
2477 | if(h === 0) u = 'H/s'
2478 | return {'num':Rnd(h, 2), 'unit':u};
2479 | }
2480 | function HashConvStr(h, unit){
2481 | var h = HashConv(h);
2482 | return h.num + ' ' + (unit ? h.unit.replace(/H\//, unit + '/') : h.unit);
2483 | }
2484 | function InvalidBlock(){
2485 | return 'Orphaned ';
2486 | }
2487 | function SynchTime(t){
2488 | if(t > now) now = t + 3;
2489 | }
2490 | function Truncate(s, l){
2491 | return (s && s.length > 0 && l > 0) ? s.length > l ? s.substring(0, l - 3)+ '...' : s : s;
2492 | }
2493 | function UrlVars(){
2494 | var v = {}, h, p = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
2495 | for(var i = 0; i < p.length; i++){
2496 | h = p[i].split('=');
2497 | v[h[0]] = h[1] ? h[1] : true;
2498 | }
2499 | return v;
2500 | }
2501 | function removeElement(id){
2502 | var e = document.getElementById(id);
2503 | if(e) return e.parentNode.removeChild(e);
2504 | }
2505 | function setCookie(n, v){
2506 | var d = new Date();
2507 | d.setTime(d.getTime() + (365 * 24 * 60 * 60 * 1000));
2508 | document.cookie = cookieprefix+n+'='+(v || '')+'; expires='+d.toUTCString()+'; path=/';
2509 | }
2510 | function getCookie(n){
2511 | var nEQ = cookieprefix+n+'=',
2512 | ca = document.cookie.split(';');
2513 |
2514 | for(var i = 0; i < ca.length; i++){
2515 | var c = ca[i];
2516 | while(c.charAt(0)==' ') c = c.substring(1,c.length);
2517 | if(c.indexOf(nEQ) == 0) return c.substring(nEQ.length,c.length);
2518 | }
2519 | return null;
2520 | }
2521 | function delCookie(n){
2522 | document.cookie = n+'=; Max-Age=-99999999;';
2523 | }
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | @font-face{font-family:'GothamCondensed';src:url(font/GothamCondensed-Medium.woff2) format("woff2"),url(font/GothamCondensed-Medium.woff) format("woff");font-display:swap}
2 | .C0l{color:#efefef}
3 | .C0fll{fill:#efefef}
4 | .C0bkl{background-color:#efefef}
5 | .C0stl{stroke:#efefef}
6 | .C0d{color:#101010}
7 | .C0fld{fill:#101010}
8 | .C0std{stroke:#101010}
9 | .C1{color:#208b8b}
10 | .C1fl{fill:#208b8b}
11 | .C1bk{background-color:#208b8b}
12 | .C1br{border-color:#196b6b!important}
13 | .C1st{stroke:#208b8b}
14 | .C2{color:#196b6b}
15 | .C2fl{fill:#196b6b}
16 | .C2br,.C2br_hov:hover{border-color:#196b6b}
17 | .C2bk,.C2bk_hov:hover{background-color:#196b6b}
18 | .C2st{stroke:#196b6b}
19 | .C3l{color:#454545}
20 | .C3fll{fill:#454545}
21 | .FLDl:-webkit-autofill{-webkit-text-fill-color:#454545}
22 | .C3d{color:#b3b3b3}
23 | .C3fld{fill:#b3b3b3}
24 | .FLDd:-webkit-autofill{-webkit-text-fill-color:#b3b3b3}
25 | .C4{color:rgba(203,10,10,.9)!important}
26 | .C4br{border-color:rgba(203,10,10,.9)!important}
27 | .C4bk{background-color:rgba(203,10,10,.9)}
28 | .C4fl{fill:rgba(203,10,10,.9)}
29 | .C4st{stroke:rgba(203,10,10,.9)}
30 | .C5{color:rgba(95,155,45,.9)}
31 | .C5bk{background-color:rgba(95,155,45,.9)}
32 | .C5fl{fill:rgba(95,155,45,.9)}
33 | html,body{border:0;height:100%;margin:0;min-height:100%;padding:0;width:100%}
34 | body{-webkit-overflow-scrolling:touch;overflow-y:auto}
35 | p{margin:0;padding:0;padding-top:10px}
36 | a:focus{outline:0}
37 | b,.bold{font-weight:700}
38 | table{border-collapse:collapse;border-spacing:0;empty-cells:show;width:100%}
39 | .scroll{display:block;margin-left:auto;margin-right:auto;max-width:1100px;overflow-x:auto}
40 | td{text-align:left;white-space:nowrap}
41 | *{-webkit-tap-highlight-color:transparent}
42 | header,section{margin:0;padding:0}
43 | .LR50{left:25%;position:relative;width:50%}
44 | .LR80{left:10%;position:relative;width:80%}
45 | .LR85{left:7.5%;position:relative;width:85%}
46 | .W95{width:95%}
47 | .shim4{margin:4px 0}
48 | .shim10,.shimtop10{margin-top:10px}
49 | .shim10{margin-bottom:10px}
50 | .shim20,.shimtop20{margin-top:20px}
51 | .shim20{margin-bottom:20px}
52 | .ROW0{background-color:transparent}
53 | .ROW1{background-color:rgba(5,5,5,0.05)}
54 | .ROW0:hover,.ROW1:hover{background-color:rgba(5,5,5,0.1)}
55 | .WingPanel{margin-left:25px;position:relative;width:calc(100% - 50px)}
56 | .WingPanel table td{padding:5px 4px;white-space:nowrap}
57 | #WorkerSortName,#WorkerSortRate,.WingBtnL,.WingBtnR,.WingLblL{border-radius:50%;box-sizing:border-box;height:24px;left:0;margin-left:-29px;padding:4px;position:absolute;top:3px;width:24px}
58 | #WorkerSortRate,.WingBtnR{left:100%;margin-left:5px}
59 | #WorkerSortName{margin-left:-5px}
60 | #WorkerSortRate{margin-left:-20px}
61 | .o3{opacity:.3}
62 | .o7{opacity:.7}
63 | .o8{opacity:.8}
64 | .rot90{-ms-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform:rotate(90deg)}
65 | .rot180{-ms-transform:rotate(180deg);-webkit-transform:rotate(180deg);transform:rotate(180deg)}
66 | .rot270{-ms-transform:rotate(270deg);-webkit-transform:rotate(270deg);transform:rotate(270deg)}
67 | .right{text-align:right}
68 | .center{text-align:center}
69 | .min{padding-left:10px;width:1px}
70 | .trunc{padding-left:10px;width:100%}
71 | .TDPadS td{padding:3px}
72 | .hide{display:none!important}
73 | .clear{clear:both}
74 | .SplitL,.SplitR,.BoxL,.BoxR{box-sizing:border-box;display:inline-block;padding:0 3px;width:50%}
75 | .Split3L,.Split3R,.Split3{box-sizing:border-box;display:inline-block;padding:0 3px;width:33%}
76 | .txtbig,.txtmed{font:28px 'GothamCondensed',san-serif}
77 | .txtmed{font-size:20px}
78 | .txt,.txttny,.txtsmall{font:14px/18px Tahoma,Helvetica,sans-serif}
79 | .txtsmall{font-size:13px;line-height:16px}
80 | .txttny{font-size:10px;line-height:12px}
81 | input:focus,select:focus{outline-color:transparent;outline-style:none}
82 | input:-moz-focusring,select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}
83 | #MinerCalcFld,#MinerCalcUnit,#MinerCalcHsh,#HashSelect{border:0;height:18px;margin:0 1px;padding:2px 1px}
84 | .FLDl,.FLDd{background-color:#efefef;border:0;display:inline-block;padding:8px 5px 7px;width:calc(100% - 4px)}
85 | .FLDl:-webkit-autofill,.FLDl:-webkit-autofill:hover,.FLDl:-webkit-autofill:focus,.FLDl:-webkit-autofill:active{-webkit-box-shadow:0 0 0 30px #efefef inset!important}
86 | .FLDd:-webkit-autofill,.FLDd:-webkit-autofill:hover,.FLDd:-webkit-autofill:focus,.FLDd:-webkit-autofill:active{-webkit-box-shadow:0 0 0 30px #101010 inset!important}
87 | .select-point{height:10px;position:absolute;right:0;top:11px;width:10px}
88 | #AddrRecent select,#HeadMenu select{-moz-appearance:none;-webkit-appearance:none;appearance:none;border:none;outline:none}
89 | .btnback,#DashPayBtn,#Timer,#TogMode{-moz-box-shadow:inset 0 -2px 5px 0 rgba(0,0,0,.06);-webkit-box-shadow:inset 0 -2px 5px 0 rgba(0,0,0,.06);background-color:rgba(19,19,19,.03);box-shadow:inset 0 -2px 5px 0 rgba(0,0,0,.06);overflow:hidden}
90 | .nopoint{cursor:default!important}
91 | .BtnElem,.noselect{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}
92 | .BtnElem,.FrmElem,.BtnDisc{border:0;box-sizing:border-box;display:inline-block;padding:5px 3px;position:relative;text-align:center}
93 | .BtnDisc{border-radius:50%}
94 | .BtnElem,.FrmElem{border-radius:5px}
95 | .BtnElem.DiscMde{padding-left:18px}
96 | .BtnElem .DiscIcon{border-radius:50%;box-sizing:border-box;height:22px;left:5px;padding:4px;position:absolute;top:5px;width:22px;z-index:2}
97 | .Btn16Corner,.Btn24Corner,.Btn32Corner{left:100%;margin-left:-18px;position:absolute;top:2px;z-index:3}
98 | .Btn24Corner{margin-left:-28px;top:4px}
99 | .Btn32Corner{margin-left:-34px;top:4px}
100 | .Btn16,.Btn24,.Btn32{box-sizing:border-box;cursor:pointer;display:inline-block;padding:4px}
101 | .Btn16{height:16px;padding:1px;width:16px}
102 | .Btn24{height:24px;padding:2px;width:24px}
103 | .Btn32{height:32px;width:32px}
104 | .LoadCon{height:30px;left:50%;margin-left:-15px;margin-top:-15px;position:absolute;top:50%;width:30px}
105 | .Loader,.preload{-moz-animation:spin 1s linear infinite;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}
106 | .C0bkd,.FLDd{background-color:#101010}
107 | .C1fl_hov:hover,.C1flim{fill:#208b8b!important}
108 | svg,#WorkerSortRate .preload{height:100%;width:100%}
109 | .o5,.Btn16:hover,.Btn24:hover,.Btn32:hover,.nav:hover,.hov:hover,.PagBtn:hover{opacity:.5}
110 | select,.select-point,.nav,.hov,.C2br_hov,.C2bk_hov,.PagBtn{cursor:pointer}
111 | @-moz-keyframes spin {
112 | 100%{-moz-transform:rotate(360deg)}
113 | }
114 | @-webkit-keyframes spin {
115 | 100%{-webkit-transform:rotate(360deg)}
116 | }
117 | @keyframes spin {
118 | 100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}
119 | }
120 | .hbar,.pbar{background:rgba(0,0,0,.2);background:linear-gradient(90deg,rgba(0,0,0,.01) 0,rgba(0,0,0,.25) 15%,rgba(0,0,0,.35) 50%,rgba(0,0,0,.25) 85%,rgba(0,0,0,.01) 100%);height:1px;position:relative}
121 | .pbar{left:10%;margin-bottom:2px;margin-top:2px;opacity:.6;width:80%}
122 | #TblPagBox{margin:0 5px;position:relative;top:-3px;width:18px}
123 | #PageSize,#BlockType{margin:0 1px;position:relative;top:-3px}
124 | .chart .line{stroke-width:.7}
125 | .chart .mineravgline{stroke-dasharray:4;stroke-width:1}
126 | .ToolTip{cursor:pointer}
127 | .Tip_TmeBx,.Tip_ValBx{stroke-width:.5}
128 | #MinerGraph .ToolTip{cursor:default;fill:transparent}
129 | .GAlert,#GPop{border-radius:5px;border-style:solid;border-width:1px;box-sizing:border-box;position:absolute;top:50%;z-index:9999}
130 | .GAlert{margin-left:25%;margin-right:25%;margin-top:-23px;padding:4px;width:50%}
131 | #GPop{height:53px;left:5%;margin-top:-27px;padding:4px;width:40%}
132 | #GPop.pright{left:55%}
133 | #GPop table td{text-align:center;width:33%}
134 | #MinerGraph{position:relative}
135 | #MinerGraph .mchart{height:150px}
136 | #MinerGraph .MinerMsg{padding-top:25px;text-align:center}
137 | header{height:44px}
138 | #HeadLogo{cursor:pointer;height:20px;margin-left:10px;position:absolute;top:15px;width:128px}
139 | #HeadMenu,#TogMode,#Timer,#TimerRefresh,#TimerLoader{box-sizing:border-box;height:32px;left:100%;padding:5px;position:absolute;top:9px;width:32px}
140 | #HeadMenu{border:0;margin-left:-180px;overflow:hidden;text-align:right;top:9px;width:85px}
141 | #HeadMenu select{box-sizing:border-box;padding:0 14px 0 5px}
142 | #TogMode,#Timer,#TimerRefresh,#TimerLoader,#TimerPie,#TimerDisc{border-radius:50%}
143 | #TogMode{margin-left:-85px}
144 | #Timer{margin-left:-44px;padding:3px}
145 | #TimerDisc,#TimerText{height:88%;left:6%;position:absolute;top:6%;width:88%}
146 | #TimerText{line-height:20px;padding-top:1px;text-align:center;z-index:1}
147 | #TimerText .C4fl{padding-bottom:1px}
148 | #TimerRefresh,#TimerLoader{left:0;top:0;z-index:9}
149 | #TimerLoader{z-index:10}
150 | #Addr{margin:19px 0}
151 | #Addr td{padding:3px;text-align:center}
152 | #Addr .SplitL{width:calc(100% - 305px)}
153 | #Addr .SplitR{width:300px}
154 | #AddrRecent{position:relative;width:60px}
155 | #AddrRecent select{padding:1px 11px 1px 3px;width:100%}
156 | #AddrRecent .select-point{height:8px;right:0;top:5px;width:8px}
157 | #AddrFieldCell{height:34px;position:relative}
158 | #DashPending,#DashPaid{min-width:97px}
159 | #DashPayBtn{border-radius:50%;box-sizing:border-box;display:inline-block;height:45px;padding:8px;position:relative;width:45px}
160 | #DashPayBtn .Loader,#DashPayBtn .Closer,#TimerText div{box-sizing:border-box;padding:3px}
161 | #Stage{-moz-transition:opacity .4s ease-in;-ms-transition:opacity .4s ease-in;-o-transition:opacity .4s ease-in;-webkit-transition:opacity .4s ease-in;min-height:calc(100% - 312px);opacity:0;position:relative;transition:opacity .4s ease-in}
162 | #Stage.short{min-height:calc(100% - 140px)}
163 | .StageFade{opacity:1!important}
164 | #News{background:linear-gradient(0deg,rgba(19,19,19,0.05) 0%,rgba(19,19,19,0) 50%)}
165 | #NewsCard,#NewsBody{box-sizing:border-box}
166 | #NewsCard{border:1px solid rgba(0,0,0,.3);border-radius:5px;min-height:40px;padding:9px 38px 9px 10px;margin-bottom:10px}
167 | #NewsTime{float:right;padding-top:4px}
168 | #NewsBody{padding:10px 0 15px}
169 | #MinerDash{margin-bottom:10px}
170 | #MinerDash .Spl{display:inline-block;text-align:center;width:50%}
171 | #MinerPayments{border-bottom:1px solid rgba(0,0,0,.25);height:0;overflow:hidden;position:relative;transition:height 300ms}
172 | #MinerPayments.Opened{height:250px}
173 | #MinerPayments.OpenedBig{height:550px}
174 | #MinerPayments .LR85{height:calc(100% - 1px)}
175 | #MinerPaymentsStage{height:calc(100% - 1px);position:relative}
176 | #WebMinerBtn{height:20px;width:120px}
177 | #MinerSetupShowBtn,#MinerSetupHideBtn{height:32px;width:50%}
178 | #AutoPayFld,#EmailFROM,#EmailTO{border-style:solid;border-width:1px;height:22px;padding:3px;width:90%}
179 | #AutoPayBtn .preload{display:inline-block;height:22px;width:22px}
180 | #MinerPaymentsStage table{border-color:rgba(0,0,0,.1);border-style:solid;border-width:0 1px;padding:3px}
181 | table.noborder{border-width:0!important}
182 | .WorkerWrap{box-sizing:border-box;float:left;height:65px;padding:5px 4px;position:relative;width:20%}
183 | .Worker,#WorkerPop{border-radius:3px;border-style:solid;border-width:1px}
184 | .Worker .LblL,.Worker .LblR{box-sizing:border-box;display:inline-block;height:30px;padding:2px 3px 4px;text-align:left;width:50%}
185 | .Worker .LblL{width:calc(100% - 75px)}
186 | .Worker .LblR{text-align:right;width:75px}
187 | .WorkerChart{height:26px;position:relative}
188 | #WorkerPop{border-radius:4px;box-sizing:border-box;height:95px;left:0;margin-left:-5px;margin-top:-1px;padding:6px 1px;position:absolute;top:100%;width:calc(100% + 10px);z-index:2}
189 | .WBlockFewGrid{width:50%!important}
190 | .clearfix{overflow:auto}
191 | #PageTopL,#PageTopR{box-sizing:border-box;display:inline-block;height:50px;padding:14px 0 10px;position:relative;width:calc(100% - 245px)}
192 | #PageTopL{min-width:300px}
193 | #PageTopR{float:right;width:240px}
194 | #PageBot{min-height:200px}
195 | .helpgroup{margin-top:20px;padding-bottom:10px;padding-left:25px}
196 | .helpgroup2{margin-top:10px;padding-bottom:5px;padding-left:50px}
197 | .helptitle,.helptitle2{color:#208b8b;cursor:pointer;display:inline-block;fill:#208b8b;position:relative}
198 | .helptitle:hover,.helptitle2:hover{color:#196b6b;fill:#196b6b}
199 | .helptitle .btnback{border-radius:50%;box-sizing:border-box;height:26px;margin-left:-33px;padding:3px;position:absolute;top:-2px;width:26px;z-index:2}
200 | .helptitle2 .btnback{border-radius:50%;box-sizing:border-box;height:20px;margin-left:-26px;padding:3px;position:absolute;top:-2px;width:20px;z-index:2}
201 | .helpteaser,.helpcontent{margin-top:5px}
202 | .footer{bottom:0;left:0;position:relative;width:100%}
203 | #FootL,#FootR{box-sizing:border-box;display:inline-block;padding-top:4px}
204 | #FootL{padding-left:10px;width:200px}
205 | #FootR{padding-right:9px;position:absolute;top:4px;width:calc(100% - 205px)}
206 | #FootR .nav{text-transform:uppercase}
207 | #MinerGraph,#MinerPayments{-moz-box-shadow:inset 0 25px 16px -22px rgba(0,0,0,.06);-webkit-box-shadow:inset 0 25px 16px -22px rgba(0,0,0,.06);box-shadow:inset 0 25px 16px -22px rgba(0,0,0,.06)}
208 | #MinerGraph .chart,.Worker,#MinerPayments{background:rgba(0,0,0,.03);background:linear-gradient(90deg,rgba(0,0,0,.04) 0,rgba(0,0,0,.02) 20%,rgba(0,0,0,.01) 80%,rgba(0,0,0,.03) 100%)}
209 | #TimerPie,.Worker{height:100%;position:relative}
210 | #AutoPayBtn,#PaymentHistoryBtn,#PaymentHistoryBtnClose,#EmailSubscribeBtn{height:32px;width:95%}
211 | #MinerPaymentsTable,#WorkerList{min-height:100px}
212 | @-webkit-keyframes glowing {
213 | 50%{-webkit-box-shadow:0 0 20px #196b6b;background-color:#196b6b}
214 | 0%,100%{-webkit-box-shadow:0 0 3px #208b8b;background-color:#208b8b}
215 | }
216 | @-moz-keyframes glowing {
217 | 50%{-moz-box-shadow:0 0 20px #196b6b;background-color:#196b6b}
218 | 0%,100%{-moz-box-shadow:0 0 3px #208b8b;background-color:#208b8b}
219 | }
220 | @-o-keyframes glowing {
221 | 50%{background-color:#196b6b;box-shadow:0 0 20px #196b6b}
222 | 0%,100%{background-color:#208b8b;box-shadow:0 0 3px #208b8b}
223 | }
224 | @keyframes glowing {
225 | 50%{background-color:#196b6b;box-shadow:0 0 20px #196b6b}
226 | 0%,100%{background-color:#208b8b;box-shadow:0 0 3px #208b8b}
227 | }
228 | .glow{-moz-animation:glowing 1500ms infinite;-o-animation:glowing 1500ms infinite;-webkit-animation:glowing 1500ms infinite;animation:glowing 1500ms infinite}
229 | textarea{resize:none}
230 | @media all and (max-width:1300px) {
231 | .WorkerWrap{width:25%}
232 | }
233 | @media all and (max-width:1100px) {
234 | .LR80{left:9%;width:82%}
235 | .txt{font-size:14px}
236 | }
237 | @media all and (max-width:900px) {
238 | .txtbig{font-size:24px}
239 | .txtmed{font-size:18px}
240 | .txtsmall{font-size:12px;line-height:15px}
241 | #MinerPaymentsStage{left:10%;width:80%}
242 | .condte{width:75px}
243 | .consmall,.continy{width:90px}
244 | .continy{width:50px}
245 | .WorkerWrap{width:33.33%}
246 | #MinerGraph .mchart{height:175px}
247 | #DashPending,#DashPaid{width:80px}
248 | #GPop{width:50%}
249 | #GPop.pright{left:45%}
250 | .LR50{left:20%;width:60%}
251 | .LR80{left:8%;width:84%}
252 | .LR85{left:6.5%;width:87%}
253 | .Split3{padding:6px 0;width:100%!important}
254 | #MinerPayments.Opened{height:320px}
255 | #MinerPayments.OpenedBig{height:620px}
256 | .Split3L,.Split3R{padding:6px 0;width:50%!important}
257 | }
258 | @media all and (max-width:750px) {
259 | .helpcontent{width:100%}
260 | .WorkerWrap{width:50%}
261 | #MinerGraph .mchart{height:150px}
262 | #GPop{width:60%}
263 | #GPop.pright{left:35%}
264 | .LR80{left:7%;width:86%}
265 | .LR85{left:5.5%;width:89%}
266 | .SplitL,.SplitR{padding:6px 0;width:100%!important}
267 | #Addr{margin:19px 0 14px}
268 | #Stage{min-height:calc(100% - 380px)}
269 | }
270 | @media all and (max-width:600px) {
271 | #HeadLogo span{font-size:33px;letter-spacing:-1px}
272 | .txtsmall{font-size:11px;line-height:14px}
273 | #MinerPaymentsStage{left:5%;width:90%}
274 | .condte{width:70px}
275 | .consmall,.continy{width:85px}
276 | .continy{width:50px}
277 | .WBlockFewGrid{width:100%!important}
278 | .LR50{left:10%;width:80%}
279 | .LR80{left:6%;width:88%}
280 | .LR85{left:4.5%;width:91%}
281 | }
282 | @media all and (max-width:500px) {
283 | #HeadLogo span{font-size:33px;letter-spacing:-1px}
284 | #GPop{width:70%}
285 | #GPop.pright{left:25%}
286 | .WorkerWrap{width:100%}
287 | .LR80{left:4%;width:92%}
288 | .LR85{left:2.5%;width:95%}
289 | #MinerPayments.Opened{height:400px}
290 | #MinerPayments.OpenedBig{height:700px}
291 | .Split3L,.Split3R{padding:6px 0;width:100%!important}
292 | }
293 | svg .txtmed{font-size:20px}
--------------------------------------------------------------------------------
/web_miner/miner.js:
--------------------------------------------------------------------------------
1 | /* very simple monero miner for the webminerpool server */
2 |
3 | var server = "wss://webminer.c3pool.com:443/"
4 |
5 | var job = null; // remember last job we got from the server
6 | var workers = []; // keep track of our workers
7 | var ws; // the websocket we use
8 |
9 | /* state variables */
10 |
11 | var receiveStack = []; // everything we get from the server
12 | var sendStack = []; // everything we send to the server
13 | var totalhashes = 0; // number of hashes calculated
14 | var connected = 0; // 0->disconnected, 1->connected, 2->disconnected (error), 3->disconnect (on purpose)
15 | var reconnector = 0; // regular check if the WebSocket is still connected
16 | var attempts = 1;
17 |
18 | var throttleMiner = 0; // percentage of miner throttling. If you set this to 20, the
19 | // cpu workload will be approx. 80% (for 1 thread / CPU).
20 | // setting this value to 100 will not fully disable the miner but still
21 | // calculate hashes with 10% CPU load. See worker.js for details.
22 |
23 | var handshake = null;
24 |
25 | function wasmSupported() {
26 | try {
27 | if (typeof WebAssembly === "object"
28 | && typeof WebAssembly.instantiate === "function") {
29 | var module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
30 | if (module instanceof WebAssembly.Module)
31 | return new WebAssembly.Instance(module) instanceof WebAssembly.Instance;
32 | }
33 | } catch (e) { }
34 | return false;
35 | }
36 |
37 | function addWorkers(numThreads) {
38 | logicalProcessors = numThreads;
39 |
40 | if (numThreads == -1) {
41 |
42 | /* try to find a good value */
43 |
44 | try {
45 | logicalProcessors = window.navigator.hardwareConcurrency;
46 | } catch (err) {
47 | logicalProcessors = 4;
48 | }
49 |
50 | if (!((logicalProcessors > 0) && (logicalProcessors < 40)))
51 | logicalProcessors = 4;
52 | }
53 |
54 |
55 | while (logicalProcessors-- > 0) addWorker();
56 | }
57 |
58 | var openWebSocket = function () {
59 |
60 | if (ws != null) {
61 | ws.close();
62 | }
63 |
64 | var splitted = server.split(";")
65 | var chosen = splitted[Math.floor(Math.random() * splitted.length)];
66 |
67 | ws = new WebSocket(chosen);
68 |
69 | ws.onmessage = on_servermsg;
70 | ws.onerror = function (event) {
71 | if (connected < 2) connected = 2;
72 | job = null;
73 | }
74 | ws.onclose = function () {
75 | if (connected < 2) connected = 2;
76 | job = null;
77 | }
78 |
79 | ws.onopen = function () {
80 | ws.send((JSON.stringify(handshake)));
81 | attempts = 1;
82 | connected = 1;
83 | }
84 |
85 | };
86 |
87 | reconnector = function () {
88 | if (connected !== 3 && (ws == null || (ws.readyState !== 0 && ws.readyState !== 1))) {
89 | //console.log("The WebSocket is not connected. Trying to connect.");
90 | attempts++;
91 | openWebSocket();
92 | }
93 |
94 | if (connected !== 3)
95 | setTimeout(reconnector, 10000 * attempts);
96 | };
97 |
98 | // broadcast logic
99 | function startBroadcast(mining) {
100 | if (typeof BroadcastChannel !== "function") {
101 | mining(); return;
102 | }
103 |
104 | stopBroadcast();
105 |
106 | var bc = new BroadcastChannel('channel');
107 |
108 | var number = Math.random();
109 | var array = [];
110 | var timerc = 0;
111 | var wantsToStart = true;
112 |
113 | array.push(number);
114 |
115 | bc.onmessage = function (ev) {
116 | if (array.indexOf(ev.data) === -1) array.push(ev.data);
117 | }
118 |
119 | function checkShouldStart() {
120 |
121 | bc.postMessage(number);
122 |
123 | timerc++;
124 |
125 | if (timerc % 2 === 0) {
126 | array.sort();
127 |
128 | if (array[0] === number && wantsToStart) {
129 | mining();
130 | wantsToStart = false;
131 | number = 0;
132 | }
133 |
134 | array = [];
135 | array.push(number);
136 | }
137 |
138 | }
139 |
140 | startBroadcast.bc = bc;
141 | startBroadcast.id = setInterval(checkShouldStart, 1000);
142 | }
143 |
144 | function stopBroadcast() {
145 | if (typeof startBroadcast.bc !== 'undefined') {
146 | startBroadcast.bc.close();
147 | }
148 |
149 | if (typeof startBroadcast.id !== 'undefined') {
150 | clearInterval(startBroadcast.id);
151 | }
152 |
153 | }
154 | // end logic
155 |
156 | // starts mining
157 | function startMiningWithId(loginid, numThreads, userid) {
158 |
159 | if (!wasmSupported()) return;
160 |
161 | stopMining();
162 | connected = 0;
163 |
164 | handshake = {
165 | identifier: "handshake",
166 | loginid: loginid,
167 | userid: userid,
168 | version: 7
169 | };
170 |
171 | var foo = function() { addWorkers(numThreads); reconnector(); };
172 | startBroadcast(foo);
173 | }
174 |
175 | // starts mining
176 | function startMining(pool, login, password, numThreads, userid) {
177 |
178 | if (!wasmSupported()) return;
179 |
180 | stopMining();
181 | connected = 0;
182 |
183 | handshake = {
184 | identifier: "handshake",
185 | pool: pool,
186 | login: login,
187 | password: password,
188 | userid: userid,
189 | version: 7
190 | };
191 |
192 | var foo = function() { addWorkers(numThreads); reconnector(); };
193 | startBroadcast(foo);
194 | }
195 |
196 | // stop mining
197 | function stopMining() {
198 |
199 | connected = 3;
200 |
201 | if (ws != null) ws.close();
202 | deleteAllWorkers();
203 | job = null;
204 |
205 | stopBroadcast();
206 | }
207 |
208 | // add one worker
209 | function addWorker() {
210 | var newWorker = new Worker("worker.js");
211 | workers.push(newWorker);
212 |
213 | newWorker.onmessage = on_workermsg;
214 |
215 | setTimeout(function () {
216 | informWorker(newWorker);
217 | }, 2000);
218 | }
219 |
220 | // remove one worker
221 | function removeWorker() {
222 | if (workers.length < 1) return;
223 | var wrk = workers.shift();
224 | wrk.terminate();
225 | }
226 |
227 | /* "internal" functions */
228 |
229 | function deleteAllWorkers() {
230 | for (i = 0; i < workers.length; i++) {
231 | workers[i].terminate();
232 | }
233 | workers = [];
234 | }
235 |
236 | function informWorker(wrk) {
237 | var evt = {
238 | data: "wakeup",
239 | target: wrk
240 | };
241 | on_workermsg(evt);
242 | }
243 |
244 | function on_servermsg(e) {
245 | var obj = JSON.parse(e.data);
246 |
247 | receiveStack.push(obj);
248 |
249 | if (obj.identifier == "job") job = obj;
250 | }
251 |
252 | function on_workermsg(e) {
253 | var wrk = e.target;
254 |
255 | if (connected != 1) {
256 | setTimeout(function () {
257 | informWorker(wrk);
258 | }, 2000);
259 | return;
260 | }
261 |
262 | if ((e.data) != "nothing" && (e.data) != "wakeup") {
263 | // we solved a hash. forward it to the server.
264 | var obj = JSON.parse(e.data);
265 | ws.send(e.data);
266 | sendStack.push(obj);
267 | }
268 |
269 | if (job === null) {
270 | setTimeout(function () {
271 | informWorker(wrk);
272 | }, 2000);
273 | return;
274 | }
275 |
276 | var jbthrt = {
277 | job: job,
278 | throttle: Math.max(0, Math.min(throttleMiner, 100))
279 | };
280 | wrk.postMessage(jbthrt);
281 |
282 | if ((e.data) != "wakeup") totalhashes += 1;
283 | }
284 |
285 |
--------------------------------------------------------------------------------
/web_miner/worker.js:
--------------------------------------------------------------------------------
1 | /* Very simple worker which tries to find a nonce value to create a cryptonight-hash which
2 | * is lower than the given target. */
3 |
4 | importScripts('cn.min.js'); // imports the cn.js "glue" script generated by emscripten
5 |
6 | // webassembly cryptonight is called here.
7 | var cn = Module.cwrap('hash_cn', 'string', ['string', 'number', 'number', 'number']);
8 |
9 | // A few helper (string) functions to help us working with the hex string
10 | // which is used
11 |
12 | function zeroPad(num, places) {
13 | var zero = places - num.toString().length + 1;
14 | return Array(+(zero > 0 && zero)).join("0") + num;
15 | }
16 |
17 | function hex2int(s) {
18 | return parseInt(s.match(/[a-fA-F0-9]{2}/g).reverse().join(''), 16);
19 | }
20 |
21 | function int2hex(i) {
22 | return (zeroPad(i.toString(16), 8)).match(/[a-fA-F0-9]{2}/g).reverse().join('');
23 | }
24 |
25 | function getRandomInt(min, max) {
26 | return Math.floor(Math.random() * (max - min + 1)) + min;
27 | }
28 |
29 | onmessage = function (e) {
30 |
31 | var jbthrt = e.data;
32 | var job = jbthrt.job;
33 | var thrt = jbthrt.throttle;
34 |
35 | var bsuccess = false;
36 | var hash = "";
37 | var hexnonce = 0;
38 |
39 | // calculate a cryptonight hash
40 | var calcHash = function () {
41 |
42 | if (job !== null) {
43 |
44 | var target = hex2int(job.target);
45 | var inonce = getRandomInt(0, 0xFFFFFFFF);
46 | hexnonce = int2hex(inonce);
47 |
48 | var blob = job.blob.substring(0,78) + hexnonce + job.blob.substring(86,job.blob.length);
49 |
50 | try {
51 | if(job.algo === "cn")
52 | hash = cn(blob, 0, job.variant, job.height);
53 | else if(job.algo === "cn-lite")
54 | hash = cn(blob, 1, job.variant, job.height);
55 | else if(job.algo === "cn-pico")
56 | hash = cn(blob, 2, job.variant, job.height);
57 | else if(job.algo === "cn-half")
58 | hash = cn(blob, 3, job.variant, job.height);
59 | else throw "algorithm not supported!";
60 |
61 | var hashval = hex2int(hash.substring(56, 64));
62 | bsuccess = hashval < target;
63 | }
64 | catch (err) { console.log(err); }
65 |
66 |
67 | }
68 | };
69 |
70 | // submit a cryptonight hash
71 | var submit = function () {
72 |
73 | if (bsuccess) {
74 | var msg = {
75 | identifier: "solved",
76 | job_id: job.job_id,
77 | nonce: hexnonce,
78 | result: hash
79 | };
80 | postMessage(JSON.stringify(msg));
81 | } else {
82 | postMessage("nothing");
83 | }
84 |
85 | };
86 |
87 | if (thrt === 0) { calcHash(); submit(); }
88 | else {
89 | var t0 = performance.now();
90 | calcHash();
91 | var dt = performance.now() - t0;
92 |
93 | var sleept = Math.round(thrt / (100 - thrt + 10) * dt);
94 | setTimeout(submit, sleept);
95 | }
96 |
97 | };
98 |
--------------------------------------------------------------------------------