├── .editorconfig ├── LICENSE ├── README.md ├── c++ ├── base64.h └── crypto │ ├── README.md │ ├── salsa20.h │ └── sha512.h ├── docs ├── fetchit │ ├── fetchit.js │ └── test.html ├── index.html └── vue │ ├── vs-crumbs │ ├── assets │ │ ├── vue-router.js │ │ └── vue.min.js │ ├── index.html │ └── vs-crumbs.js │ ├── vs-notify │ ├── index.html │ └── vuepack.js │ └── vue-submit │ ├── assets │ ├── bootstrap.min.css │ └── vue.min.js │ ├── index.html │ ├── vue-submit-example.png │ └── vue-submit.js ├── js ├── bitcoin │ ├── cashaddr │ │ ├── README.md │ │ ├── cashaddr.js │ │ ├── cashaddr.min.js │ │ ├── index.html │ │ └── sha256.js │ └── validate │ │ ├── README.md │ │ ├── btc_validate.js │ │ ├── btc_validate.min.js │ │ └── validate_test.html ├── crypto │ ├── README.md │ ├── blake2s.js │ ├── blake2s.min.js │ ├── salsa20.js │ ├── salsa20.min.js │ ├── sha256.js │ ├── sha256.min.js │ ├── sha512.js │ ├── sha512.min.js │ └── tests │ │ ├── blake2s.html │ │ ├── sha256.html │ │ └── sha512.html ├── css_parser │ ├── README.md │ ├── css_compile.js │ ├── css_parse.js │ ├── test.html │ └── test.js ├── fetchit │ ├── README.md │ ├── fetchit.js │ ├── fetchit.min.js │ └── test.html ├── int64 │ ├── README.md │ └── int64.js ├── jslib │ ├── README.md │ ├── jslib.js │ ├── jslib.min.js │ └── src │ │ ├── cookies.js │ │ ├── debounce.js │ │ ├── extra.js │ │ ├── main.js │ │ ├── merge.bat │ │ └── polyfill.js └── vue │ ├── vs-crumbs │ ├── README.md │ ├── example.jpg │ ├── test │ │ ├── assets │ │ │ ├── vue-router.js │ │ │ └── vue.min.js │ │ └── index.html │ └── vs-crumbs.js │ ├── vs-notify │ ├── README.md │ ├── test │ │ ├── index.html │ │ └── vuepack.js │ ├── vs-notify.js │ └── vs-notify.min.js │ ├── vue-css │ ├── README.md │ ├── vue-css.js │ └── vue-css.min.js │ └── vue-submit │ ├── README.md │ ├── test │ ├── assets │ │ ├── bootstrap.min.css │ │ └── vue.min.js │ └── index.html │ ├── vue-submit-example.png │ ├── vue-submit.js │ └── vue-submit.min.js └── php └── bitcoin ├── api ├── README.md └── json_api.php ├── cashaddr ├── README.md ├── cashaddr.php └── test.php └── validate ├── README.md ├── test.php └── validate.php /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*.{js,html,css,h,cpp}] 3 | indent_style = tab 4 | indent_size = 4 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pieces 2 | 3 | Simple, stand-alone, reusable components. 4 | 5 | Follow me on Twitter for latest updates 6 | 7 | ## JavaScript 8 | 9 | * [**Simple CSS parser**](https://github.com/NxtChg/pieces/tree/master/js/css_parser) 10 | * [**jslib**](/js/jslib) - a simple helper library 11 | * [**fetchit**](https://github.com/NxtChg/pieces/tree/master/js/fetchit) - a simple version of fetch() based on XMLHttpRequest 12 | * [**Int64**](/js/int64) - a simple class to allow 64-bit calculations in Javascript 13 | * [**crypto**](/js/crypto) - a collection of JS cryptographic primitives 14 | * [**btc_validate**](/js/bitcoin/validate) - Bitcoin address validation 15 | * [**cashaddr**](/js/bitcoin/cashaddr) - CashAddr translator 16 | 17 | ## Vue.js 18 | 19 | * [**vue-css**](https://github.com/NxtChg/pieces/tree/master/js/vue/vue-css) - bundle relevant CSS with your components 20 | * [**vue-submit**](https://github.com/NxtChg/pieces/tree/master/js/vue/vue-submit) - simple implementation of Ladda in less than 90 lines of code 21 | * [**vs-crumbs**](https://github.com/NxtChg/pieces/tree/master/js/vue/vs-crumbs) - very simple breadcrumbs in 40 lines of code 22 | * [**vs-notify**](/js/vue/vs-notify) - tiny but powerful notification component 23 | 24 | ## PHP 25 | 26 | * [**JsonAPI**](/php/bitcoin/api) - Bitcoin RPC interface 27 | * [**btc_validate**](/php/bitcoin/validate) - Bitcoin address validation 28 | * [**cashaddr**](/php/bitcoin/cashaddr) - CashAddr translator 29 | 30 | ## C++ 31 | 32 | * [**crypto**](/c++/crypto) - a collection of C++ cryptographic primitives 33 | * [**base64**](/c++/base64.h) - base64 encoding/decoding in 60 lines of code 34 | -------------------------------------------------------------------------------- /c++/base64.h: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | typedef unsigned char byte; 6 | 7 | char b64enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 8 | char b64dec[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; 9 | 10 | int base64_encode(byte *bin, int size, char *out) // returns the number of characters written 11 | { 12 | int sz = 0, rm = size; 13 | 14 | while(rm > 0) 15 | { 16 | int b = (bin[0] & 3) << 4, c = 64; 17 | 18 | if(rm > 1){ b |= (bin[1] & 0xF0) >> 4; c = ((bin[1] & 0x0F) << 2) | ((bin[2] & 0xC0) >> 6); } 19 | 20 | out[sz+0] = b64enc[bin[0] >> 2]; 21 | out[sz+1] = b64enc[b]; 22 | out[sz+2] = b64enc[c]; 23 | out[sz+3] = b64enc[rm > 2 ? (bin[2] & 0x3F) : 64]; 24 | 25 | sz += 4; bin += 3; rm -= 3; 26 | } 27 | 28 | out[sz] = 0; 29 | 30 | return sz; 31 | }//____________________________________________________________________________ 32 | 33 | int base64_decode(char *str, byte *out, int size) // returns the number of bytes written or -1 if decoding failed 34 | { 35 | int d = 0, sz = 0, bits = 0; 36 | 37 | while(*str) 38 | { 39 | char a = *str++; if(a > 0 && a < 33) continue; 40 | 41 | if(a != '=') 42 | { 43 | if(a < 43 || a > 122) return -1; // bad character 44 | 45 | char b = b64dec[a-43]; if(b == '$') return -1; // bad character 46 | 47 | d = (d << 6) | (b - 62); bits += 6; 48 | 49 | if(bits > 7) 50 | { 51 | int r = bits - 8; if(sz >= size) return -1; 52 | 53 | out[sz++] = (byte)(d >> r); d &= (1 << r) - 1; bits -= 8; 54 | } 55 | } 56 | } 57 | 58 | return (bits < 6 ? sz : -1); 59 | }//____________________________________________________________________________ 60 | -------------------------------------------------------------------------------- /c++/crypto/README.md: -------------------------------------------------------------------------------- 1 | 2 | # A collection of C++ cryptographic primitives. 3 | 4 | * [**SHA512**](/c++/crypto/sha512.h) 5 | * [**salsa20**](/c++/crypto/salsa20.h) 6 | -------------------------------------------------------------------------------- /c++/crypto/salsa20.h: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2014-2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | typedef unsigned char byte; 6 | typedef unsigned int uint; 7 | typedef __int64 int64; 8 | 9 | #define till(a) for(int i = 0; i < (a); i++) 10 | 11 | #define ROTL32(x,c) (((x) << c) | ((x) >> (32-c))) // _lrotl(x,c) 12 | 13 | #define STEP(a,b,c,d) \ 14 | x[a] ^= ROTL32(x[d]+x[c], 7); \ 15 | x[b] ^= ROTL32(x[a]+x[d], 9); \ 16 | x[c] ^= ROTL32(x[b]+x[a],13); \ 17 | x[d] ^= ROTL32(x[c]+x[b],18); 18 | 19 | void salsa20(byte *dst, byte *src, int size, byte key[32], byte nonce[8] = NULL) 20 | { 21 | uint *k = (uint*)key; 22 | uint *n = (uint*)nonce; 23 | uint *c = (uint*)"expand 32-byte k"; 24 | 25 | uint x[16], state[16] = { c[0], k[0], k[1], k[2], k[3], c[1], 0, 0, 0, 0, c[2], k[4], k[5], k[6], k[7], c[3] }; 26 | 27 | if(nonce){ state[6] = n[0]; state[7] = n[1]; } 28 | 29 | while(size > 0) 30 | { 31 | { till(16) x[i] = state[i]; } 32 | 33 | till(10) 34 | { 35 | STEP( 4, 8, 12, 0); STEP( 9, 13, 1, 5); 36 | STEP(14, 2, 6, 10); STEP( 3, 7, 11, 15); 37 | STEP( 1, 2, 3, 0); STEP( 6, 7, 4, 5); 38 | STEP(11, 8, 9, 10); STEP(12, 13, 14, 15); 39 | } 40 | 41 | { till(16) x[i] += state[i]; } 42 | 43 | state[8]++; // if(!state[8]) state[9]++; 44 | 45 | int sz = (size < 64 ? size : 64); 46 | 47 | { till(sz) dst[i] = src[i] ^ *((byte*)x+i); } 48 | 49 | src += 64; dst += 64; size -= 64; 50 | } 51 | }//____________________________________________________________________________ 52 | 53 | void salsa20(void *ptr, int size, byte key[32], byte nonce[8] = NULL ){ salsa20((byte*)ptr, (byte*)ptr, size, key, nonce); } 54 | void salsa20(void *ptr, int size, byte key[32], int64 nonce ){ salsa20((byte*)ptr, (byte*)ptr, size, key, (byte*)&nonce); } 55 | void salsa20(void *dst, void *src, int size, byte key[32], int64 nonce){ salsa20((byte*)dst, (byte*)src, size, key, (byte*)&nonce); } 56 | 57 | #undef STEP 58 | -------------------------------------------------------------------------------- /c++/crypto/sha512.h: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | typedef unsigned char byte; 6 | typedef unsigned __int64 uint64; 7 | 8 | #define till(a) for(int i = 0; i < (a); i++) 9 | 10 | #define ROTR64(x,c) (((x) >> c) | ((x) << (64-c))) // _rotr64() 11 | 12 | #define STEP(a,b,c,d,e,f,g,h) \ 13 | t = s[h] + (ROTR64(s[e],14) ^ ROTR64(s[e],18) ^ ROTR64(s[e],41)) + ((s[e] & s[f]) ^ (~s[e] & s[g])) + w[i] + k[i]; s[d] += t; \ 14 | s[h] = t + (ROTR64(s[a],28) ^ ROTR64(s[a],34) ^ ROTR64(s[a],39)) + ((s[a] & s[b]) ^ ( s[a] & s[c]) ^ (s[b] & s[c])); 15 | //_____________________________________________________________________________ 16 | 17 | void sha512_blocks(uint64 *state, byte *in, int len) 18 | { 19 | static uint64 k[80] = 20 | { 21 | 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC, 0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118, 22 | 0xD807AA98A3030242, 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2, 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, 0xC19BF174CF692694, 23 | 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65, 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5, 24 | 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4, 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, 0x06CA6351E003826F, 0x142929670A0E6E70, 25 | 0x27B70A8546D22FFC, 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF, 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, 0x92722C851482353B, 26 | 0xA2BFE8A14CF10364, 0xA81A664BBC423001, 0xC24B8B70D0F89791, 0xC76C51A30654BE30, 0xD192E819D6EF5218, 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8, 27 | 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8, 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3, 28 | 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC, 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, 0xC67178F2E372532B, 29 | 0xCA273ECEEA26619C, 0xD186B8C721C0C207, 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178, 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B, 30 | 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C, 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 31 | }; 32 | 33 | uint64 w[80], s[8] = { state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7] }; 34 | 35 | while(len >= 128) 36 | { 37 | till(128){ ((byte*)w)[(i & ~7) + 7 - (i & 7)] = in[i]; } // load big-endian 38 | 39 | for(i = 16; i < 80; i++) 40 | { 41 | const uint64 gam0 = ROTR64(w[i-15], 1) ^ ROTR64(w[i-15], 8) ^ (w[i-15] >> 7); 42 | const uint64 gam1 = ROTR64(w[i- 2],19) ^ ROTR64(w[i- 2],61) ^ (w[i- 2] >> 6); 43 | 44 | w[i] = gam1 + w[i-7] + gam0 + w[i-16]; 45 | } 46 | 47 | uint64 t; i = 0; 48 | 49 | do 50 | { 51 | STEP(0, 1, 2, 3, 4, 5, 6, 7); i++; 52 | STEP(7, 0, 1, 2, 3, 4, 5, 6); i++; 53 | STEP(6, 7, 0, 1, 2, 3, 4, 5); i++; 54 | STEP(5, 6, 7, 0, 1, 2, 3, 4); i++; 55 | STEP(4, 5, 6, 7, 0, 1, 2, 3); i++; 56 | STEP(3, 4, 5, 6, 7, 0, 1, 2); i++; 57 | STEP(2, 3, 4, 5, 6, 7, 0, 1); i++; 58 | STEP(1, 2, 3, 4, 5, 6, 7, 0); i++; 59 | 60 | } 61 | while(i < 80); 62 | 63 | { till(8){ s[i] += state[i]; state[i] = s[i]; } } 64 | 65 | in += 128; len -= 128; 66 | } 67 | }//____________________________________________________________________________ 68 | 69 | void sha512(const void *src, int len, byte out[64]) 70 | { 71 | uint64 s[8]; int sz = len; 72 | 73 | byte pad[256], *in = (byte*)src; 74 | 75 | s[0] = 0x6A09E667F3BCC908; s[1] = 0xBB67AE8584CAA73B; s[2] = 0x3C6EF372FE94F82B; s[3] = 0xA54FF53A5F1D36F1; 76 | s[4] = 0x510E527FADE682D1; s[5] = 0x9B05688C2B3E6C1F; s[6] = 0x1F83D9ABFB41BD6B; s[7] = 0x5BE0CD19137E2179; 77 | 78 | sha512_blocks(s, in, sz); 79 | 80 | in += sz; sz &= 127; in -= sz; 81 | 82 | pad[sz] = 0x80; till(sz) pad[i] = in[i]; 83 | 84 | int ofs = (sz < 112 ? 119 : 247); 85 | 86 | for(i = sz+1; i < ofs+4; i++) pad[i] = 0; 87 | 88 | pad[i+0] = byte(len >> 29); 89 | pad[i+1] = byte(len >> 21); 90 | pad[i+2] = byte(len >> 13); 91 | pad[i+3] = byte(len >> 5); 92 | pad[i+4] = byte(len << 3); 93 | 94 | sha512_blocks(s, pad, ofs+9); 95 | 96 | { till(64) out[i] = ((byte*)s)[(i & ~7) + 7 - (i & 7)]; } // store big-endian 97 | } 98 | 99 | #undef STEP 100 | -------------------------------------------------------------------------------- /docs/fetchit/fetchit.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | function fetchit(url, data, options) 6 | { 7 | return new Promise(function(resolve, reject) 8 | { 9 | 'use strict'; 10 | 11 | options = (options || {}); 12 | 13 | var xhr = new XMLHttpRequest; 14 | 15 | var ue = false, method = (options.method || 'GET'); 16 | 17 | if(data instanceof FormData) 18 | { 19 | method = 'POST'; 20 | } 21 | else if(data) 22 | { 23 | data = 'data=' + encodeURIComponent(JSON.stringify(data)); 24 | 25 | if(method == 'POST') ue = true; else 26 | if(method == 'GET' ) 27 | { 28 | url += (url.indexOf('?') < 0 ? '?' : '&') + data; data = null; 29 | } 30 | } 31 | 32 | xhr.open(method.toUpperCase(), url, true); 33 | 34 | xhr.onreadystatechange = function() 35 | { 36 | if(this.readyState !== 4) return; 37 | 38 | if(this.status === 200) 39 | { 40 | resolve(JSON.parse(this.responseText)); 41 | } 42 | else 43 | { 44 | reject('network error' + (this.status > 0 ? ': '+this.status : '')); 45 | } 46 | }; 47 | 48 | xhr.timeout = (options.timeout || 5000); // time in milliseconds 49 | 50 | if(options.credentials === 'include'){ xhr.withCredentials = true; } else 51 | if(options.credentials === 'omit' ){ xhr.withCredentials = false; } 52 | 53 | if(options.header) option.headers.forEach(function(value, name){ xhr.setRequestHeader(name, value); }); 54 | 55 | if(ue) xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 56 | 57 | xhr.send(data); 58 | }); 59 | } 60 | -------------------------------------------------------------------------------- /docs/fetchit/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fetchit test 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 |
18 | Response:

19 |

20 | Error: 21 |
22 | 23 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Examples 6 | 8 | 9 | 10 | 11 | fetchit test

12 | 13 | vue-submit test

14 | 15 | vs-crumbs test

16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/vue/vs-crumbs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-submit test 6 | 17 | 18 | 19 |
20 |

Breadcrumbs

21 | Simple:

22 | Arrows:
23 | 24 |

View

25 |
26 | 27 |
28 | 29 |

Navigation: 30 | Home | 31 | Users | 32 | User | 33 | Foo | 34 | Bar | 35 | Boo | 36 | 404 | 37 | About 38 |
39 | 40 | 41 | 42 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /docs/vue/vs-crumbs/vs-crumbs.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | Vue.component('vs-crumbs', 6 | { 7 | template: 8 | '
    ' + 9 | '
  • ' + 10 | '{{ crumb.name }}' + 11 | '{{ crumb.name }}' + 12 | '
', 13 | 14 | props: { root: String }, 15 | 16 | computed: 17 | { 18 | crumbs: function() 19 | { 20 | var path = '', title = (this.root || 'home'); 21 | 22 | var cs = [ { name: title, path: '/'} ]; if(!this.$route) return []; 23 | 24 | var r = (this.$route.path ).split('/'); 25 | var m = (this.$route.matched[0].meta.crumbs || '').split('/'); 26 | 27 | for(var i = 1; i < r.length; i++) 28 | { 29 | var name = (m[i] || r[i]); if(r[i] == '') continue; 30 | 31 | title += ' : '+ name; 32 | path += '/' + name; 33 | 34 | cs.push({ name: name, path: path }); 35 | } 36 | 37 | window.document.title = title; 38 | 39 | return cs; 40 | } 41 | } 42 | }); -------------------------------------------------------------------------------- /docs/vue/vs-notify/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vs-notify test 6 | 67 | 68 | 69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 84 | 85 | 86 |
87 | 88 | 89 |
90 | 91 |


92 | 93 | 94 |
95 |
96 | 97 |
98 |
99 | 100 |
101 | 102 | 103 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /docs/vue/vue-submit/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-submit test 6 | 7 | 10 | 11 | 12 |
13 | Click the buttons: 14 |
15 |
16 | Button 1 17 | Button 2 18 | Button 3 19 | Button 4

20 | Submit Form 21 |
22 |
23 |
24 | 25 | 26 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /docs/vue/vue-submit/vue-submit-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NxtChg/pieces/3eb39c8287a97632e9347a24f333d52d916bc816/docs/vue/vue-submit/vue-submit-example.png -------------------------------------------------------------------------------- /docs/vue/vue-submit/vue-submit.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | Math.log10 = Math.log10 || function(x){ return Math.log(x) * Math.LOG10E; }; 6 | //_____________________________________________________________________________ 7 | 8 | var s = document.createElement("style"); s.type = 'text/css'; // add spinner keyframes 9 | 10 | document.getElementsByTagName('head')[0].appendChild(s); 11 | 12 | s.sheet.insertRule('@keyframes spin { 100% { transform: rotate(360deg); } }', 0); 13 | //_____________________________________________________________________________ 14 | 15 | Vue.component('vue-submit', 16 | { 17 | template: 18 | '', 23 | 24 | props:{ progress: Number, autoProgress: Number, disabled: Boolean }, 25 | 26 | data: function() 27 | { 28 | return{ at: 0, t: 0, 29 | dt: (typeof(this.autoProgress) != 'undefined' ? this.autoProgress : 3000), 30 | enabled: (typeof(this.disabled ) == 'undefined' || this.disabled != true) 31 | }; 32 | }, 33 | 34 | watch: 35 | { 36 | disabled: function(v){ this.enabled = !v; }, 37 | 38 | progress: function(v) 39 | { 40 | if(!this.enabled) return; 41 | 42 | var prev = this.in_progress; this.at = v; 43 | 44 | if(this.dt > 0) 45 | { 46 | if(!prev && this.in_progress){ this.at = 1; this.t = 0; this.tick(); } // start auto progress 47 | if( prev && !this.in_progress){ this.at = 0; } // stop 48 | } 49 | } 50 | }, 51 | 52 | computed: 53 | { 54 | in_progress: function(){ return (this.at > 0 && this.at < 100); }, 55 | 56 | locked: function(){ return (!this.enabled || this.in_progress); }, 57 | 58 | bar_style: function() 59 | { 60 | return{ position: 'absolute', top: 0, left: 0, bottom: 0, backgroundColor: '#fff', transition: 'width 200ms linear', opacity: '0.4', 61 | width: this.at + '%', height: '100%', zIndex: 3 62 | }; 63 | }, 64 | 65 | spn_style: function() 66 | { 67 | return{ position: 'relative', border: '3.5px solid rgba(255,255,255,0.5)', borderRightColor: '#fff', borderRadius: '50%', display: 'inline-block', 68 | width: '1.33em', height: '1.33em', zIndex: 2, marginLeft:'6px', verticalAlign: 'text-top', top: '-1px', 69 | animation: 'spin 0.75s linear', animationIterationCount: 'infinite', // background: 'url("loading.gif") center center no-repeat' 70 | }; 71 | } 72 | }, 73 | 74 | methods: 75 | { 76 | tick: function() 77 | { 78 | if(!this.enabled || !this.in_progress) return; 79 | 80 | this.at = Math.round(100 + Math.log10(0.1 + this.t / this.dt) * 100); 81 | 82 | if(this.at < 1) this.at = 1; 83 | if(this.at > 95) this.at = 95; 84 | 85 | this.t += 200; 86 | 87 | var self = this; setTimeout(function(){ self.tick(); }, 200); 88 | } 89 | } 90 | }); -------------------------------------------------------------------------------- /js/bitcoin/cashaddr/README.md: -------------------------------------------------------------------------------- 1 | # CashAddr Translator 2 | 3 | Usage: 4 | 5 | ```js 6 | var pk = cashaddr2pk('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'); 7 | 8 | console.log(pk2adr(pk)); // 1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu 9 | 10 | console.log(pk2cashaddr(pk)); // bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /js/bitcoin/cashaddr/cashaddr.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2018. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | function poly_mod(v, ret) // checksum magic 6 | { 7 | var a = 0, b = 1, c = 0; 8 | 9 | for(var i = 0; i < v.length; i++) 10 | { 11 | c = (a >>> 3); 12 | a = ((a & 7) << 5) | (b >>> 27); 13 | b = ((b & 0x07ffffff) << 5) ^ v[i]; 14 | 15 | if(c == 0) continue; 16 | 17 | if(c & 1){ a ^= 0x98; b ^= 0xf2bc8e61; } 18 | if(c & 2){ a ^= 0x79; b ^= 0xb76d99e2; } 19 | if(c & 4){ a ^= 0xf3; b ^= 0x3e5fb3c4; } 20 | if(c & 8){ a ^= 0xae; b ^= 0x2eabe2a8; } 21 | if(c & 16){ a ^= 0x1e; b ^= 0x4f43e470; } 22 | } 23 | 24 | return (ret ? [a, b^1] : (a == 0 && (b^1) == 0)); 25 | }//____________________________________________________________________________ 26 | 27 | function bits5to8(arr) // converts 5-bit words into bytes 28 | { 29 | var t = 0, bits = 0, out = []; 30 | 31 | for(var i = 0; i < arr.length; i++) 32 | { 33 | t <<= 5; t |= arr[i]; bits += 5; 34 | 35 | while(bits > 7){ bits -= 8; out.push((t >> bits) & 0xFF); } 36 | } 37 | 38 | return out; 39 | }//____________________________________________________________________________ 40 | 41 | function bits8to5(arr) // converts bytes into 5-bit words 42 | { 43 | var t = 0, bits = 0, out = []; 44 | 45 | for(var i = 0; i < arr.length; i++) 46 | { 47 | t <<= 8; t |= arr[i]; bits += 8; 48 | 49 | while(bits > 5){ bits -= 5; out.push((t >> bits) & 31); } 50 | } 51 | 52 | if(bits) out.push((t & ((1 << bits) - 1)) << (5 - bits)); 53 | 54 | return out; 55 | }//____________________________________________________________________________ 56 | 57 | function base58_encode(bin) 58 | { 59 | var d = [0], alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; 60 | 61 | for(var i = 0; i < bin.length; i++) 62 | { 63 | for(var j = 0, c = bin[i]; j < d.length; j++) 64 | { 65 | c += d[j] << 8; d[j] = c % 58; c = (c / 58) | 0; 66 | } 67 | 68 | while(c > 0){ d.push(c % 58); c = (c / 58) | 0; } 69 | } 70 | 71 | var out = ''; 72 | 73 | for(i = 0; i < bin.length && bin[i] == 0; i++) out += '1'; // leading zero bytes 74 | 75 | for(i = d.length - 1; i >= 0; i--) out += alphabet[d[i]]; // reverse 76 | 77 | return out; 78 | }//____________________________________________________________________________ 79 | 80 | function pk2adr(pk) 81 | { 82 | if(pk === false) return ''; 83 | 84 | pk = [pk[0] ? 0x05 : 0x00].concat(pk.slice(1)); 85 | 86 | var checksum = SHA256(SHA256(pk)).slice(0, 4); 87 | 88 | return base58_encode(pk.concat(checksum)); 89 | }//____________________________________________________________________________ 90 | 91 | function cashaddr2pk(adr) // returns payload, including the version byte 92 | { 93 | adr = (''+adr).toLowerCase(); 94 | 95 | //var idx = adr.indexOf('bitcoincash:'); if(idx != -1) adr = adr.substr(idx+12); 96 | 97 | var idx = adr.indexOf(':'); if(idx != -1) adr = adr.substr(idx+1); // let's be more relaxed about the prefix... 98 | 99 | adr = adr.replace(/(^\s+)|(\s+$)/g, ''); // trim 100 | 101 | if(adr[0] != 'q' && adr[0] != 'p') return false; 102 | 103 | var raw = [], alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; 104 | 105 | for(var i = 0; i < adr.length; i++) 106 | { 107 | idx = alphabet.indexOf(adr[i]); if(idx < 0) continue; 108 | 109 | raw.push(idx); if(raw.length > 112) return false; 110 | } 111 | 112 | if(raw.length < 42) return false; 113 | 114 | var hash_sz = (raw[1] >> 2); if(hash_sz != 0) return false; // only 160-bit hashes 115 | 116 | if(!poly_mod([2, 9, 20, 3, 15, 9, 14, 3, 1, 19, 8, 0].concat(raw))) return false; // verify checksum 117 | 118 | raw = raw.slice(0, -8); // cut off checksum 119 | 120 | return bits5to8(raw); // convert into bytes 121 | }//____________________________________________________________________________ 122 | 123 | function pk2cashaddr(pk) // needs version byte + payload 124 | { 125 | var raw = bits8to5(pk); // convert into 5-bit words 126 | 127 | var mod = poly_mod([2, 9, 20, 3, 15, 9, 14, 3, 1, 19, 8, 0].concat(raw).concat([0,0,0,0,0,0,0,0]), true); 128 | 129 | var a = mod[0], b = mod[1], checksum = new Array(8); 130 | 131 | for(var i = 7; i >= 0; i--) // convert 5-bit groups in mod to checksum values 132 | { 133 | checksum[i] = (b & 31); b >>>= 5; b |= (a & 31) << 27; a >>>= 5; // (mod >> uint(5*(7-i))) & 0x1f 134 | } 135 | 136 | raw = raw.concat(checksum); 137 | 138 | if(!poly_mod([2, 9, 20, 3, 15, 9, 14, 3, 1, 19, 8, 0].concat(raw))) return false; // verify checksum 139 | 140 | var out = 'bitcoincash:', alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; 141 | 142 | for(var i = 0; i < raw.length; i++){ out += alphabet[raw[i] & 31]; } 143 | 144 | return out; 145 | } 146 | -------------------------------------------------------------------------------- /js/bitcoin/cashaddr/cashaddr.min.js: -------------------------------------------------------------------------------- 1 | function poly_mod(r,n){for(var t=0,o=1,e=0,c=0;c>>3,t=(7&t)<<5|o>>>27,o=(134217727&o)<<5^r[c],0!=e&&(1&e&&(t^=152,o^=4072443489),2&e&&(t^=121,o^=3077413346),4&e&&(t^=243,o^=1046459332),8&e&&(t^=174,o^=783016616),16&e&&(t^=30,o^=1329849456));return n?[t,1^o]:0==t&&0==(1^o)}function bits5to8(r){for(var n=0,t=0,o=[],e=0;e7;)t-=8,o.push(n>>t&255);return o}function bits8to5(r){for(var n=0,t=0,o=[],e=0;e5;)t-=5,o.push(n>>t&31);return t&&o.push((n&(1<0;)n.push(e%58),e=e/58|0}var c="";for(t=0;t=0;t--)c+="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"[n[t]];return c}function pk2adr(r){if(!1===r)return"";r=[r[0]?5:0].concat(r.slice(1));var n=SHA256(SHA256(r)).slice(0,4);return base58_encode(r.concat(n))}function cashaddr2pk(r){r=(""+r).toLowerCase();var n=r.indexOf(":");if(-1!=n&&(r=r.substr(n+1)),r=r.replace(/(^\s+)|(\s+$)/g,""),"q"!=r[0]&&"p"!=r[0])return!1;for(var t=[],o="qpzry9x8gf2tvdw0s3jn54khce6mua7l",e=0;e112))return!1;return!(t.length<42)&&(0==t[1]>>2&&(!!poly_mod([2,9,20,3,15,9,14,3,1,19,8,0].concat(t))&&(t=t.slice(0,-8),bits5to8(t))))}function pk2cashaddr(r){for(var n=bits8to5(r),t=poly_mod([2,9,20,3,15,9,14,3,1,19,8,0].concat(n).concat([0,0,0,0,0,0,0,0]),!0),o=t[0],e=t[1],c=new Array(8),a=7;a>=0;a--)c[a]=31&e,e>>>=5,e|=(31&o)<<27,o>>>=5;if(n=n.concat(c),!poly_mod([2,9,20,3,15,9,14,3,1,19,8,0].concat(n)))return!1;for(var f="bitcoincash:",a=0;a 2 | 3 | 4 | CashAddr Translator 5 | 6 | 11 | 12 | 13 | 14 | 15 |

16 |
17 | 18 |


19 |

Test:
20 | bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu
21 | bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR
22 | bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb
23 | bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC
24 | bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e3LDsS579y7sruadqu11beEJoTjdFiFCdX4
25 | bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc3731nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw
26 |

27 |
28 | 29 | 45 | 46 | -------------------------------------------------------------------------------- /js/bitcoin/cashaddr/sha256.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2016. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | function SHA256(s) // 's' is array 6 | { 7 | function rotr (x, n){ return ( x >>> n ) | (x << (32 - n)); } 8 | function Ch (x, y, z){ return ((x & y) ^ ((~x) & z)); } 9 | function Maj(x, y, z){ return ((x & y) ^ ( x & z) ^ (y & z)); } 10 | function Sigma0256(x){ return (rotr(x, 2) ^ rotr(x,13) ^ rotr(x,22)); } 11 | function Sigma1256(x){ return (rotr(x, 6) ^ rotr(x,11) ^ rotr(x,25)); } 12 | function Gamma0256(x){ return (rotr(x, 7) ^ rotr(x,18) ^ (x >>> 3)); } 13 | function Gamma1256(x){ return (rotr(x,17) ^ rotr(x,19) ^ (x >>> 10)); } 14 | 15 | function core_sha256(read, len) 16 | { 17 | var a, b, c, d, e, f, g, h, i, j, t, w = new Array(64); 18 | 19 | var k = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2); 20 | var H = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); 21 | 22 | for(i = 0; i < len; i += 16) 23 | { 24 | a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; 25 | 26 | for(j = 0; j < 64; j++) 27 | { 28 | w[j] = (j < 16 ? read(j+i) : Gamma1256(w[j-2]) + w[j-7] + Gamma0256(w[j-15]) + w[j-16]); 29 | 30 | t = h + Sigma1256(e) + Ch(e,f,g) + k[j] + w[j]; 31 | 32 | h = g; g = f; f = e; e = (d + t) >>> 0; 33 | d = c; c = b; b = a; a = (t + Sigma0256(b) + Maj(b,c,d)) >>> 0; 34 | } 35 | 36 | H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; 37 | } 38 | 39 | return H; 40 | }//___________________________________________________________________________ 41 | 42 | var bitlen = s.length * 8, last = (((bitlen + 64) >> 9) << 4) + 15; 43 | 44 | function read(idx) 45 | { 46 | var p = idx << 2, out = (s[p] << 24) | (s[p+1] << 16) | (s[p+2] << 8) | s[p+3]; 47 | 48 | if(idx == (bitlen >> 5)){ out |= 0x80 << (24 - (bitlen & 31)); } 49 | 50 | return (idx == last ? bitlen : out) >>> 0; 51 | }//___________________________________________________________________________ 52 | 53 | var h = core_sha256(read, last+1); 54 | 55 | for(var b = [], i = 0; i < 32; i++) 56 | { 57 | b.push((h[i>>2] >>> (24 - ((i&3)<<3))) & 0xFF); 58 | } 59 | 60 | return b; 61 | }//____________________________________________________________________________ 62 | -------------------------------------------------------------------------------- /js/bitcoin/validate/README.md: -------------------------------------------------------------------------------- 1 | # Bitcoin address validation 2 | 3 | Usage: 4 | 5 | ```js 6 | if(btc_validate('1Jgt77gGxYBTv1vfJAxeFUpiR6rhz7UeDb') == true) 7 | ``` 8 | 9 | -------------------------------------------------------------------------------- /js/bitcoin/validate/btc_validate.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | function SHA256(s) // 's' is array 6 | { 7 | function rotr (x, n){ return ( x >>> n ) | (x << (32 - n)); } 8 | function Ch (x, y, z){ return ((x & y) ^ ((~x) & z)); } 9 | function Maj(x, y, z){ return ((x & y) ^ ( x & z) ^ (y & z)); } 10 | function Sigma0256(x){ return (rotr(x, 2) ^ rotr(x,13) ^ rotr(x,22)); } 11 | function Sigma1256(x){ return (rotr(x, 6) ^ rotr(x,11) ^ rotr(x,25)); } 12 | function Gamma0256(x){ return (rotr(x, 7) ^ rotr(x,18) ^ (x >>> 3)); } 13 | function Gamma1256(x){ return (rotr(x,17) ^ rotr(x,19) ^ (x >>> 10)); } 14 | 15 | function core_sha256(read, len) 16 | { 17 | var a, b, c, d, e, f, g, h, i, j, t, w = new Array(64); 18 | 19 | var k = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2); 20 | var H = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); 21 | 22 | for(i = 0; i < len; i += 16) 23 | { 24 | a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; 25 | 26 | for(j = 0; j < 64; j++) 27 | { 28 | w[j] = (j < 16 ? read(j+i) : Gamma1256(w[j-2]) + w[j-7] + Gamma0256(w[j-15]) + w[j-16]); 29 | 30 | t = h + Sigma1256(e) + Ch(e,f,g) + k[j] + w[j]; 31 | 32 | h = g; g = f; f = e; e = (d + t) >>> 0; 33 | d = c; c = b; b = a; a = (t + Sigma0256(b) + Maj(b,c,d)) >>> 0; 34 | } 35 | 36 | H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; 37 | } 38 | 39 | return H; 40 | }//___________________________________________________________________________ 41 | 42 | var bitlen = s.length * 8, last = (((bitlen + 64) >> 9) << 4) + 15; 43 | 44 | function read(idx) 45 | { 46 | var p = idx << 2, out = (s[p] << 24) | (s[p+1] << 16) | (s[p+2] << 8) | s[p+3]; 47 | 48 | if(idx == (bitlen >> 5)){ out |= 0x80 << (24 - (bitlen & 31)); } 49 | 50 | return (idx == last ? bitlen : out) >>> 0; 51 | }//___________________________________________________________________________ 52 | 53 | var h = core_sha256(read, last+1); 54 | 55 | for(var b = [], i = 0; i < 32; i++) 56 | { 57 | b.push((h[i>>2] >>> (24 - ((i&3)<<3))) & 0xFF); 58 | } 59 | 60 | return b; 61 | }//____________________________________________________________________________ 62 | 63 | function base58_decode(s) 64 | { 65 | var i, j, b = [0], pos, carry; if(!s.length) return false; 66 | 67 | for(i = 0; i < s.length; i++) 68 | { 69 | pos = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.indexOf(s[i]); if(pos < 0) return false; 70 | 71 | for(j = 0; j < b.length; j++) b[j] *= 58; 72 | 73 | b[0] += pos; carry = 0; 74 | 75 | for(j = 0; j < b.length; j++){ b[j] += carry; carry = b[j] >> 8; b[j] &= 0xFF; } 76 | 77 | while(carry){ b.push(carry & 0xFF); carry >>= 8; } 78 | } 79 | 80 | for(i = 0; s[i] === '1' && i < s.length - 1; i++) b.push(0); // deal with leading zeros 81 | 82 | return b.reverse(); 83 | }//____________________________________________________________________________ 84 | 85 | function btc_validate(adr) 86 | { 87 | var b = base58_decode(adr); 88 | 89 | if(b !== false && b.length == 25) 90 | { 91 | var checksum = SHA256(SHA256(b.slice(0, b.length-4))).slice(0,4); 92 | 93 | if(checksum+'' == b.slice(b.length-4)+'' && (b[0] == 0 || b[0] == 5)) 94 | { 95 | return true; 96 | } 97 | } 98 | 99 | return false; 100 | } -------------------------------------------------------------------------------- /js/bitcoin/validate/btc_validate.min.js: -------------------------------------------------------------------------------- 1 | function SHA256(n){function r(n,r){return n>>>r|n<<32-r}function e(n,r,e){return n&r^~n&e}function t(n,r,e){return n&r^n&e^r&e}function u(n){return r(n,2)^r(n,13)^r(n,22)}function f(n){return r(n,6)^r(n,11)^r(n,25)}function o(n){return r(n,7)^r(n,18)^n>>>3}function i(n){return r(n,17)^r(n,19)^n>>>10}function c(r){var e=r<<2,t=n[e]<<24|n[e+1]<<16|n[e+2]<<8|n[e+3];return r==a>>5&&(t|=128<<24-(31&a)),(r==h?a:t)>>>0}for(var a=8*n.length,h=15+(a+64>>9<<4),l=function(n,r){var c,a,h,l,g,s,v,d,A,b,p,w=new Array(64),y=new Array(1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298),H=new Array(1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225);for(A=0;A>>0,l=h,h=a,a=c,c=p+u(a)+t(a,h,l)>>>0;H[0]+=c,H[1]+=a,H[2]+=h,H[3]+=l,H[4]+=g,H[5]+=s,H[6]+=v,H[7]+=d}return H}(c,h+1),g=[],s=0;s<32;s++)g.push(l[s>>2]>>>24-((3&s)<<3)&255);return g}function base58_decode(n){var r,e,t,u,f=[0];if(!n.length)return!1;for(r=0;r>8,f[e]&=255;for(;u;)f.push(255&u),u>>=8}for(r=0;"1"===n[r]&&r 2 | 3 | See console. 4 | 5 | 6 | 7 | 21 | 22 | -------------------------------------------------------------------------------- /js/crypto/README.md: -------------------------------------------------------------------------------- 1 | 2 | # A collection of JS cryptographic primitives. 3 | 4 | * [**SHA256**](/js/crypto/sha256.js) (2 Kb) 5 | * [**SHA512**](/js/crypto/sha512.js) (4 Kb) 6 | * [**Blake2s**](/js/crypto/blake2s.js) (2 Kb) 7 | * [**salsa20**](/js/crypto/salsa20.js) (1 Kb) 8 | -------------------------------------------------------------------------------- /js/crypto/blake2s.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 'use strict'; 5 | 6 | var blake_iv = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, 0, 0, 0, 0] 7 | 8 | function blake2s_core(state, s, more) 9 | { 10 | function STEP(a, b, c, d, x, y) 11 | { 12 | var t; 13 | 14 | v[a] = v[a] + v[b] + x; t = v[d] ^ v[a]; v[d] = (t >>> 16) | (t << 16); 15 | v[c] = v[c] + v[d]; t = v[b] ^ v[c]; v[b] = (t >>> 12) | (t << 20); 16 | v[a] = v[a] + v[b] + y; t = v[d] ^ v[a]; v[d] = (t >>> 8) | (t << 24); 17 | v[c] = v[c] + v[d]; t = v[b] ^ v[c]; v[b] = (t >>> 7) | (t << 25); 18 | }//___________________________________________________________________________ 19 | 20 | var i, sz, start = 0, len = s.length, m = new Array(16), v = new Array(16), block = new Array(64); 21 | 22 | var sigma = 23 | [ 24 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3, 25 | 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4, 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8, 26 | 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13, 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9, 27 | 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11, 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10, 28 | 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5, 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0, 29 | ]; 30 | 31 | for(i = 0; i < 8; i++) v[i] = state[i]; 32 | 33 | if(!len && state[8]) return; 34 | 35 | do 36 | { 37 | sz = 64; 38 | 39 | if(len <= 64){ sz = len; if(!more) state[10] = ~0; } 40 | 41 | state[8] += sz; // state[9] += (state[8] < sz); <- we only support less than 4Gb data 42 | 43 | for(i = 0; i < sz; i++){ block[i] = (typeof(s) == 'string' ? s.charCodeAt(start+i) : +s[start+i]); } 44 | 45 | while(i < 64) block[i++] = 0; 46 | 47 | for(i = 0; i < 64; i += 4) m[i>>2] = block[i] | block[i+1] << 8 | block[i+2] << 16 | block[i+3] << 24; 48 | 49 | v[ 8] = blake_iv[0]; v[12] = state[ 8] ^ blake_iv[4]; 50 | v[ 9] = blake_iv[1]; v[13] = state[ 9] ^ blake_iv[5]; 51 | v[10] = blake_iv[2]; v[14] = state[10] ^ blake_iv[6]; 52 | v[11] = blake_iv[3]; v[15] = state[11] ^ blake_iv[7]; 53 | 54 | for(i = 0; i < 160; i += 16) 55 | { 56 | STEP(0, 4, 8, 12, m[sigma[i+ 0]], m[sigma[i+ 1]]); 57 | STEP(1, 5, 9, 13, m[sigma[i+ 2]], m[sigma[i+ 3]]); 58 | STEP(2, 6, 10, 14, m[sigma[i+ 4]], m[sigma[i+ 5]]); 59 | STEP(3, 7, 11, 15, m[sigma[i+ 6]], m[sigma[i+ 7]]); 60 | STEP(0, 5, 10, 15, m[sigma[i+ 8]], m[sigma[i+ 9]]); 61 | STEP(1, 6, 11, 12, m[sigma[i+10]], m[sigma[i+11]]); 62 | STEP(2, 7, 8, 13, m[sigma[i+12]], m[sigma[i+13]]); 63 | STEP(3, 4, 9, 14, m[sigma[i+14]], m[sigma[i+15]]); 64 | } 65 | 66 | for(i = 0; i < 8; i++){ state[i] ^= v[i] ^ v[i+8]; v[i] = state[i]; } 67 | 68 | start += 64; len -= 64; 69 | } 70 | while(len > 0); 71 | }//____________________________________________________________________________ 72 | 73 | // 'msg' can be a string, Uint8Array or regular JS array 74 | // 'out' can be 'bin', 'hex' or 'HEX' 75 | 76 | function Blake2s(msg, out, prefix) 77 | { 78 | function hash2hex(b, out) 79 | { 80 | var str = '', hex = (out == 'HEX' ? '0123456789ABCDEF' : '0123456789abcdef'); 81 | 82 | for(var i = 0; i < 32; i++){ str += hex[(b[i] >> 4) & 0xF] + hex[b[i] & 0xF]; } 83 | 84 | return str; 85 | }//____________________________________________________________________________ 86 | 87 | var state = blake_iv.slice(0); 88 | 89 | state[0] ^= 0x1010020; // params 90 | 91 | if(prefix) blake2s_core(state, prefix, 64, msg.length > 0); 92 | 93 | blake2s_core(state, msg, false); 94 | 95 | var H = new Array(32); 96 | 97 | for(var i = 0; i < 8; i++) 98 | { 99 | H[i*4] = (state[i] ) & 0xFF; 100 | H[i*4+1] = (state[i] >> 8) & 0xFF; 101 | H[i*4+2] = (state[i] >> 16) & 0xFF; 102 | H[i*4+3] = (state[i] >>> 24); 103 | } 104 | 105 | return (out == 'bin' ? H : hash2hex(H, out)); 106 | }//____________________________________________________________________________ 107 | 108 | function Blake2s_HMAC(msg, key, out) // key is a 32-byte array 109 | { 110 | var ipad = new Array(64); 111 | var opad = new Array(64); 112 | 113 | for(var i = 0; i < 64; i++) 114 | { 115 | var k = (i < 32 ? key[i] & 0xFF : 0); 116 | 117 | ipad[i] = k ^ 0x36; 118 | opad[i] = k ^ 0x5c; 119 | } 120 | 121 | var H = Blake2s(msg, 'bin', ipad); 122 | return Blake2s(H, out, opad); 123 | }//____________________________________________________________________________ 124 | -------------------------------------------------------------------------------- /js/crypto/blake2s.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function blake2s_core(r,e,a){function n(r,e,a,n,i,l){var o;k[r]=k[r]+k[e]+i,o=k[n]^k[r],k[n]=o>>>16|o<<16,k[a]=k[a]+k[n],o=k[e]^k[a],k[e]=o>>>12|o<<20,k[r]=k[r]+k[e]+l,o=k[n]^k[r],k[n]=o>>>8|o<<24,k[a]=k[a]+k[n],o=k[e]^k[a],k[e]=o>>>7|o<<25}var i,l,o=0,v=e.length,f=new Array(16),k=new Array(16),b=new Array(64),t=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3,11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4,7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8,9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13,2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9,12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11,13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10,6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5,10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0];for(i=0;i<8;i++)k[i]=r[i];if(v||!r[8])do{for(l=64,v<=64&&(l=v,a||(r[10]=-1)),r[8]+=l,i=0;i>2]=b[i]|b[i+1]<<8|b[i+2]<<16|b[i+3]<<24;for(k[8]=blake_iv[0],k[12]=r[8]^blake_iv[4],k[9]=blake_iv[1],k[13]=r[9]^blake_iv[5],k[10]=blake_iv[2],k[14]=r[10]^blake_iv[6],k[11]=blake_iv[3],k[15]=r[11]^blake_iv[7],i=0;i<160;i+=16)n(0,4,8,12,f[t[i+0]],f[t[i+1]]),n(1,5,9,13,f[t[i+2]],f[t[i+3]]),n(2,6,10,14,f[t[i+4]],f[t[i+5]]),n(3,7,11,15,f[t[i+6]],f[t[i+7]]),n(0,5,10,15,f[t[i+8]],f[t[i+9]]),n(1,6,11,12,f[t[i+10]],f[t[i+11]]),n(2,7,8,13,f[t[i+12]],f[t[i+13]]),n(3,4,9,14,f[t[i+14]],f[t[i+15]]);for(i=0;i<8;i++)r[i]^=k[i]^k[i+8],k[i]=r[i];o+=64,v-=64}while(v>0)}function Blake2s(r,e,a){var n=blake_iv.slice(0);n[0]^=16842784,a&&blake2s_core(n,a,64,r.length>0),blake2s_core(n,r,!1);for(var i=new Array(32),l=0;l<8;l++)i[4*l]=255&n[l],i[4*l+1]=n[l]>>8&255,i[4*l+2]=n[l]>>16&255,i[4*l+3]=n[l]>>>24;return"bin"==e?i:function(r,e){for(var a="",n="HEX"==e?"0123456789ABCDEF":"0123456789abcdef",i=0;i<32;i++)a+=n[r[i]>>4&15]+n[15&r[i]];return a}(i,e)}function Blake2s_HMAC(r,e,a){for(var n=new Array(64),i=new Array(64),l=0;l<64;l++){var o=l<32?255&e[l]:0;n[l]=54^o,i[l]=92^o}return Blake2s(Blake2s(r,"bin",n),a,i)}var blake_iv=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225,0,0,0,0]; -------------------------------------------------------------------------------- /js/crypto/salsa20.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | /* 5 | 'key' is 32 bytes, 'nonce' is 8 bytes. All parameters can be strings, Uint8Array's or regular JS arrays. 6 | */ 7 | function salsa20(msg, key, nonce) 8 | { 9 | var i, m = msg, len = m.length, k = [], out = [], x = [16]; 10 | 11 | function str2arr(s){ var t = []; for(var i = 0; i < s.length; i++){ t.push(s.charCodeAt(i) & 0xFF); } return t; } 12 | 13 | if(typeof(msg) == 'string') m = str2arr(msg); 14 | if(typeof(key) == 'string') key = str2arr(key); 15 | if(typeof(nonce) == 'string') nonce = str2arr(nonce); 16 | 17 | for(i = 0; i < 32; i += 4){ k.push((key[i] | (key[i+1] << 8) | (key[i+2] << 16) | (key[i+3] << 24)) >>> 0); } 18 | 19 | var state = [ 0x61707865, k[0], k[1], k[2], k[3], 0x3320646e, 0, 0, 0, 0, 0x79622d32, k[4], k[5], k[6], k[7], 0x6b206574 ]; 20 | 21 | if(nonce.length >= 8) 22 | { 23 | state[6] = (nonce[0] | (nonce[1] << 8) | (nonce[2] << 16) | (nonce[3] << 24)) >>> 0; 24 | state[7] = (nonce[4] | (nonce[5] << 8) | (nonce[6] << 16) | (nonce[7] << 24)) >>> 0; 25 | } 26 | 27 | function STEP(a, b, c, d) 28 | { 29 | var t = x[d] + x[c]; x[a] ^= (t << 7) | (t >>> 25); 30 | t = x[a] + x[d]; x[b] ^= (t << 9) | (t >>> 23); 31 | t = x[b] + x[a]; x[c] ^= (t << 13) | (t >>> 19); 32 | t = x[c] + x[b]; x[d] ^= (t << 18) | (t >>> 14); 33 | } 34 | 35 | while(len > 0) 36 | { 37 | for(i = 0; i < 16; i++) x[i] = state[i]; 38 | 39 | for(i = 0; i < 10; i++) 40 | { 41 | STEP( 4, 8, 12, 0); STEP( 9, 13, 1, 5); 42 | STEP(14, 2, 6, 10); STEP( 3, 7, 11, 15); 43 | STEP( 1, 2, 3, 0); STEP( 6, 7, 4, 5); 44 | STEP(11, 8, 9, 10); STEP(12, 13, 14, 15); 45 | } 46 | 47 | for(i = 0; i < 16; i++) x[i] += state[i]; 48 | 49 | state[8]++; 50 | 51 | var sz = (len < 64 ? len : 64), pos = m.length - len; len -= 64; 52 | 53 | for(i = 0; i < sz; i++){ out[pos+i] = m[pos+i] ^ (x[i>>2] >>> ((i&3)<<3)) & 0xFF; } 54 | } 55 | 56 | if(typeof(msg) == 'string') 57 | { 58 | for(var i = 0; i < out.length; i++){ out[i] = String.fromCharCode(out[i]); } 59 | 60 | return out.join(''); 61 | } 62 | 63 | if(msg instanceof Uint8Array) return new Uint8Array(out); 64 | 65 | return out; 66 | } 67 | -------------------------------------------------------------------------------- /js/crypto/salsa20.min.js: -------------------------------------------------------------------------------- 1 | function salsa20(r,n,t){function o(r){for(var n=[],t=0;t>>25,f=s[r]+s[o],s[n]^=f<<9|f>>>23,f=s[n]+s[r],s[t]^=f<<13|f>>>19,f=s[t]+s[n],s[o]^=f<<18|f>>>14}var e,a=r,i=a.length,g=[],h=[],s=[16];for("string"==typeof r&&(a=o(r)),"string"==typeof n&&(n=o(n)),"string"==typeof t&&(t=o(t)),e=0;e<32;e+=4)g.push((n[e]|n[e+1]<<8|n[e+2]<<16|n[e+3]<<24)>>>0);var u=[1634760805,g[0],g[1],g[2],g[3],857760878,0,0,0,0,2036477234,g[4],g[5],g[6],g[7],1797285236];for(t.length>=8&&(u[6]=(t[0]|t[1]<<8|t[2]<<16|t[3]<<24)>>>0,u[7]=(t[4]|t[5]<<8|t[6]<<16|t[7]<<24)>>>0);i>0;){for(e=0;e<16;e++)s[e]=u[e];for(e=0;e<10;e++)f(4,8,12,0),f(9,13,1,5),f(14,2,6,10),f(3,7,11,15),f(1,2,3,0),f(6,7,4,5),f(11,8,9,10),f(12,13,14,15);for(e=0;e<16;e++)s[e]+=u[e];u[8]++;var l=i<64?i:64,p=a.length-i;for(i-=64,e=0;e>2]>>>((3&e)<<3)&255}if("string"==typeof r){for(var e=0;e> 28) & 0xF] + hex[(a >> 24) & 0xF] + 20 | hex[(a >> 20) & 0xF] + hex[(a >> 16) & 0xF] + 21 | hex[(a >> 12) & 0xF] + hex[(a >> 8) & 0xF] + 22 | hex[(a >> 4) & 0xF] + hex[(a ) & 0xF]; 23 | } 24 | 25 | return str; 26 | }//___________________________________________________________________________ 27 | 28 | var bitlen = msg.length * 8, last = (((bitlen + 64) >> 9) << 4) + 15; 29 | 30 | //if(typeof(msg) == 'string'){ msg = unescape(encodeURIComponent(msg)); } // encode UTF-8 <-- this should probably be outside... 31 | 32 | function read_str(idx) 33 | { 34 | var p = idx << 2, out = (p < msg.length ? msg.charCodeAt(p) << 24 | msg.charCodeAt(p+1) << 16 | msg.charCodeAt(p+2) << 8 | msg.charCodeAt(p+3) : 0); 35 | 36 | if(idx == (bitlen >> 5)){ out |= 0x80 << (24 - (bitlen & 31)); } 37 | 38 | return out; 39 | } 40 | 41 | function read_bytes(idx) 42 | { 43 | var p = idx << 2, out = (p < msg.length ? (msg[p] << 24) | (msg[p+1] << 16) | (msg[p+2] << 8) | msg[p+3] : 0); 44 | 45 | if(idx == (bitlen >> 5)){ out |= 0x80 << (24 - (bitlen & 31)); } 46 | 47 | return out; 48 | } 49 | 50 | var read = (typeof(msg) == 'string' ? read_str : read_bytes), len = last+1 51 | 52 | var a, b, c, d, e, f, g, h, i, j, p, t, w = new Array(64); 53 | 54 | var k = [0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2]; 55 | var H = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19]; 56 | 57 | for(i = 0; i < len; i += 16) 58 | { 59 | a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; 60 | 61 | for(j = 0; j < 64; j++) 62 | { 63 | if(j < 16) 64 | { 65 | w[j] = (j+i == last ? bitlen : read(j+i)); 66 | } 67 | else 68 | { 69 | t = w[j-15]; t = (t >>> 7 | t << 25) ^ (t >>> 18 | t << 14) ^ (t >>> 3); 70 | p = w[j- 2]; t += (p >>> 17 | p << 15) ^ (p >>> 19 | p << 13) ^ (p >>> 10); 71 | 72 | w[j] = t + w[j-7] + w[j-16]; 73 | } 74 | 75 | t = h + ((e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7)); 76 | 77 | t += ((e & f) ^ (~e & g)) + k[j] + w[j]; 78 | 79 | h = g; g = f; f = e; e = (d + t) >>> 0; d = c; c = b; b = a; 80 | 81 | t += (b >>> 2 | b << 30) ^ (b >>> 13 | b << 19) ^ (b >>> 22 | b << 10); 82 | 83 | a = (t + ((b & c) ^ (b & d) ^ (c & d))) >>> 0; 84 | } 85 | 86 | H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; H[5] += f; H[6] += g; H[7] += h; 87 | } 88 | 89 | return (out == 'bin' ? H : hash2hex(H)); 90 | } 91 | -------------------------------------------------------------------------------- /js/crypto/sha256.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function SHA256(r,t){function n(t){var n=t<<2,e=n>5&&(e|=128<<24-(31&l)),e}function e(t){var n=t<<2,e=n>5&&(e|=128<<24-(31&l)),e}var o,a,c,f,u,h,i,A,d,C,g,v,l=8*r.length,s=15+(l+64>>9<<4),b="string"==typeof r?n:e,y=s+1,E=new Array(64),H=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],p=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];for(d=0;d>>7|v<<25)^(v>>>18|v<<14)^v>>>3,g=E[C-2],v+=(g>>>17|g<<15)^(g>>>19|g<<13)^g>>>10,E[C]=v+E[C-7]+E[C-16]),v=A+((u>>>6|u<<26)^(u>>>11|u<<21)^(u>>>25|u<<7)),v+=(u&h^~u&i)+H[C]+E[C],A=i,i=h,h=u,u=f+v>>>0,f=c,c=a,a=o,v+=(a>>>2|a<<30)^(a>>>13|a<<19)^(a>>>22|a<<10),o=v+(a&c^a&f^c&f)>>>0;p[0]+=o,p[1]+=a,p[2]+=c,p[3]+=f,p[4]+=u,p[5]+=h,p[6]+=i,p[7]+=A}return"bin"==t?p:function(r){for(var n,e="",o="HEX"==t?"0123456789ABCDEF":"0123456789abcdef",a=0;a<8;a++)n=r[a],e+=o[n>>28&15]+o[n>>24&15]+o[n>>20&15]+o[n>>16&15]+o[n>>12&15]+o[n>>8&15]+o[n>>4&15]+o[15&n];return e}(p)} -------------------------------------------------------------------------------- /js/crypto/sha512.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 'use strict'; 5 | 6 | function _i64(){ } 7 | 8 | var p = _i64.prototype; 9 | 10 | p.from = function(hi, lo){ this.hi = hi; this.lo = lo; }; 11 | //____________________________________________________________________________ 12 | 13 | p.add = function(v) 14 | { 15 | var $ = this, lsw, msw; 16 | 17 | lsw = ($.lo & 0xFFFF) + (v.lo & 0xFFFF); 18 | msw = ($.lo >>> 16) + (v.lo >>> 16) + (lsw >>> 16); 19 | $.lo = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); 20 | 21 | lsw = ($.hi & 0xFFFF) + (v.hi & 0xFFFF) + (msw >>> 16); 22 | msw = ($.hi >>> 16) + (v.hi >>> 16) + (lsw >>> 16); 23 | $.hi = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); 24 | 25 | return $; 26 | };//___________________________________________________________________________ 27 | 28 | p.s0 = function(v) 29 | { 30 | this.hi = ((v.hi >>> 28) | (v.lo << 4)) ^ ((v.lo >>> 2) | (v.hi << 30)) ^ ((v.lo >>> 7) | (v.hi << 25)); 31 | this.lo = ((v.lo >>> 28) | (v.hi << 4)) ^ ((v.hi >>> 2) | (v.lo << 30)) ^ ((v.hi >>> 7) | (v.lo << 25)); 32 | };//___________________________________________________________________________ 33 | 34 | p.s1 = function(v) 35 | { 36 | this.hi = ((v.hi >>> 14) | (v.lo << 18)) ^ ((v.hi >>> 18) | (v.lo << 14)) ^ ((v.lo >>> 9) | (v.hi << 23)); 37 | this.lo = ((v.lo >>> 14) | (v.hi << 18)) ^ ((v.lo >>> 18) | (v.hi << 14)) ^ ((v.hi >>> 9) | (v.lo << 23)); 38 | 39 | return this; 40 | };//___________________________________________________________________________ 41 | 42 | p.g0 = function(v) 43 | { 44 | this.hi = ((v.hi >>> 1) | (v.lo << 31)) ^ ((v.hi >>> 8) | (v.lo << 24)) ^ (v.hi >>> 7); 45 | this.lo = ((v.lo >>> 1) | (v.hi << 31)) ^ ((v.lo >>> 8) | (v.hi << 24)) ^ (v.lo >>> 7 | (v.hi << 25)); 46 | };//___________________________________________________________________________ 47 | 48 | p.g1 = function(v) 49 | { 50 | this.hi = ((v.hi >>> 19) | (v.lo << 13)) ^ ((v.lo >>> 29) | (v.hi << 3)) ^ (v.hi >>> 6); 51 | this.lo = ((v.lo >>> 19) | (v.hi << 13)) ^ ((v.hi >>> 29) | (v.lo << 3)) ^ (v.lo >>> 6 | (v.hi << 26)); 52 | 53 | return this; 54 | };//___________________________________________________________________________ 55 | 56 | p.ch = function(x, y, z) 57 | { 58 | this.hi = (x.hi & y.hi) ^ (~x.hi & z.hi); 59 | this.lo = (x.lo & y.lo) ^ (~x.lo & z.lo); 60 | 61 | return this; 62 | };//___________________________________________________________________________ 63 | 64 | p.maj = function(x, y, z) 65 | { 66 | this.hi = (x.hi & y.hi) ^ (x.hi & z.hi) ^ (y.hi & z.hi); 67 | this.lo = (x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo); 68 | 69 | return this; 70 | };//___________________________________________________________________________ 71 | 72 | p.K = [ 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, 73 | 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, 74 | 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, 75 | 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, 76 | 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, 77 | 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, 78 | 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, 79 | 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, 80 | 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, 81 | 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817]; 82 | 83 | p.w = new Array(90); for(var i = 0; i < 90; i++) p.w[i] = new _i64(); 84 | 85 | p.hash2hex = function(b, out) // for some weird reason it's much faster here 86 | { 87 | var str = '', hex = (out == 'HEX' ? '0123456789ABCDEF' : '0123456789abcdef'); 88 | 89 | for(var i = 0; i < 16; i++) 90 | { 91 | var a = b[i]; 92 | 93 | str += hex[((a >> 28) & 0xF)] + hex[((a >> 24) & 0xF)] + 94 | hex[((a >> 20) & 0xF)] + hex[((a >> 16) & 0xF)] + 95 | hex[((a >> 12) & 0xF)] + hex[((a >> 8) & 0xF)] + 96 | hex[((a >> 4) & 0xF)] + hex[((a ) & 0xF)]; 97 | } 98 | 99 | return str; 100 | };//__________________________________________________________________________ 101 | 102 | p.hash2bin = function(b) 103 | { 104 | var i, r = new Array(64); 105 | 106 | for(i = 0; i < 64; i++){ r[i] = (b[i>>2] >> (24 - ((i&3)<<3))) & 0xFF; } 107 | 108 | return r; 109 | };//___________________________________________________________________________ 110 | 111 | // 'msg' can be a string, Uint8Array or regular JS array 112 | // 'out' can be 'bin', 'hex' or 'HEX' 113 | 114 | function SHA512(msg, out) 115 | { 116 | function add(x, idx, y) 117 | { 118 | var t = (x[idx+1] + y.lo); 119 | var c = ((x[idx+1] & y.lo) | (x[idx+1] | y.lo) & ~t) >>> 31; 120 | 121 | x[idx+1] = t; x[idx] = (x[idx] + y.hi + c); 122 | } 123 | 124 | var H = [0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1, 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179]; 125 | 126 | var bitlen = msg.length * 8, last = (((bitlen + 128) >> 10) << 5) + 31; 127 | 128 | //if(typeof(msg) == 'string'){ msg = unescape(encodeURIComponent(msg)); } // encode UTF-8 <-- this should probably be outside... 129 | 130 | function read_str(idx) 131 | { 132 | var p = idx << 2, out = (p < msg.length ? msg.charCodeAt(p) << 24 | msg.charCodeAt(p+1) << 16 | msg.charCodeAt(p+2) << 8 | msg.charCodeAt(p+3) : 0); 133 | 134 | if(idx == (bitlen >> 5)){ out |= 0x80 << (24 - (bitlen & 31)); } 135 | 136 | return out; 137 | } 138 | 139 | function read_bytes(idx) 140 | { 141 | var p = idx << 2, out = (p < msg.length ? (msg[p] << 24) | (msg[p+1] << 16) | (msg[p+2] << 8) | msg[p+3] : 0); 142 | 143 | if(idx == (bitlen >> 5)){ out |= 0x80 << (24 - (bitlen & 31)); } 144 | 145 | return out; 146 | } 147 | 148 | var read = (typeof(msg) == 'string' ? read_str : read_bytes); 149 | 150 | var i, j, w = p.w, a = w[80], b = w[81], c = w[82], d = w[83], e = w[84], f = w[85], g = w[86], h = w[87], k = w[88], t = w[89]; 151 | 152 | for(i = 0; i < last+1; i += 32) 153 | { 154 | a.from(H[0], H[1]); b.from(H[ 2], H[ 3]); c.from(H[ 4], H[ 5]); d.from(H[ 6], H[ 7]); 155 | e.from(H[8], H[9]); f.from(H[10], H[11]); g.from(H[12], H[13]); h.from(H[14], H[15]); 156 | 157 | for(j = 0; j < 80; j++) 158 | { 159 | if(j < 16) 160 | { 161 | if(j*2+i+1 == last){ p.w[j].hi = 0; p.w[j].lo = bitlen; } 162 | else { p.w[j].from(read(j*2+i), read(j*2+i+1)); } 163 | } 164 | else 165 | { 166 | k.g0(p.w[j-15]); p.w[j].g1(p.w[j-2]).add(p.w[j-7]).add(k).add(p.w[j-16]); 167 | } 168 | 169 | k.from(p.K[j*2], p.K[j*2+1]); k.add(p.w[j]); 170 | 171 | t.ch(e,f,g).add(h); h.s1(e).add(k); t.add(h); 172 | 173 | var ta = h; h = g; g = f; f = e; e = d; d = c; c = b; b = a; 174 | 175 | e.add(t); k.s0(a); ta.maj(b,c,d).add(k).add(t); a = ta; 176 | } 177 | 178 | add(H, 0, a); add(H, 2, b); add(H, 4, c); add(H, 6, d); 179 | add(H, 8, e); add(H,10, f); add(H,12, g); add(H,14, h); 180 | } 181 | 182 | return (out == 'bin' ? p.hash2bin(H) : p.hash2hex(H, out)); 183 | } -------------------------------------------------------------------------------- /js/crypto/sha512.min.js: -------------------------------------------------------------------------------- 1 | "use strict";function _i64(){}function SHA512(i,h){function o(i,h,o){var r=i[h+1]+o.lo,t=(i[h+1]&o.lo|(i[h+1]|o.lo)&~r)>>>31;i[h+1]=r,i[h]=i[h]+o.hi+t}function r(h){var o=h<<2,r=o>5&&(r|=128<<24-(31&f)),r}function t(h){var o=h<<2,r=o>5&&(r|=128<<24-(31&f)),r}var l,n,a=[1779033703,4089235720,3144134277,2227873595,1013904242,4271175723,2773480762,1595750129,1359893119,2917565137,2600822924,725511199,528734635,4215389547,1541459225,327033209],f=8*i.length,s=31+(f+128>>10<<5),d="string"==typeof i?r:t,e=p.w,u=e[80],c=e[81],w=e[82],m=e[83],v=e[84],g=e[85],A=e[86],C=e[87],b=e[88],y=e[89];for(l=0;l>>16)+(i.lo>>>16)+(h>>>16),r.lo=(65535&o)<<16|65535&h,h=(65535&r.hi)+(65535&i.hi)+(o>>>16),o=(r.hi>>>16)+(i.hi>>>16)+(h>>>16),r.hi=(65535&o)<<16|65535&h,r},p.s0=function(i){this.hi=(i.hi>>>28|i.lo<<4)^(i.lo>>>2|i.hi<<30)^(i.lo>>>7|i.hi<<25),this.lo=(i.lo>>>28|i.hi<<4)^(i.hi>>>2|i.lo<<30)^(i.hi>>>7|i.lo<<25)},p.s1=function(i){return this.hi=(i.hi>>>14|i.lo<<18)^(i.hi>>>18|i.lo<<14)^(i.lo>>>9|i.hi<<23),this.lo=(i.lo>>>14|i.hi<<18)^(i.lo>>>18|i.hi<<14)^(i.hi>>>9|i.lo<<23),this},p.g0=function(i){this.hi=(i.hi>>>1|i.lo<<31)^(i.hi>>>8|i.lo<<24)^i.hi>>>7,this.lo=(i.lo>>>1|i.hi<<31)^(i.lo>>>8|i.hi<<24)^(i.lo>>>7|i.hi<<25)},p.g1=function(i){return this.hi=(i.hi>>>19|i.lo<<13)^(i.lo>>>29|i.hi<<3)^i.hi>>>6,this.lo=(i.lo>>>19|i.hi<<13)^(i.hi>>>29|i.lo<<3)^(i.lo>>>6|i.hi<<26),this},p.ch=function(i,h,o){return this.hi=i.hi&h.hi^~i.hi&o.hi,this.lo=i.lo&h.lo^~i.lo&o.lo,this},p.maj=function(i,h,o){return this.hi=i.hi&h.hi^i.hi&o.hi^h.hi&o.hi,this.lo=i.lo&h.lo^i.lo&o.lo^h.lo&o.lo,this},p.K=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],p.w=new Array(90);for(var i=0;i<90;i++)p.w[i]=new _i64;p.hash2hex=function(i,h){for(var o="",r="HEX"==h?"0123456789ABCDEF":"0123456789abcdef",t=0;t<16;t++){var l=i[t];o+=r[l>>28&15]+r[l>>24&15]+r[l>>20&15]+r[l>>16&15]+r[l>>12&15]+r[l>>8&15]+r[l>>4&15]+r[15&l]}return o},p.hash2bin=function(i){var h,o=new Array(64);for(h=0;h<64;h++)o[h]=i[h>>2]>>24-((3&h)<<3)&255;return o}; -------------------------------------------------------------------------------- /js/crypto/tests/blake2s.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Blake2s test 5 | 6 | 7 | 8 | 9 | Testing... (see console) 10 | 11 | 80 | 81 | -------------------------------------------------------------------------------- /js/crypto/tests/sha256.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SHA-256 test 5 | 6 | 7 | 8 | 9 | Testing... (see console) 10 | 11 | 62 | 63 | -------------------------------------------------------------------------------- /js/crypto/tests/sha512.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SHA-512 test 5 | 6 | 7 | 8 | 9 | Testing... (see console) 10 | 11 | 62 | 63 | -------------------------------------------------------------------------------- /js/css_parser/README.md: -------------------------------------------------------------------------------- 1 | 2 | # The simplest CSS parser/compiler 3 | 4 | Based on https://github.com/reworkcss/css but rewritten and greatly simplified. 5 | 6 | ## Example: 7 | 8 | ```js 9 | var tree = css_parse('body { font-size: 12px; }'); 10 | 11 | var out = css_compile(tree, '\n'); 12 | ``` 13 | 14 | If 'silent' is set to 'true' in css_parse() it will add all the errors to the 'stylesheet.errors' array. 15 | 16 | Otherwise it will trigger an exception (the default behaviour). 17 | 18 | You can pass a callback function to css_compile() to be called before each node gets processed: 19 | 20 | ```js 21 | css_compile(tree, '\n\n', function(node){ /* pre-process here */ }); 22 | ``` 23 | -------------------------------------------------------------------------------- /js/css_parser/css_compile.js: -------------------------------------------------------------------------------- 1 | 2 | function css_compile(tree, delim, cb) // Example: css_compile(css_parse(text), '\n'); 3 | { 4 | delim = delim || ''; 5 | 6 | function visit(nodes) 7 | { 8 | for(var buf = '', i = 0; i < nodes.length; i++) 9 | { 10 | var n = nodes[i]; if(cb) cb(n); 11 | 12 | var txt = this[n.type](n); 13 | 14 | if(txt){ buf += txt; if(txt.length && n.selectors) buf += delim; } 15 | } 16 | 17 | return buf; 18 | }//___________________________________________________________________________ 19 | 20 | this.comment = function(node){ return ''; }; 21 | this.import = function(node){ return '@import ' + node.import + ';'; }; 22 | this.charset = function(node){ return '@charset ' + node.name + ';'; }; 23 | this.namespace = function(node){ return '@namespace ' + node.name + ';'; }; 24 | this['custom-media'] = function(node){ return '@custom-media ' + node.name + ' ' + node.media + ';'; }; 25 | this.media = function(node){ return '@media ' + node.media + '{' + visit(node.rules) + '}'; }; 26 | this.supports = function(node){ return '@supports ' + node.name + '{' + visit(node.rules) + '}'; }; 27 | this['font-face'] = function(node){ return '@font-face' + '{' + visit(node.declarations) + '}'; }; 28 | this.host = function(node){ return '@host' + '{' + visit(node.rules) + '}'; }; 29 | this.keyframes = function(node){ return '@' + (node.vendor || '') + 'keyframes ' + node.name + '{' + visit(node.keyframes) + '}'; }; 30 | this.document = function(node){ return '@' + (node.vendor || '') + 'document ' + node.document + '{' + visit(node.rules) + '}'; }; 31 | this.page = function(node){ return '@page ' + (node.selectors.length ? node.selectors.join(', ') : '') + '{' + visit(node.declarations) + '}'; }; 32 | this.declaration = function(node){ return node.property + ':' + node.value + ';'; }; 33 | this.keyframe = function(node){ return node.values.join(',') + '{' + visit(node.declarations) + '}'; }; 34 | this.rule = function(node){ var decls = node.declarations; if(decls.length) return node.selectors.join(',') + '{' + visit(decls) + '}'; }; 35 | 36 | return visit(tree.stylesheet.rules); 37 | } 38 | -------------------------------------------------------------------------------- /js/css_parser/css_parse.js: -------------------------------------------------------------------------------- 1 | 2 | if(typeof(String.prototype.trim) !== 'function'){ String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g, ''); }; } 3 | //________________________________________________________________________________ 4 | 5 | function css_parse(css, silent) 6 | { 7 | var errors = []; 8 | 9 | function error(msg) 10 | { 11 | var err = new Error(msg + ' at "' + css.substr(0,100) + '..."'); 12 | 13 | err.reason = msg; if(silent) errors.push(err); else throw err; 14 | }//___________________________________________________________________________ 15 | 16 | function match(re){ var m = re.exec(css); if(m){ css = css.slice(m[0].length); return m; } } // match regexp and return captures 17 | //____________________________________________________________________________ 18 | 19 | function whitespace(){ match(/^\s*/); } 20 | 21 | function open(){ return match(/^{\s*/); } // opening brace 22 | function close(){ return match(/^}/); } // closing brace 23 | 24 | function comment() 25 | { 26 | whitespace(); 27 | 28 | if(css[0] != '/' || css[1] != '*') return; 29 | 30 | var i = 2; while(css[i] != '' && (css[i] != '*' || css[i+1] != '/')) i++; 31 | 32 | if(css[i+1] == '') return error('End of comment is missing'); 33 | 34 | var str = css.slice(2,i); css = css.slice(i+2); 35 | 36 | return { type: 'comment', comment: str }; 37 | } 38 | 39 | function comments(){ var c, cmnts = []; while(c = comment()){ cmnts.push(c); } return cmnts; } 40 | //____________________________________________________________________________ 41 | 42 | function selector() 43 | { 44 | whitespace(); while(css[0] == '}'){ error('extra closing bracket'); css = css.slice(1); whitespace(); } 45 | 46 | var m = match(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/); 47 | 48 | if(m) return m[0].trim() // remove all comments from selectors 49 | .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '') 50 | .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m){ return m.replace(/,/g, '\u200C'); }) 51 | .split(/\s*(?![^(]*\)),\s*/) 52 | .map(function(s){ return s.replace(/\u200C/g, ','); }); 53 | }//___________________________________________________________________________ 54 | 55 | function declaration() 56 | { 57 | match(/^([;\s]*)+/); // ignore empty declarations + whitespace 58 | 59 | const comment_regexp = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g; 60 | 61 | var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/); if(!prop) return; 62 | 63 | prop = prop[0].trim(); 64 | 65 | if(!match(/^:\s*/)) return error("property missing ':'"); 66 | 67 | // Quotes regex repeats verbatim inside and outside parentheses 68 | var val = match(/^((?:\/\*.*?\*\/|'(?:\\'|.)*?'|"(?:\\"|.)*?"|\((\s*'(?:\\'|.)*?'|"(?:\\"|.)*?"|[^)]*?)\s*\)|[^};])+)/); 69 | 70 | var ret = { type: 'declaration', property: prop.replace(comment_regexp, ''), value: val ? val[0].replace(comment_regexp, '').trim() : '' }; 71 | 72 | match(/^[;\s]*/); 73 | 74 | return ret; 75 | } 76 | 77 | function declarations() 78 | { 79 | if(!open()) return error("missing '{'"); 80 | 81 | var d, decls = comments(); while(d = declaration()){ decls.push(d); decls = decls.concat(comments()); } 82 | 83 | if(!close()) return error("missing '}'"); 84 | 85 | return decls; 86 | }//___________________________________________________________________________ 87 | 88 | function keyframe() 89 | { 90 | whitespace(); 91 | 92 | var m, vals = []; while(m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)){ vals.push(m[1]); match(/^,\s*/); } 93 | 94 | if(vals.length) return { type: 'keyframe', values: vals, declarations: declarations() }; 95 | } 96 | 97 | function at_keyframes() 98 | { 99 | var m = match(/^@([-\w]+)?keyframes\s*/); if(!m) return; 100 | 101 | var vendor = m[1]; 102 | 103 | var m = match(/^([-\w]+)\s*/); if(!m) return error("@keyframes missing name"); // identifier 104 | 105 | var name = m[1]; 106 | 107 | if(!open()) return error("@keyframes missing '{'"); 108 | 109 | var frame, frames = comments(); while(frame = keyframe()){ frames.push(frame); frames = frames.concat(comments()); } 110 | 111 | if(!close()) return error("@keyframes missing '}'"); 112 | 113 | return { type: 'keyframes', name: name, vendor: vendor, keyframes: frames }; 114 | }//___________________________________________________________________________ 115 | 116 | function at_page (){ var m = match(/^@page */); if(m){ var sel = selector() || []; return { type: 'page', selectors: sel, declarations: declarations() }; } } 117 | function at_fontface(){ var m = match(/^@font-face\s*/); if(m) return { type: 'font-face', declarations: declarations() }; } 118 | function at_supports(){ var m = match(/^@supports *([^{]+)/); if(m) return { type: 'supports', supports: m[1].trim(), rules: rules() }; } 119 | function at_host (){ var m = match(/^@host\s*/); if(m) return { type: 'host', rules: rules() }; } 120 | function at_media (){ var m = match(/^@media *([^{]+)/); if(m) return { type: 'media', media: m[1].trim(), rules: rules() }; } 121 | function at_custom_m(){ var m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/); if(m) return { type: 'custom-media', name: m[1].trim(), media: m[2].trim() }; } 122 | function at_document(){ var m = match(/^@([-\w]+)?document *([^{]+)/); if(m) return { type: 'document', document: m[2].trim(), vendor: m[1].trim(), rules: rules() }; } 123 | function at_x (){ var m = match(/^@(import|charset|namespace)\s*([^;]+);/); if(m) return { type: m[1], name: m[2].trim() }; } 124 | //____________________________________________________________________________ 125 | 126 | function at_rule() 127 | { 128 | whitespace(); if(css[0] == '@') return at_keyframes() || at_supports() || at_host() || at_media() || at_custom_m() || at_page() || at_document() || at_fontface() || at_x(); 129 | }//___________________________________________________________________________ 130 | 131 | function rule() 132 | { 133 | var sel = selector() || []; if(!sel.length) error('selector missing'); 134 | 135 | return { type: 'rule', selectors: sel, declarations: declarations() }; 136 | }//___________________________________________________________________________ 137 | 138 | function rules(core) 139 | { 140 | if(!core && !open()) return error("missing '{'"); 141 | 142 | var node, rules = comments(); 143 | 144 | while(css.length && (core || css[0] != '}') && (node = (at_rule() || rule()))) 145 | { 146 | rules.push(node); rules = rules.concat(comments()); 147 | } 148 | 149 | if(!core && !close()) return error("missing '}'"); 150 | 151 | return rules; 152 | }//___________________________________________________________________________ 153 | 154 | return { type: 'stylesheet', stylesheet: { rules: rules(true), errors: errors } }; 155 | } 156 | -------------------------------------------------------------------------------- /js/css_parser/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CSS parser/compiler test 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /js/fetchit/README.md: -------------------------------------------------------------------------------- 1 | 2 | # fetchit 3 | 4 | ## About 5 | 6 | A simple version of fetch() based on XMLHttpRequest. 7 | 8 | _Not a polyfill._ 9 | 10 | The main difference is that it treats bad statuses (like 404 or 500) as errors, so you don't have to check response.ok in resolve(), which is retarded. 11 | 12 | If response starts with '{' or '[' it is automatically parsed as JSON. 13 | 14 | And it allows specifying timeout in 'options', which defaults to 5 seconds. 15 | 16 | ## Usage 17 | 18 | ```js 19 | fetchit(url, [data, options]).then(function(r){...}).catch(function(error){...}); 20 | ``` 21 | 22 | **data** can either be FormData or a JS object, which will then be encoded as JSON and sent as GET or POST "data" parameter. 23 | 24 | **options**: 25 | 26 | * **method** - 'GET' or 'POST' 27 | * **timeout** - timeout in seconds, default is 5 28 | * **credentials** - 'include' or 'omit' 29 | * **headers** - additional HTTP headers 30 | -------------------------------------------------------------------------------- /js/fetchit/fetchit.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | function fetchit(url, data, options) 6 | { 7 | return new Promise(function(resolve, reject) 8 | { 9 | 'use strict'; 10 | 11 | options = (options || {}); 12 | 13 | var xhr = new XMLHttpRequest; 14 | 15 | var ue = false, method = (options.method || 'GET').toUpperCase(); 16 | 17 | if(data instanceof FormData) 18 | { 19 | method = 'POST'; 20 | } 21 | else if(data) 22 | { 23 | data = 'data=' + encodeURIComponent(JSON.stringify(data)); 24 | 25 | if(method == 'POST') ue = true; else 26 | if(method == 'GET' ) 27 | { 28 | url += (url.indexOf('?') < 0 ? '?' : '&') + data; data = null; 29 | } 30 | } 31 | 32 | xhr.open(method, url, true); 33 | 34 | xhr.onreadystatechange = function() 35 | { 36 | if(this.readyState !== 4) return; 37 | 38 | if(this.status === 200) 39 | { 40 | var r = this.responseText; 41 | 42 | if(r.length > 1 && (r[0] == '{' || r[0] == '[')) 43 | { 44 | try{ r = JSON.parse(r); } catch(e){ reject('bad response'); return; } 45 | 46 | // if(r.error != 'ok'){ reject(r.error); return; } // uncomment if you use 'error' member with 'ok' as success value 47 | } 48 | 49 | resolve(r); 50 | } 51 | else 52 | { 53 | reject('network error' + (this.status > 0 ? ': '+this.status : '')); 54 | } 55 | }; 56 | 57 | xhr.timeout = (options.timeout || 5) * 1000; // time in milliseconds 58 | 59 | if(options.credentials === 'include'){ xhr.withCredentials = true; } else 60 | if(options.credentials === 'omit' ){ xhr.withCredentials = false; } 61 | 62 | if(options.header) option.headers.forEach(function(value, name){ xhr.setRequestHeader(name, value); }); 63 | 64 | if(ue) xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 65 | 66 | xhr.send(data); 67 | }); 68 | } 69 | -------------------------------------------------------------------------------- /js/fetchit/fetchit.min.js: -------------------------------------------------------------------------------- 1 | function fetchit(e,t,n){return new Promise(function(s,i){"use strict";n=n||{};var r=new XMLHttpRequest,a=!1,o=(n.method||"GET").toUpperCase();t instanceof FormData?o="POST":t&&(t="data="+encodeURIComponent(JSON.stringify(t)),"POST"==o?a=!0:"GET"==o&&(e+=(e.indexOf("?")<0?"?":"&")+t,t=null)),r.open(o,e,!0),r.onreadystatechange=function(){if(4===this.readyState)if(200===this.status){var e=this.responseText;if(e.length>1&&("{"==e[0]||"["==e[0]))try{e=JSON.parse(e)}catch(e){return void i("bad response")}s(e)}else i("network error"+(this.status>0?": "+this.status:""))},r.timeout=1e3*(n.timeout||5),"include"===n.credentials?r.withCredentials=!0:"omit"===n.credentials&&(r.withCredentials=!1),n.header&&option.headers.forEach(function(e,t){r.setRequestHeader(t,e)}),a&&r.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),r.send(t)})} -------------------------------------------------------------------------------- /js/fetchit/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fetchit test 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 |
18 | Response:

19 |

20 | Error: 21 |
22 | 23 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /js/int64/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Int64 class for Javascript 3 | 4 | ## About 5 | 6 | A simple class to allow 64-bit calculations in Javascript. _Not a polyfill._ 7 | 8 | More info: https://medium.com/@nxtchg/simplifying-int64-polyfill-4a9c35441e25 9 | 10 | ## Usage 11 | 12 | ```js 13 | var v = new Int64(123); 14 | 15 | v.add(4).mul(555); 16 | 17 | var js_num = v.toNumber(); 18 | ``` 19 | 20 | See the code for all available methods, it's just 260 lines. 21 | -------------------------------------------------------------------------------- /js/int64/int64.js: -------------------------------------------------------------------------------- 1 | 2 | const POW2_32 = Math.pow(2, 32); 3 | const POW2_64 = Math.pow(2, 64); 4 | 5 | /* Constructors: 6 | - Int64(123) 7 | - Int64(Int64) 8 | - Int64(hi,lo) 9 | */ 10 | 11 | function Int64(v, low) 12 | { 13 | this.hi = this.lo = 0; if(v !== undefined) this.from(v, low); 14 | }//____________________________________________________________________________ 15 | 16 | Int64.prototype.is_eq = function(v){ return (this.hi == v.hi && this.lo == v.lo); }; 17 | Int64.prototype.is_nul = function(v){ return (this.hi == 0 && this.lo == 0); }; 18 | Int64.prototype.is_neg = function(v){ return (this.hi | 0) < 0; }; 19 | 20 | Int64.prototype.cmp = function(v, unsign) // compare: +1, 0, -1 21 | { 22 | var a = (unsign ? this.hi >>> 0 : this.hi | 0); 23 | var b = (unsign ? v.hi >>> 0 : v.hi | 0); 24 | 25 | if(a < b) return -1; 26 | if(a > b) return +1; 27 | 28 | if(this.lo < v.lo) return -1; 29 | if(this.lo > v.lo) return +1; 30 | 31 | return 0; 32 | };//___________________________________________________________________________ 33 | 34 | Int64.prototype.neg = function() 35 | { 36 | if(this.hi == 2147483648 && this.lo == 0){ this.hi--; this.lo = POW2_32-1; return; } // special case for 0x80000000|00000000 37 | 38 | var a = this.lo >>> 0; 39 | 40 | this.lo = (-a) >>> 0; 41 | 42 | var r = (a | (~a & this.lo)) >>> 31; 43 | 44 | this.hi = (-(this.hi >>> 0) - r) >>> 0; 45 | };//___________________________________________________________________________ 46 | 47 | Int64.prototype.abs = function(){ if(this.is_neg()) this.neg(); }; 48 | 49 | Int64.prototype.not = function(v) 50 | { 51 | if(!(v instanceof Int64)) v = new Int64(v); 52 | 53 | this.hi = (~this.hi) >>> 0; 54 | this.lo = (~this.lo) >>> 0; 55 | }; 56 | 57 | Int64.prototype.and = function(v) 58 | { 59 | if(!(v instanceof Int64)) v = new Int64(v); 60 | 61 | this.hi = (this.hi & v.hi) >>> 0; 62 | this.lo = (this.lo & v.lo) >>> 0; 63 | }; 64 | 65 | Int64.prototype.or = function(v) 66 | { 67 | if(!(v instanceof Int64)) v = new Int64(v); 68 | 69 | this.hi = (this.hi | v.hi) >>> 0; 70 | this.lo = (this.lo | v.lo) >>> 0; 71 | }; 72 | 73 | Int64.prototype.xor = function(v) 74 | { 75 | if(!(v instanceof Int64)) v = new Int64(v); 76 | 77 | this.hi = (this.hi ^ v.hi) >>> 0; 78 | this.lo = (this.lo ^ v.lo) >>> 0; 79 | }; 80 | //_____________________________________________________________________________ 81 | 82 | Int64.prototype.from = function(v, low) 83 | { 84 | if(low !== undefined){ this.hi = v; this.lo = low; return this; } 85 | if(v instanceof Int64){ this.hi = v.hi; this.lo = v.lo; return this; } 86 | 87 | var vi = Math.floor(Math.abs(v)) % POW2_64; 88 | 89 | this.hi = (vi / POW2_32) >>> 0; 90 | this.lo = (vi % POW2_32) >>> 0; 91 | 92 | if(v < 0) this.neg(); 93 | 94 | return this; 95 | };//___________________________________________________________________________ 96 | 97 | Int64.prototype.add = function(v) 98 | { 99 | if(!(v instanceof Int64)) v = new Int64(v); 100 | 101 | var t = (this.lo + v.lo) >>> 0; 102 | var c = ((this.lo & v.lo) | (this.lo | v.lo) & ~t) >>> 31; 103 | 104 | this.lo = t; this.hi = (this.hi + v.hi + c) >>> 0; 105 | 106 | return this; 107 | };//___________________________________________________________________________ 108 | 109 | Int64.prototype.sub = function(v) 110 | { 111 | if(!(v instanceof Int64)) v = new Int64(v); 112 | 113 | var t = ( this.lo - v.lo) >>> 0; 114 | var r = ((~this.lo & v.lo) | (~(this.lo ^ v.lo) & t)) >>> 31; 115 | 116 | this.lo = t; this.hi = (this.hi - v.hi - r) >>> 0; 117 | 118 | return this; 119 | };//___________________________________________________________________________ 120 | 121 | Int64.prototype.shl_1 = function() // shift left by one bit 122 | { 123 | this.hi = ((this.hi << 1) | this.lo >>> 31) >>> 0; 124 | this.lo = (this.lo << 1) >>> 0; 125 | }; 126 | 127 | Int64.prototype.shr_1 = function(unsign) // shift right by one bit 128 | { 129 | this.lo = ((this.lo >>> 1) | (this.hi << 31)) >>> 0; 130 | this.hi = (unsign ? this.hi >>> 1 : (this.hi >> 1) >>> 0 ); 131 | }; 132 | 133 | Int64.prototype.shl = function(n) // shift left by n bits 134 | { 135 | n %= 64; if(n < 1) return; 136 | 137 | this.hi = ((this.hi << n) | (this.lo >>> (32 - n))) >>> 0; 138 | this.lo = (this.lo << n) >>> 0; 139 | 140 | return this; 141 | }; 142 | 143 | Int64.prototype.shr = function(n, unsign) // shift right by n bits 144 | { 145 | n %= 64; if(n < 1) return; 146 | 147 | this.lo = ((this.lo >>> n) | (this.hi << (32 - n))) >>> 0; 148 | this.hi = (unsign ? this.hi >>> n : (this.hi >> n) >>> 0); 149 | 150 | return this; 151 | };//___________________________________________________________________________ 152 | 153 | Int64.prototype.mul = function(v) 154 | { 155 | var a = new Int64(this); 156 | var b = new Int64(v); 157 | 158 | this.hi = this.lo = 0; if(a.is_nul() || b.is_nul()) return this; 159 | 160 | var an = a.is_neg(); if(an) a.neg(); 161 | var bn = b.is_neg(); if(bn) b.neg(); 162 | 163 | if(a.cmp(b, true) < 0){ var tmp = a; a = b; b = tmp; } 164 | 165 | while(!b.is_nul()) 166 | { 167 | if(b.lo & 1) this.add(a); 168 | 169 | a.shl_1(); b.shr_1(); 170 | } 171 | 172 | if(an != bn) this.neg(); 173 | 174 | return this; 175 | };//___________________________________________________________________________ 176 | 177 | if(!Math.clz32){ Math.clz32 = function(x){ return (x === 0 ? 32 : 31 - Math.floor(Math.log(x >>> 0) * Math.LOG2E)); }; } 178 | 179 | Int64.prototype.clz = function(){ return this.hi ? Math.clz32(this.hi) : Math.clz32(this.lo) + 32; }; 180 | 181 | Int64.prototype._do_div = function(a, b, mod) 182 | { 183 | var q = new Int64(); 184 | 185 | switch(a.cmp(b, true)) 186 | { 187 | case -1:/*a = a; q = new Int64( );*/ break; 188 | case 0: a = q; q = new Int64(1); break; 189 | case +1: 190 | { 191 | var shift = b.clz() - a.clz(); b.shl(shift); 192 | 193 | while(shift-- >= 0) 194 | { 195 | q.shl_1(); 196 | 197 | if(!a.is_nul() && a.cmp(b, true) >= 0){ a.sub(b); q.lo |= 1; } 198 | 199 | b.shr_1(); 200 | } 201 | } 202 | } 203 | 204 | this.from(mod ? a : q); 205 | }; 206 | 207 | Int64.prototype.div = function(v, mod) 208 | { 209 | var a = new Int64(this); 210 | var b = new Int64(v); if(b.is_nul()) throw 'division by zero'; 211 | 212 | //if(b.is_one()) return; 213 | 214 | var an = a.is_neg(); if(an) a.neg(); 215 | var bn = b.is_neg(); if(bn) b.neg(); 216 | 217 | this._do_div(a, b, mod); 218 | 219 | if((mod && an) | (!mod && an != bn)) this.neg(); 220 | 221 | return this; 222 | }; 223 | 224 | Int64.prototype.mod = function(v){ this.div(v, true); return this; }; 225 | //_____________________________________________________________________________ 226 | 227 | Int64.prototype.toNumber = function() 228 | { 229 | if(this.is_neg()){ var t = new Int64(this); t.neg(); return -(t.hi * POW2_32 + t.lo); } 230 | 231 | return (this.hi * POW2_32 + this.lo); 232 | };//___________________________________________________________________________ 233 | 234 | Int64.prototype.toString = function(base) 235 | { 236 | var sign = '', t = new Int64(this); base = base || 10; 237 | 238 | if(t.is_neg()){ t.neg(); sign = '-'; } 239 | 240 | var s = '', n, v0 = t.lo, v1 = t.hi; 241 | 242 | if(base == 2) 243 | { 244 | for(n = 0; n < 32; n++) s = ((v0 >> n) & 1).toString(base) + s; 245 | for(n = 0; n < 32; n++) s = ((v1 >> n) & 1).toString(base) + s; 246 | 247 | return sign + s.replace(/^0+/, '') || '0'; 248 | } 249 | 250 | if(base == 16) 251 | { 252 | for(n = 0; n < 32; n += 4) s = ((v0 >> n) & 0xF).toString(base) + s; 253 | for(n = 0; n < 32; n += 4) s = ((v1 >> n) & 0xF).toString(base) + s; 254 | 255 | return sign + s.replace(/^0+/, '') || '0'; 256 | } 257 | 258 | return this.toNumber().toString(base); 259 | };//___________________________________________________________________________ 260 | 261 | Int64.prototype.print = function() 262 | { 263 | var a = ('00000000' + this.hi.toString(16)).slice(-8); 264 | var b = ('00000000' + this.lo.toString(16)).slice(-8); 265 | 266 | console.log('['+a+'|'+b+']', this.toNumber()); 267 | } 268 | -------------------------------------------------------------------------------- /js/jslib/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Javascript helpers 3 | 4 | Helper libraries, like jQuery, are usually bloated and there is no easy way to select only individual parts you need. 5 | 6 | This is a collection of small, stand-alone pieces you can easily combine into a single JS file with the _merge.bat_ script. 7 | 8 | They all use a global **"js"** root object as a namespace, for example `js.get_cookie()`. 9 | 10 | The code is usually so simple you don't even need any additional documentation. 11 | 12 | Feel free to submit your own pieces, provided they are small and beautiful :) 13 | -------------------------------------------------------------------------------- /js/jslib/jslib.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | var js = {}; // it all starts with a small first step 6 | 7 | function defined(a){ return (a !== void 0 && a !== null); } 8 | 9 | js.$ = function(id){ return document.getElementById(id); }; 10 | 11 | js.is_array = function(obj){ return (obj && obj.constructor === Array); }; 12 | 13 | js.cb = function(obj, fn){ return function(){ return fn.apply(obj, arguments); }; }; // bind 'this' and function together 14 | //_____________________________________________________________________________ 15 | 16 | js.count = function(obj) // returns the number of elements in both arrays and objects 17 | { 18 | var cnt = 0; if(defined(obj.length)) return obj.length; 19 | 20 | for(var p in obj){ if(obj.hasOwnProperty(p)) cnt++; } 21 | 22 | return cnt; 23 | };//___________________________________________________________________________ 24 | 25 | // neat way to convert a string into array: js.clone([], 'test') 26 | 27 | js.clone = function(obj) // any additional arguments will be added to the clone 28 | { 29 | if(obj === null || typeof(obj) !== 'object') return obj; 30 | 31 | var a = arguments, c = new obj.constructor(); 32 | 33 | for(var i = 0; i < a.length; i++) 34 | { 35 | for(var k in a[i]) 36 | { 37 | if(a[i].hasOwnProperty(k)) c[k] = js.clone(a[i][k]); 38 | } 39 | } 40 | 41 | return c; 42 | };//___________________________________________________________________________ 43 | 44 | js.encode_utf8 = function(s){ return unescape(encodeURIComponent(s)); }; // JS str => utf-8 45 | js.decode_utf8 = function(s){ return decodeURIComponent(escape (s)); }; // utf-8 => JS str 46 | //_____________________________________________________________________________ 47 | 48 | js.round = function(n, precision, down) // fixes nasty JS rounding and behaves like PHP round() 49 | { 50 | var neg = (n < 0), factor = Math.pow(10, precision); 51 | 52 | var t = Math.abs(n) * factor; 53 | 54 | t = (down ? Math.floor(t) : Math.round(t)); 55 | 56 | return (neg ? -t : t) / factor; 57 | };//___________________________________________________________________________ 58 | 59 | js.round_sig = function(n, digits) // round to a certain number of significant digits 60 | { 61 | return js.round(n, digits - Math.floor(Math.log10(Math.abs(n))) - 1); 62 | };//___________________________________________________________________________ 63 | 64 | 65 | String.prototype.trim = String.prototype.trim || function(){ return this.replace(/(^\s+)|(\s+$)/g, ''); }; 66 | //_____________________________________________________________________________ 67 | 68 | window.escape = window.escape || function(s) 69 | { 70 | return s.replace(/[^\w@\*\-\+\.\/]/g, function(c) 71 | { 72 | c = '000' + c.charCodeAt(0).toString(16).toUpperCase(); return (c.length < 6 ? '%'+c.slice(-2) : '%u'+c.slice(-4)); 73 | }); 74 | };//___________________________________________________________________________ 75 | 76 | window.unescape = window.unescape || function(s) 77 | { 78 | return s.replace(/%u([\da-f]{4})|%([\da-f]{2})/gi, function(m,l,s){ return String.fromCharCode(parseInt(l||s, 16)); }); 79 | };//___________________________________________________________________________ 80 | 81 | Math.log2 = Math.log2 || function(x){ return Math.log(x) * Math.LOG2E; }; 82 | Math.log10 = Math.log10 || function(x){ return Math.log(x) * Math.LOG10E; }; 83 | //_____________________________________________________________________________ 84 | 85 | js.get_cookie = function(name) 86 | { 87 | var arr = document.cookie.split(';'); 88 | 89 | for(var i = 0; i < arr.length; i++) 90 | { 91 | var c = arr[i], p = -1; while(c.charCodeAt(++p) < 33); 92 | 93 | if(c.indexOf(name+'=', p) == p) 94 | { 95 | return decodeURIComponent(c.substr(p + name.length + 1)); 96 | } 97 | } 98 | };//___________________________________________________________________________ 99 | 100 | js.set_cookie = function(name, val, days, path) // (name, "", -1) to delete a cookie 101 | { 102 | var enc = encodeURIComponent, v = enc(val); 103 | 104 | if(days) 105 | { 106 | var d = new Date(); d.setDate(d.getDate() + days); 107 | 108 | v += '; expires=' + d.toUTCString(); 109 | } 110 | 111 | if(path) v += '; path=' + path; 112 | 113 | document.cookie = enc(name) + '=' + v; // + '; Secure' 114 | };//___________________________________________________________________________ 115 | 116 | js.check_cookies = function() 117 | { 118 | var n = 'testcookie'; 119 | 120 | js.set_cookie(n,1); // this is here on purpose, because of Chrome 121 | 122 | if(navigator.cookieEnabled) 123 | { 124 | if(js.get_cookie(n)){ js.set_cookie(n, '', -1); return true; } 125 | } 126 | };//___________________________________________________________________________ 127 | 128 | js.debounce = function(fn, delay) // returns a function to add delay to fn; if called again sooner the delay is reset 129 | { 130 | return function() 131 | { 132 | clearTimeout(this.timer); 133 | 134 | var self = this, args = arguments; 135 | 136 | this.timer = setTimeout(function(){ fn.apply(self, args); }, delay); 137 | }; 138 | }; 139 | 140 | js.throttle = function(fn, delay, immediate) // returns a function to add delay to fn; if called again sooner the call is ignored 141 | { 142 | return function() 143 | { 144 | if(this.timer) return; 145 | 146 | var self = this, args = arguments; 147 | 148 | if(immediate) fn.apply(self, args); 149 | 150 | this.timer = setTimeout(function(){ self.timer = null; fn.apply(self, args); }, delay); 151 | }; 152 | };//___________________________________________________________________________ 153 | -------------------------------------------------------------------------------- /js/jslib/jslib.min.js: -------------------------------------------------------------------------------- 1 | function defined(t){return void 0!==t&&null!==t}var js={};js.$=function(t){return document.getElementById(t)},js.is_array=function(t){return t&&t.constructor===Array},js.cb=function(t,n){return function(){return n.apply(t,arguments)}},js.count=function(t){var n=0;if(defined(t.length))return t.length;for(var e in t)t.hasOwnProperty(e)&&n++;return n},js.clone=function(t){if(null===t||"object"!=typeof t)return t;for(var n=arguments,e=new t.constructor,o=0;o object 12 | { 13 | var obj = {}; 14 | 15 | for(var i = 0; i < arr.length; i++){ obj[keys[i]] = arr[i]; } 16 | 17 | return obj; 18 | };//___________________________________________________________________________ 19 | 20 | // Generate all prime numbers < limit. 21 | 22 | js.gen_primes = function(limit) // limit must fit into a 32-bit integer 23 | { 24 | var i, inc = 4, p = [2,3], L = limit >> 1; // we only need half of the array, since we don't need to check even numbers 25 | 26 | var bits = new Uint8Array(L); 27 | 28 | for(i = 0; i < L; i ++) bits[i] = 1; // this can be replaced by fill() if you don't care about old browsers 29 | 30 | for(i = 5; i < limit; i += inc) 31 | { 32 | if(bits[i>>1]) 33 | { 34 | p.push(i); for(var j = i * i; j < limit; j += i){ if(j&1) bits[j>>1] = 0; } 35 | } 36 | 37 | inc = 6 - inc; // 2 and 3 produce {2, 4, 2, 4, ...} iteration pattern 38 | } 39 | 40 | return p; 41 | };//___________________________________________________________________________ 42 | -------------------------------------------------------------------------------- /js/jslib/src/main.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | var js = {}; // it all starts with a small first step 6 | 7 | function defined(a){ return (a !== void 0 && a !== null); } 8 | 9 | js.$ = function(id){ return document.getElementById(id); }; 10 | 11 | js.is_array = function(obj){ return (obj && obj.constructor === Array); }; 12 | 13 | js.cb = function(obj, fn){ return function(){ return fn.apply(obj, arguments); }; }; // bind 'this' and function together 14 | //_____________________________________________________________________________ 15 | 16 | js.count = function(obj) // returns the number of elements in both arrays and objects 17 | { 18 | var cnt = 0; if(defined(obj.length)) return obj.length; 19 | 20 | for(var p in obj){ if(obj.hasOwnProperty(p)) cnt++; } 21 | 22 | return cnt; 23 | };//___________________________________________________________________________ 24 | 25 | // neat way to convert a string into array: js.clone([], 'test') 26 | 27 | js.clone = function(obj) // any additional arguments will be added to the clone 28 | { 29 | if(obj === null || typeof(obj) !== 'object') return obj; 30 | 31 | var a = arguments, c = new obj.constructor(); 32 | 33 | for(var i = 0; i < a.length; i++) 34 | { 35 | for(var k in a[i]) 36 | { 37 | if(a[i].hasOwnProperty(k)) c[k] = js.clone(a[i][k]); 38 | } 39 | } 40 | 41 | return c; 42 | };//___________________________________________________________________________ 43 | 44 | js.encode_utf8 = function(s){ return unescape(encodeURIComponent(s)); }; // JS str => utf-8 45 | js.decode_utf8 = function(s){ return decodeURIComponent(escape (s)); }; // utf-8 => JS str 46 | //_____________________________________________________________________________ 47 | 48 | js.round = function(n, precision, down) // fixes nasty JS rounding and behaves like PHP round() 49 | { 50 | var neg = (n < 0), factor = Math.pow(10, precision); 51 | 52 | var t = Math.abs(n) * factor; 53 | 54 | t = (down ? Math.floor(t) : Math.round(t)); 55 | 56 | return (neg ? -t : t) / factor; 57 | };//___________________________________________________________________________ 58 | 59 | js.round_sig = function(n, digits) // round to a certain number of significant digits 60 | { 61 | return js.round(n, digits - Math.floor(Math.log10(Math.abs(n))) - 1); 62 | };//___________________________________________________________________________ 63 | 64 | -------------------------------------------------------------------------------- /js/jslib/src/merge.bat: -------------------------------------------------------------------------------- 1 | cls 2 | 3 | @rem main should always be included 4 | type "main.js" > ..\jslib.js 5 | 6 | type "polyfill.js" >> ..\jslib.js 7 | 8 | type "cookies.js" >> ..\jslib.js 9 | type "debounce.js" >> ..\jslib.js 10 | 11 | rem type "extra.js" >> ..\jslib.js 12 | -------------------------------------------------------------------------------- /js/jslib/src/polyfill.js: -------------------------------------------------------------------------------- 1 | 2 | String.prototype.trim = String.prototype.trim || function(){ return this.replace(/(^\s+)|(\s+$)/g, ''); }; 3 | //_____________________________________________________________________________ 4 | 5 | window.escape = window.escape || function(s) 6 | { 7 | return s.replace(/[^\w@\*\-\+\.\/]/g, function(c) 8 | { 9 | c = '000' + c.charCodeAt(0).toString(16).toUpperCase(); return (c.length < 6 ? '%'+c.slice(-2) : '%u'+c.slice(-4)); 10 | }); 11 | };//___________________________________________________________________________ 12 | 13 | window.unescape = window.unescape || function(s) 14 | { 15 | return s.replace(/%u([\da-f]{4})|%([\da-f]{2})/gi, function(m,l,s){ return String.fromCharCode(parseInt(l||s, 16)); }); 16 | };//___________________________________________________________________________ 17 | 18 | Math.log2 = Math.log2 || function(x){ return Math.log(x) * Math.LOG2E; }; 19 | Math.log10 = Math.log10 || function(x){ return Math.log(x) * Math.LOG10E; }; 20 | //_____________________________________________________________________________ 21 | -------------------------------------------------------------------------------- /js/vue/vs-crumbs/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Very simple Vue breadcrumbs in 40 lines of code 3 | 4 | Works with multi-level paths without the need for child views. For example: "/foo/bar" and "/foo/boo" or even "/foo/:id" can all be used at the same level with a single router-view. Supports child views too. 5 | 6 | Requires: [vue-router](https://github.com/vuejs/vue-router). 7 | 8 | ## Live Demo 9 | 10 | https://nxtchg.github.io/pieces/vue/vs-crumbs/#/foo/bar 11 | 12 | ## Props 13 | 14 | * **root** - name of the root element, default is 'home' 15 | 16 | ## Usage 17 | 18 | Simply add 'vs-crumbs.js' file into your project and insert one or more tags anywhere: 19 | 20 | ```html 21 | 22 | ``` 23 | 24 | Then style your separator: 25 | ```css 26 | .vs-crumbs a:after{ padding: 0 12px; color: #888; content: "/"; } 27 | ``` 28 | 29 | By default, the component uses router path to display breadcrumb names. 30 | 31 | You can override this with custom names by using **meta.crumbs**: 32 | 33 | ```js 34 | { path: '/foo/bar', component: FooBar, meta: { crumbs: '/My Foo/My Bar'} } 35 | ``` 36 | 37 | This component also sets page title to "home : foo : bar". 38 | 39 | See the "test/index.html" file for more examples of how to use it. 40 | -------------------------------------------------------------------------------- /js/vue/vs-crumbs/example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NxtChg/pieces/3eb39c8287a97632e9347a24f333d52d916bc816/js/vue/vs-crumbs/example.jpg -------------------------------------------------------------------------------- /js/vue/vs-crumbs/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vs-crumbs test 6 | 17 | 18 | 19 |
20 |

Breadcrumbs

21 | Simple:

22 | Arrows:
23 | 24 |

View

25 |
26 | 27 |
28 | 29 |

Navigation: 30 | Home | 31 | Users | 32 | User | 33 | Foo | 34 | Bar | 35 | Boo | 36 | 404 | 37 | About 38 |
39 | 40 | 41 | 42 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /js/vue/vs-crumbs/vs-crumbs.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | Vue.component('vs-crumbs', 6 | { 7 | template: 8 | '
    ' + 9 | '
  • ' + 10 | '{{ crumb.name }}' + 11 | '{{ crumb.name }}' + 12 | '
', 13 | 14 | props: { root: String }, 15 | 16 | computed: 17 | { 18 | crumbs: function() 19 | { 20 | var path = '', title = (this.root || 'home'); 21 | 22 | var cs = [ { name: title, path: '/'} ]; if(!this.$route) return []; 23 | 24 | var r = (this.$route.path ).split('/'); 25 | var m = (this.$route.matched[0].meta.crumbs || '').split('/'); 26 | 27 | for(var i = 1; i < r.length; i++) 28 | { 29 | var name = (m[i] || r[i]); if(r[i] == '') continue; 30 | 31 | title += ' : '+ name; 32 | path += '/' + name; 33 | 34 | cs.push({ name: name, path: path }); 35 | } 36 | 37 | window.document.title = title; 38 | 39 | return cs; 40 | } 41 | } 42 | }); -------------------------------------------------------------------------------- /js/vue/vs-notify/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Tiny but powerful notification component 3 | 4 | ## Live Demo 5 | 6 | https://nxtchg.github.io/pieces/vue/vs-notify/ 7 | 8 | ## Usage 9 | 10 | Simply add "vs-notify.min.js" file into your project and insert one or more tags anywhere: 11 | 12 | ```html 13 | 14 | ``` 15 | 16 | Then you can send notifications from Javascript: 17 | 18 | ```js 19 | this.$notify("alert", "Hello, world!"); 20 | this.$notify("alert", "Ice caps are melting.", "warn"); 21 | ``` 22 | 23 | You can also pass duration like this: 24 | 25 | ```js 26 | this.$notify("alert", "No more ice cream!", "error", 0); 27 | ``` 28 | 29 | To close all notifications in a group: `this.$notify("alert");`. 30 | 31 | See 'test/index.html' for more examples. 32 | 33 | ## Props 34 | 35 | * **group** - name to send notifications to 36 | * **position** - 'top/bottom' and 'left/right/center', for example: 'bottom left' 37 | * **duration** - number of milliseconds to show the notification (0 = until user closes it) 38 | * **reverse** - display notifications in reverse order 39 | * **transition** - Vue transition name to use 40 | 41 | There are several predefined transitions: 42 | 43 | * **ntf-left** - slide notification from the left (default for 'left' position) 44 | * **ntf-right** - slide notification from the right (default for 'right' position) 45 | * **ntf-fade** - simply fade-in/fade-out notifications 46 | * **ntf-top** - slide from the top 47 | * **ntf-bottom** - slide from the bottom 48 | 49 | ## Custom notifications 50 | 51 | You can use the slot "body" for custom notifications: 52 | 53 | ```html 54 | 57 | ``` 58 | 59 | `props.close()` closes the notification. 60 | 61 | ## Styling 62 | 63 | ```css 64 | .vs-notify .ntf{ /* main notification container */ } 65 | 66 | .vs-notify .ntf.success { } 67 | .vs-notify .ntf.warn { } 68 | .vs-notify .ntf.error { } 69 | ``` 70 | 71 | You can also use your own notification types: 72 | 73 | `this.$notify("alert", "Where are my keys?!", "panic");` 74 | 75 | `.vs-notify .panic{ color: red; }` 76 | -------------------------------------------------------------------------------- /js/vue/vs-notify/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vs-notify test 6 | 67 | 68 | 69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 84 | 85 | 86 |
87 | 88 | 89 |
90 | 91 |


92 | 93 | 94 |
95 |
96 | 97 |
98 |
99 | 100 |
101 | 102 | 103 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /js/vue/vs-notify/vs-notify.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | var s = document.createElement("style"); s.type = 'text/css'; 6 | 7 | document.getElementsByTagName('head')[0].appendChild(s); 8 | 9 | s.innerHTML = 10 | '.vs-notify{ position:fixed; width:300px; z-index:9999; }'+ 11 | '.vs-notify .ntf{ font-size:14px; padding:10px; margin:0 5px 5px; color:#fff; background:#44A4FC; border-left:5px solid #187FE7; box-sizing:border-box; text-align:left; cursor:pointer; }'+ 12 | '.vs-notify .warn { background:#ffb648; border-left-color:#f48a06; }'+ 13 | '.vs-notify .error { background:#E54D42; border-left-color:#B82E24; }'+ 14 | '.vs-notify .success{ background:#68CD86; border-left-color:#42A85F; }'+ 15 | 16 | '.ntf-left-enter-active, .ntf-left-leave-active, .ntf-right-enter-active, .ntf-right-leave-active, .ntf-top-enter-active, .ntf-top-leave-active,'+ 17 | '.ntf-bottom-enter-active, .ntf-bottom-leave-active{ transition: all 0.3s; }'+ 18 | '.ntf-left-enter, .ntf-left-leave-to { opacity:0; transform:translateX(-300px); }'+ 19 | '.ntf-right-enter, .ntf-right-leave-to{ opacity:0; transform:translateX(300px); }'+ 20 | '.ntf-fade-enter-active, .ntf-fade-leave-active{ transition: opacity 0.5s; }'+ 21 | '.ntf-fade-enter, .ntf-fade-leave-to{ opacity: 0; }'+ 22 | '.ntf-top-enter, .ntf-top-leave-to{ opacity:0; transform: translateY(-120px); }'+ 23 | '.ntf-bottom-enter, .ntf-bottom-leave-to{ opacity:0; transform: translateY(120px); }'; 24 | //_____________________________________________________________________________ 25 | 26 | var VsNotify = 27 | { 28 | install: function(Vue) 29 | { 30 | var self = this; this.g = {}; 31 | 32 | var $notify = function(group, text, type, time){ if(self.g[group]) self.g[group](text, type, time); }; 33 | 34 | Object.defineProperty(Vue.prototype, '$notify', { get: function(){ return $notify; } }); 35 | } 36 | }; 37 | 38 | Vue.use(VsNotify); 39 | 40 | Vue.component('vs-notify', 41 | { 42 | template: 43 | '
'+ 44 | '
'+ 45 | ''+ 46 | '
'+ 47 | '
'+ 48 | '
'+ 49 | '
', 50 | 51 | props: 52 | { 53 | group: String, transition: String, 54 | position: { type: String, default: 'top right' }, 55 | duration: { type: Number, default: 3000 }, 56 | reverse: { type: Boolean, default: false } 57 | }, 58 | 59 | data: function() 60 | { 61 | var d = !this.reverse, p = this.position, t = this.transition; 62 | 63 | if(p.indexOf('bottom')+1) d = !d; 64 | 65 | if(!t && p.indexOf('left' )+1) t = 'ntf-left'; 66 | if(!t && p.indexOf('right')+1) t = 'ntf-right'; 67 | 68 | return{ dir:d, trans: t, list:[] } 69 | }, 70 | 71 | created: function() 72 | { 73 | var ids = 1, self = this; 74 | 75 | VsNotify.g[this.group] = function(text, type, time) 76 | { 77 | if(text === undefined){ self.end(); return; } 78 | 79 | var it = { id: ids++, text: text, type: 'ntf' + (type ? ' '+type : '') }; 80 | 81 | time = (time !== undefined ? time : self.duration); 82 | 83 | if(time > 0){ it.timer = setTimeout(function(){ self.end(it); }, time); } 84 | 85 | self.dir ? self.list.push(it) : self.list.unshift(it); 86 | }; 87 | }, 88 | 89 | //destroyed: function(){ }, // do we need it? if so - remove group from VsNotify 90 | 91 | computed: 92 | { 93 | styles: function() 94 | { 95 | var s = {}, pa = this.position.split(' '); 96 | 97 | for(var i = 0; i < pa.length; i++) 98 | { 99 | if(pa[i] == 'center'){ s.left = s.right = 0; s.margin = 'auto'; } else if(pa[i] != '') s[pa[i]] = 0; 100 | } 101 | 102 | return s; 103 | } 104 | }, 105 | 106 | methods: 107 | { 108 | find: function(id){ for(var i = 0; i < this.list.length; i++) if(this.list[i].id == id) return i; return -1; }, 109 | 110 | end_no: function(n){ if(n+1){ clearTimeout(this.list[n].timer); this.list.splice(n, 1); } }, 111 | 112 | end: function(it) 113 | { 114 | if(it === undefined){ while(this.list.length) this.end_no(0); return; } // kill all 115 | 116 | this.end_no(this.find(it.id)); 117 | } 118 | } 119 | }); 120 | -------------------------------------------------------------------------------- /js/vue/vs-notify/vs-notify.min.js: -------------------------------------------------------------------------------- 1 | var s=document.createElement("style");s.type="text/css",document.getElementsByTagName("head")[0].appendChild(s),s.innerHTML=".vs-notify{ position:fixed; width:300px; z-index:9999; }.vs-notify .ntf{ font-size:14px; padding:10px; margin:0 5px 5px; color:#fff; background:#44A4FC; border-left:5px solid #187FE7; box-sizing:border-box; text-align:left; cursor:pointer; }.vs-notify .warn { background:#ffb648; border-left-color:#f48a06; }.vs-notify .error { background:#E54D42; border-left-color:#B82E24; }.vs-notify .success{ background:#68CD86; border-left-color:#42A85F; }.ntf-left-enter-active, .ntf-left-leave-active, .ntf-right-enter-active, .ntf-right-leave-active, .ntf-top-enter-active, .ntf-top-leave-active,.ntf-bottom-enter-active, .ntf-bottom-leave-active{ transition: all 0.3s; }.ntf-left-enter, .ntf-left-leave-to { opacity:0; transform:translateX(-300px); }.ntf-right-enter, .ntf-right-leave-to{ opacity:0; transform:translateX(300px); }.ntf-fade-enter-active, .ntf-fade-leave-active{ transition: opacity 0.5s; }.ntf-fade-enter, .ntf-fade-leave-to{ opacity: 0; }.ntf-top-enter, .ntf-top-leave-to{ opacity:0; transform: translateY(-120px); }.ntf-bottom-enter, .ntf-bottom-leave-to{ opacity:0; transform: translateY(120px); }";var VsNotify={install:function(t){var e=this;this.g={};var i=function(t,i,n,o){e.g[t]&&e.g[t](i,n,o)};Object.defineProperty(t.prototype,"$notify",{get:function(){return i}})}};Vue.use(VsNotify),Vue.component("vs-notify",{template:'
',props:{group:String,transition:String,position:{type:String,default:"top right"},duration:{type:Number,default:3e3},reverse:{type:Boolean,default:!1}},data:function(){var t=!this.reverse,e=this.position,i=this.transition;return e.indexOf("bottom")+1&&(t=!t),!i&&e.indexOf("left")+1&&(i="ntf-left"),!i&&e.indexOf("right")+1&&(i="ntf-right"),{dir:t,trans:i,list:[]}},created:function(){var t=1,e=this;VsNotify.g[this.group]=function(i,n,o){if(void 0===i)return void e.end();var r={id:t++,text:i,type:"ntf"+(n?" "+n:"")};o=void 0!==o?o:e.duration,o>0&&(r.timer=setTimeout(function(){e.end(r)},o)),e.dir?e.list.push(r):e.list.unshift(r)}},computed:{styles:function(){for(var t={},e=this.position.split(" "),i=0;iHello,

world!

', 18 | 19 | style: 'span, .this-too{ font-color: red }' 20 | }); 21 | ``` 22 | 23 | will add ```.my-component span, .my-component .this-too{ font-color: red }``` to the page. 24 | 25 | This means that the root element of your component must have the same class as its name. 26 | 27 | ## Usage 28 | 29 | Simply add 'vue-css.js' file to your page. 30 | 31 | If you want to override component styles, add `````` to the page header. 32 | 33 | The plugin will put all the component styles there and you can then add styles above or below to either inherit or override them. 34 | 35 | NOTE: Selectors inside nested at-rules, like @media, are not processed, so you need to prefix them with your root class manually. 36 | -------------------------------------------------------------------------------- /js/vue/vue-css/vue-css.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | var VueCSS = 6 | { 7 | install: function(vue, options) 8 | { 9 | var org_component_func = vue.component; 10 | 11 | vue.component = function(id, def) 12 | { 13 | if(def.style) 14 | { 15 | var css = def.style.replace(/<\/?style>/gi, ''); 16 | 17 | var rule = '', pos = 0, level = 0, prefix = '.' + id; 18 | 19 | function fail(msg){ throw 'vue-css parsing error: ' + msg + ' at "' + css.slice(pos, pos+60) + '"...'; } 20 | 21 | var s = document.getElementById('vue-styles'); 22 | 23 | if(!s){ s = document.createElement('style'); s.type = 'text/css'; s.id = 'vue-styles'; document.getElementsByTagName('head')[0].appendChild(s); } 24 | 25 | function read_until(delims) 26 | { 27 | var org = pos, c; 28 | 29 | while(c = css[pos++]) 30 | { 31 | if(c == '\'' || c == '"') 32 | { 33 | var p = css.indexOf(c, pos); if(p != -1) pos = p+1; else fail("unterminated string"); 34 | 35 | continue; 36 | } 37 | 38 | if(level == 0 && delims.indexOf(c) != -1) break; 39 | 40 | if(c == '{'){ level++; } 41 | if(c == '}'){ level--; if(level < 0) fail("extra }"); } 42 | } 43 | 44 | return css.slice(org, pos-1); 45 | } 46 | 47 | function add_sel(s) 48 | { 49 | s = s.replace(/^\s+|\s+$/g, ''); 50 | 51 | if(s == '' || s[0] == '@' || rule[0] == '@' || s.indexOf(prefix) == 0){ rule += s; } else { rule += prefix + ' ' + s; } 52 | } 53 | 54 | while(pos < css.length) 55 | { 56 | var n = read_until(',;{'); add_sel(n + (css[pos-1] || '')); 57 | 58 | switch(css[pos-1]) 59 | { 60 | //case ';': break; 61 | case ',': continue; 62 | case '{': rule += read_until('}')+'}'; break; 63 | } 64 | 65 | if(rule != ''){ console.log(s.sheet.insertRule(rule, s.sheet.cssRules.length), rule); rule = ''; } 66 | } 67 | } 68 | 69 | org_component_func.call(vue, id, def); 70 | } 71 | } 72 | };//___________________________________________________________________________ 73 | 74 | if(window.Vue) window.Vue.use(VueCSS); 75 | //_____________________________________________________________________________ 76 | -------------------------------------------------------------------------------- /js/vue/vue-css/vue-css.min.js: -------------------------------------------------------------------------------- 1 | var VueCSS={install:function(e,t){var n=e.component;e.component=function(t,s){function i(e){throw"vue-css parsing error: "+e+' at "'+c.slice(a,a+60)+'"...'}function l(e){for(var t,n=a;t=c[a++];)if("'"!=t&&'"'!=t){if(0==o&&-1!=e.indexOf(t))break;"{"==t&&o++,"}"==t&&--o<0&&i("extra }")}else{var s=c.indexOf(t,a);-1!=s?a=s+1:i("unterminated string")}return c.slice(n,a-1)}if(s.style){var c=s.style.replace(/<\/?style>/gi,""),r="",a=0,o=0,u="."+t,d=document.getElementById("vue-styles");for(d||(d=document.createElement("style"),d.type="text/css",d.id="vue-styles",document.getElementsByTagName("head")[0].appendChild(d));a 0 && < 100) the button will disable itself, and display progress bar and the spinning circle. 18 | * **autoProgress** - Number, if > 0 the button will display fake automatic progress (similar to [vue-top-progress-bar](https://github.com/dalphyx/vue-top-progress)). 19 | 20 | **autoProgress** determines the time in milliseconds to reach 100%. You should set it to your typical response time. 21 | Default is 3000 ms. 22 | 23 | The progress bar will never reach 100%, however, and will be stuck at 95% until you set it manually to either 0 or 100, in which case the button will return to its normal state. 24 | 25 | If **autoProgress** is set to 0, you should provide the progress values yourself via the **progress** prop. 26 | 27 | If you don't want the progress bar to be displayed, set the **progress** to 0.1 and don't update it until finished (then set it to 0). 28 | 29 | The automatic progression is logarithmic; this means the progress bar will move slower and slower as it goes higher. 30 | 31 | ## Usage 32 | 33 | Simply add "vue-submit.min.js" file into your project. 34 | 35 | ```html 36 | Send 37 | ``` 38 | 39 | (NOTE: The component adds "@keyframes spin" rule into your page CSS). 40 | 41 | See the "test/index.html" file for more examples of how to use it. 42 | -------------------------------------------------------------------------------- /js/vue/vue-submit/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-submit test 6 | 7 | 10 | 11 | 12 |
13 | Click the buttons: 14 |
15 |
16 | Button 1 17 | Button 2 18 | Button 3 19 | Button 4

20 | Submit Form 21 |
22 |
23 |
24 | 25 | 26 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /js/vue/vue-submit/vue-submit-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NxtChg/pieces/3eb39c8287a97632e9347a24f333d52d916bc816/js/vue/vue-submit/vue-submit-example.png -------------------------------------------------------------------------------- /js/vue/vue-submit/vue-submit.js: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Created by NxtChg (admin@nxtchg.com), 2017. License: Public Domain. 3 | =============================================================================*/ 4 | 5 | Math.log10 = Math.log10 || function(x){ return Math.log(x) * Math.LOG10E; }; 6 | //_____________________________________________________________________________ 7 | 8 | var s = document.createElement("style"); s.type = 'text/css'; // add spinner keyframes 9 | 10 | document.getElementsByTagName('head')[0].appendChild(s); 11 | 12 | s.sheet.insertRule('@keyframes spin { 100% { transform: rotate(360deg); } }', 0); 13 | //_____________________________________________________________________________ 14 | 15 | Vue.component('vue-submit', 16 | { 17 | template: 18 | '', 23 | 24 | props:{ progress: Number, autoProgress: Number, disabled: Boolean }, 25 | 26 | data: function() 27 | { 28 | return{ at: 0, t: 0, 29 | dt: (typeof(this.autoProgress) != 'undefined' ? this.autoProgress : 3000), 30 | enabled: (typeof(this.disabled ) == 'undefined' || this.disabled != true) 31 | }; 32 | }, 33 | 34 | watch: 35 | { 36 | disabled: function(v){ this.enabled = !v; }, 37 | 38 | progress: function(v) 39 | { 40 | if(!this.enabled && v) return; 41 | 42 | var prev = this.in_progress; this.at = v; 43 | 44 | if(this.dt > 0) 45 | { 46 | if(!prev && this.in_progress){ this.at = 1; this.t = 0; this.tick(); } // start auto progress 47 | if( prev && !this.in_progress){ this.at = 0; } // stop 48 | } 49 | } 50 | }, 51 | 52 | computed: 53 | { 54 | in_progress: function(){ return (this.at > 0 && this.at < 100); }, 55 | 56 | locked: function(){ return (!this.enabled || this.in_progress); }, 57 | 58 | bar_style: function() 59 | { 60 | return{ position: 'absolute', top: 0, left: 0, bottom: 0, backgroundColor: '#fff', transition: 'width 200ms linear', opacity: '0.4', 61 | width: this.at + '%', height: '100%', zIndex: 3 62 | }; 63 | }, 64 | 65 | spn_style: function() 66 | { 67 | return{ position: 'relative', border: '3.5px solid rgba(255,255,255,0.5)', borderRightColor: '#fff', borderRadius: '50%', display: 'inline-block', 68 | width: '1.33em', height: '1.33em', zIndex: 2, marginLeft:'6px', verticalAlign: 'text-top', top: '-1px', 69 | animation: 'spin 0.75s linear', animationIterationCount: 'infinite', // background: 'url("loading.gif") center center no-repeat' 70 | }; 71 | } 72 | }, 73 | 74 | methods: 75 | { 76 | tick: function() 77 | { 78 | if(!this.enabled || !this.in_progress) return; 79 | 80 | this.at = Math.round(100 + Math.log10(0.1 + this.t / this.dt) * 100); 81 | 82 | if(this.at < 1) this.at = 1; 83 | if(this.at > 95) this.at = 95; 84 | 85 | this.t += 200; 86 | 87 | var self = this; setTimeout(function(){ self.tick(); }, 200); 88 | } 89 | } 90 | }); -------------------------------------------------------------------------------- /js/vue/vue-submit/vue-submit.min.js: -------------------------------------------------------------------------------- 1 | Math.log10=Math.log10||function(t){return Math.log(t)*Math.LOG10E};var s=document.createElement("style");s.type="text/css",document.getElementsByTagName("head")[0].appendChild(s),s.sheet.insertRule("@keyframes spin { 100% { transform: rotate(360deg); } }",0),Vue.component("vue-submit",{template:'',props:{progress:Number,autoProgress:Number,disabled:Boolean},data:function(){return{at:0,t:0,dt:void 0!==this.autoProgress?this.autoProgress:3e3,enabled:void 0===this.disabled||1!=this.disabled}},watch:{disabled:function(t){this.enabled=!t},progress:function(t){if(this.enabled||!t){var s=this.in_progress;this.at=t,this.dt>0&&(!s&&this.in_progress&&(this.at=1,this.t=0,this.tick()),s&&!this.in_progress&&(this.at=0))}}},computed:{in_progress:function(){return this.at>0&&this.at<100},locked:function(){return!this.enabled||this.in_progress},bar_style:function(){return{position:"absolute",top:0,left:0,bottom:0,backgroundColor:"#fff",transition:"width 200ms linear",opacity:"0.4",width:this.at+"%",height:"100%",zIndex:3}},spn_style:function(){return{position:"relative",border:"3.5px solid rgba(255,255,255,0.5)",borderRightColor:"#fff",borderRadius:"50%",display:"inline-block",width:"1.33em",height:"1.33em",zIndex:2,marginLeft:"6px",verticalAlign:"text-top",top:"-1px",animation:"spin 0.75s linear",animationIterationCount:"infinite"}}},methods:{tick:function(){if(this.enabled&&this.in_progress){this.at=Math.round(100+100*Math.log10(.1+this.t/this.dt)),this.at<1&&(this.at=1),this.at>95&&(this.at=95),this.t+=200;var t=this;setTimeout(function(){t.tick()},200)}}}}); -------------------------------------------------------------------------------- /php/bitcoin/api/README.md: -------------------------------------------------------------------------------- 1 | # Bitcoin RPC API interface 2 | 3 | Usage: 4 | 5 | ```php 6 | $api = new JsonAPI(); 7 | 8 | $balance = $api->get_balance('*', 1); if($balance === NULL){ die('Failed to fetch balance!'); } 9 | 10 | echo "$balance\n"; 11 | ``` 12 | -------------------------------------------------------------------------------- /php/bitcoin/api/json_api.php: -------------------------------------------------------------------------------- 1 | server = 'http://user:password@127.0.0.1:8332'; } 9 | 10 | function fetch($url, $post) 11 | { 12 | $ctx = @stream_context_create(['http' => ['method'=>'POST', 'header'=>'Content-type: application/json', 'content'=>$post, 'ignore_errors'=>true]]); 13 | 14 | $data = @file_get_contents($url, false, $ctx); 15 | 16 | if($data !== false) 17 | { 18 | $object = @json_decode($data, true); 19 | 20 | if($object !== NULL) return $object; 21 | } 22 | 23 | return false; 24 | }//____________________________________________________________________________ 25 | 26 | function __call($func, $args) 27 | { 28 | $args = array_values($args); 29 | 30 | $func = str_replace('_', '', strtolower($func)); 31 | 32 | $rqst = json_encode(['jsonrpc' => '2.0', 'id' => $this->id++, 'method' => $func, 'params' => $args]); 33 | 34 | $r = $this->fetch($this->server, $rqst); if($r === false) return NULL; 35 | 36 | if($r['error']) 37 | { 38 | $this->error = $r['error']['message']; return NULL; 39 | } 40 | else 41 | { 42 | $this->error = ''; return $r['result']; 43 | } 44 | } 45 | }; 46 | 47 | ?> -------------------------------------------------------------------------------- /php/bitcoin/cashaddr/README.md: -------------------------------------------------------------------------------- 1 | # CashAddr Translator 2 | 3 | Usage: 4 | 5 | ```php 6 | $pk = cashaddr2pk('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'); 7 | 8 | echo pk2adr($pk)."\n"; // 1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu 9 | 10 | echo pk2cashaddr($pk)."\n"; // bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /php/bitcoin/cashaddr/cashaddr.php: -------------------------------------------------------------------------------- 1 | > $b) & ~(1 << (8 * PHP_INT_SIZE-1) >> ($b-1)); 9 | }//____________________________________________________________________________ 10 | 11 | function poly_mod($v, $ret = false) // checksum magic 12 | { 13 | $a = 0; $b = 1; $c = 0; 14 | 15 | for($i = 0; $i < count($v); $i++) 16 | { 17 | $c = rshift($a, 3); 18 | $c = ($a >> 3); 19 | $a = (($a & 7) << 5) | rshift($b, 27); 20 | $b = (($b & 0x07ffffff) << 5) ^ $v[$i]; 21 | 22 | if($c == 0) continue; 23 | 24 | if($c & 1){ $a ^= 0x98; $b ^= 0xf2bc8e61; } 25 | if($c & 2){ $a ^= 0x79; $b ^= 0xb76d99e2; } 26 | if($c & 4){ $a ^= 0xf3; $b ^= 0x3e5fb3c4; } 27 | if($c & 8){ $a ^= 0xae; $b ^= 0x2eabe2a8; } 28 | if($c & 16){ $a ^= 0x1e; $b ^= 0x4f43e470; } 29 | } 30 | 31 | return ($ret ? [$a, $b^1] : ($a == 0 && ($b^1) == 0)); 32 | }//____________________________________________________________________________ 33 | 34 | function bits5to8($arr) // converts 5-bit words into bytes 35 | { 36 | $t = 0; $bits = 0; $out = []; 37 | 38 | for($i = 0; $i < count($arr); $i++) 39 | { 40 | $t <<= 5; $t |= $arr[$i]; $bits += 5; 41 | 42 | while($bits > 7){ $bits -= 8; $out[] = (($t >> $bits) & 0xFF); } 43 | } 44 | 45 | return $out; 46 | }//____________________________________________________________________________ 47 | 48 | function bits8to5($arr) // converts bytes into 5-bit words 49 | { 50 | $t = 0; $bits = 0; $out = []; 51 | 52 | for($i = 0; $i < count($arr); $i++) 53 | { 54 | $t <<= 8; $t |= $arr[$i]; $bits += 8; 55 | 56 | while($bits > 5){ $bits -= 5; $out[] = (($t >> $bits) & 31); } 57 | } 58 | 59 | if($bits) $out[] = (($t & ((1 << $bits) - 1)) << (5 - $bits)); 60 | 61 | return $out; 62 | }//____________________________________________________________________________ 63 | 64 | function base58_encode($bin) 65 | { 66 | $d = [0]; $alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; 67 | 68 | for($i = 0; $i < count($bin); $i++) 69 | { 70 | for($j = 0, $c = $bin[$i]; $j < count($d); $j++) 71 | { 72 | $c += $d[$j] << 8; $d[$j] = $c % 58; $c = ($c / 58) | 0; 73 | } 74 | 75 | while($c > 0){ $d[] = ($c % 58); $c = ($c / 58) | 0; } 76 | } 77 | 78 | $out = ''; 79 | 80 | for($i = 0; $i < count($bin) && $bin[$i] == 0; $i++) $out .= '1'; // leading zero bytes 81 | 82 | for($i = count($d) - 1; $i >= 0; $i--) $out .= $alphabet[$d[$i]]; // reverse 83 | 84 | return $out; 85 | }//____________________________________________________________________________ 86 | 87 | function SHAx2($arr) 88 | { 89 | $s = ''; foreach($arr as $v) $s.= chr($v); 90 | 91 | $hash = str_split(hash('sha256', hash('sha256', $s, true), true)); 92 | 93 | for($i = 0; $i < count($hash); $i++){ $hash[$i] = ord($hash[$i]); } 94 | 95 | return $hash; 96 | }//____________________________________________________________________________ 97 | 98 | function pk2adr($pk) 99 | { 100 | if($pk === false) return ''; 101 | 102 | $pk = array_merge([$pk[0] ? 0x05 : 0x00], array_slice($pk, 1)); 103 | 104 | $checksum = array_slice(SHAx2($pk), 0, 4); 105 | 106 | return base58_encode(array_merge($pk, $checksum)); 107 | }//____________________________________________________________________________ 108 | 109 | function cashaddr2pk($adr) // returns payload, including the version byte 110 | { 111 | $adr = strtolower(strval($adr)); 112 | 113 | //$idx = strpos(adr, 'bitcoincash:'); if($idx !== false) $adr = substr($adr, $idx+12); 114 | 115 | $idx = strpos($adr, ':'); if($idx !== false) $adr = substr($adr, $idx+1); // let's be more relaxed about the prefix... 116 | 117 | $adr = trim($adr); if($adr[0] != 'q' && $adr[0] != 'p') return false; 118 | 119 | $raw = []; $alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; 120 | 121 | for($i = 0; $i < strlen($adr); $i++) 122 | { 123 | $idx = strpos($alphabet, $adr[$i]); if($idx === false) continue; 124 | 125 | $raw[] = $idx; if(count($raw) > 112) return false; 126 | } 127 | 128 | if(count($raw) < 42) return false; 129 | 130 | $hash_sz = ($raw[1] >> 2); if($hash_sz != 0) return false; // only 160-bit hashes 131 | 132 | if(!poly_mod(array_merge([2, 9, 20, 3, 15, 9, 14, 3, 1, 19, 8, 0], $raw))) return false; // verify checksum 133 | 134 | $raw = array_slice($raw, 0, -8); // cut off checksum 135 | 136 | return bits5to8($raw); // convert into bytes 137 | }//____________________________________________________________________________ 138 | 139 | function pk2cashaddr($pk) // needs version byte + payload 140 | { 141 | $raw = bits8to5($pk); // convert into 5-bit words 142 | 143 | $mod = poly_mod(array_merge([2, 9, 20, 3, 15, 9, 14, 3, 1, 19, 8, 0], $raw, [0,0,0,0,0,0,0,0]), true); 144 | 145 | $a = $mod[0]; $b = $mod[1]; $checksum = [0,0,0,0,0,0,0,0]; 146 | 147 | for($i = 7; $i >= 0; $i--) // convert 5-bit groups in mod to checksum values 148 | { 149 | $checksum[$i] = ($b & 31); $b = rshift($b, 5); $b |= ($a & 31) << 27; $a = rshift($a, 5); // (mod >> uint(5*(7-i))) & 0x1f 150 | } 151 | 152 | $raw = array_merge($raw, $checksum); 153 | 154 | if(!poly_mod(array_merge([2, 9, 20, 3, 15, 9, 14, 3, 1, 19, 8, 0], $raw))) return false; // verify checksum 155 | 156 | $out = 'bitcoincash:'; $alphabet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; 157 | 158 | for($i = 0; $i < count($raw); $i++){ $out .= $alphabet[$raw[$i] & 31]; } 159 | 160 | return $out; 161 | } 162 | ?> -------------------------------------------------------------------------------- /php/bitcoin/cashaddr/test.php: -------------------------------------------------------------------------------- 1 | '); 22 | 23 | $match = ($adr == $dst ? 'match' : 'WRONG!'); 24 | 25 | $ca = pk2cashaddr($pk); 26 | 27 | echo "\n* $src => $adr ($match) => $ca"; 28 | } 29 | 30 | ?> -------------------------------------------------------------------------------- /php/bitcoin/validate/README.md: -------------------------------------------------------------------------------- 1 | # Bitcoin address validation 2 | 3 | Usage: 4 | 5 | ```php 6 | if(btc_validate('1Jgt77gGxYBTv1vfJAxeFUpiR6rhz7UeDb')){ } // OK 7 | ``` 8 | 9 | Requires BC Math. 10 | -------------------------------------------------------------------------------- /php/bitcoin/validate/test.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /php/bitcoin/validate/validate.php: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------