├── .bowerrc
├── .gitignore
├── .jshintrc
├── .npmignore
├── Gruntfile.js
├── README.md
├── bitcore-node-zcash
├── index.js
└── service.js
├── bower.json
├── package.json
├── po
├── de_DE.po
├── es.po
└── ja.po
└── public
├── css
└── main.min.css
├── fonts
├── glyphicons-halflings-regular.eot
├── glyphicons-halflings-regular.svg
├── glyphicons-halflings-regular.ttf
└── glyphicons-halflings-regular.woff
├── img
├── .gitignore
├── angularjs.png
├── icons
│ ├── copy.png
│ └── favicon.ico
├── leveldb.png
├── loading.gif
├── logo.svg
└── nodejs.png
├── index.html
├── js
├── angularjs-all.min.js
├── main.min.js
└── vendors.min.js
├── lib
└── zeroclipboard
│ └── ZeroClipboard.swf
├── robots.txt
├── sound
└── transaction.mp3
├── src
├── css
│ └── common.css
└── js
│ ├── app.js
│ ├── config.js
│ ├── controllers
│ ├── address.js
│ ├── blocks.js
│ ├── charts.js
│ ├── connection.js
│ ├── currency.js
│ ├── footer.js
│ ├── header.js
│ ├── index.js
│ ├── messages.js
│ ├── scanner.js
│ ├── search.js
│ ├── status.js
│ └── transactions.js
│ ├── directives.js
│ ├── filters.js
│ ├── init.js
│ ├── ios-imagefile-megapixel
│ └── megapix-image.js
│ ├── jsqrcode
│ ├── alignpat.js
│ ├── bitmat.js
│ ├── bmparser.js
│ ├── datablock.js
│ ├── databr.js
│ ├── datamask.js
│ ├── decoder.js
│ ├── detector.js
│ ├── errorlevel.js
│ ├── findpat.js
│ ├── formatinf.js
│ ├── gf256.js
│ ├── gf256poly.js
│ ├── grid.js
│ ├── qrcode.js
│ ├── rsdecoder.js
│ ├── test.html
│ └── version.js
│ ├── services
│ ├── address.js
│ ├── blocks.js
│ ├── charts.js
│ ├── currency.js
│ ├── global.js
│ ├── socket.js
│ ├── status.js
│ └── transactions.js
│ └── translations.js
└── views
├── 404.html
├── address.html
├── block.html
├── block_list.html
├── charts.html
├── dummy-translations.html
├── includes
├── connection.html
├── currency.html
├── header.html
├── infoStatus.html
└── search.html
├── index.html
├── messages_verify.html
├── redirect.html
├── status.html
├── transaction.html
├── transaction
├── list.html
└── tx.html
└── transaction_sendraw.html
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "public/lib"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # from https://github.com/github/gitignore/blob/master/Node.gitignore
2 | lib-cov
3 | *.seed
4 | *.log
5 | *.csv
6 | *.dat
7 | *.out
8 | *.pid
9 | *.gz
10 | *.swp
11 | tags
12 | pids
13 | logs
14 | results
15 | build
16 |
17 | node_modules
18 |
19 | # extras
20 | *.swp
21 | *.swo
22 | *~
23 | .project
24 | peerdb.json
25 |
26 | npm-debug.log
27 | .nodemonignore
28 |
29 | .DS_Store
30 | public/lib/*
31 | !public/lib/zeroclipboard/ZeroClipboard.swf
32 | db/txs/*
33 | db/txs
34 | db/testnet/txs/*
35 | db/testnet/txs
36 | db/blocks/*
37 | db/blocks
38 | db/testnet/blocks/*
39 | db/testnet/blocks
40 |
41 | public/js/angularjs-all.js
42 | public/js/main.js
43 | public/js/vendors.js
44 |
45 | public/css/main.css
46 |
47 | README.html
48 | po/*
49 | !po/*.po
50 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment.
3 | "browser": true, // Standard browser globals e.g. `window`, `document`.
4 | "esnext": true, // Allow ES.next specific features such as `const` and `let`.
5 | "bitwise": false, // Prohibit bitwise operators (&, |, ^, etc.).
6 | "camelcase": false, // Permit only camelcase for `var` and `object indexes`.
7 | "curly": false, // Require {} for every new block or scope.
8 | "eqeqeq": true, // Require triple equals i.e. `===`.
9 | "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
10 | "latedef": true, // Prohibit variable use before definition.
11 | "newcap": true, // Require capitalization of all constructor functions e.g. `new F()`.
12 | "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`.
13 | "quotmark": "single", // Define quotes to string values.
14 | "regexp": true, // Prohibit `.` and `[^...]` in regular expressions.
15 | "undef": true, // Require all non-global variables be declared before they are used.
16 | "unused": true, // Warn unused variables.
17 | "strict": true, // Require `use strict` pragma in every file.
18 | "trailing": true, // Prohibit trailing whitespaces.
19 | "smarttabs": false, // Suppresses warnings about mixed tabs and spaces
20 | "globals": { // Globals variables.
21 | "angular": true
22 | },
23 | "predef": [ // Extra globals.
24 | "define",
25 | "require",
26 | "exports",
27 | "module",
28 | "describe",
29 | "before",
30 | "beforeEach",
31 | "after",
32 | "afterEach",
33 | "it",
34 | "inject",
35 | "$",
36 | "io",
37 | "app",
38 | "moment"
39 | ],
40 | "indent": false, // Specify indentation spacing
41 | "devel": true, // Allow development statements e.g. `console.log();`.
42 | "noempty": true // Prohibit use of empty blocks.
43 | }
44 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | lib-cov
2 | *.seed
3 | *.log
4 | *.csv
5 | *.dat
6 | *.out
7 | *.pid
8 | *.gz
9 | *.swp
10 | tags
11 | pids
12 | logs
13 | results
14 | build
15 |
16 | node_modules
17 |
18 | # extras
19 | *.swp
20 | *.swo
21 | *~
22 | .project
23 | peerdb.json
24 |
25 | npm-debug.log
26 | .nodemonignore
27 |
28 | .DS_Store
29 | db/txs/*
30 | db/txs
31 | db/testnet/txs/*
32 | db/testnet/txs
33 | db/blocks/*
34 | db/blocks
35 | db/testnet/blocks/*
36 | db/testnet/blocks
37 |
38 | README.html
39 | k*
40 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 |
5 | //Load NPM tasks
6 | grunt.loadNpmTasks('grunt-contrib-uglify');
7 | grunt.loadNpmTasks('grunt-contrib-concat');
8 | grunt.loadNpmTasks('grunt-contrib-watch');
9 | grunt.loadNpmTasks('grunt-css');
10 | grunt.loadNpmTasks('grunt-markdown');
11 | grunt.loadNpmTasks('grunt-macreload');
12 | grunt.loadNpmTasks('grunt-angular-gettext');
13 |
14 | // Project Configuration
15 | grunt.initConfig({
16 | pkg: grunt.file.readJSON('package.json'),
17 | concat: {
18 | options: {
19 | process: function(src, filepath) {
20 | if (filepath.substr(filepath.length - 2) === 'js') {
21 | return '// Source: ' + filepath + '\n' +
22 | src.replace(/(^|\n)[ \t]*('use strict'|"use strict");?\s*/g, '$1');
23 | } else {
24 | return src;
25 | }
26 | }
27 | },
28 | vendors: {
29 | src: ['public/src/js/ios-imagefile-megapixel/megapix-image.js', 'public/lib/qrcode-generator/js/qrcode.js', 'public/src/js/jsqrcode/grid.js', 'public/src/js/jsqrcode/version.js', 'public/src/js/jsqrcode/detector.js', 'public/src/js/jsqrcode/formatinf.js', 'public/src/js/jsqrcode/errorlevel.js', 'public/src/js/jsqrcode/bitmat.js', 'public/src/js/jsqrcode/datablock.js', 'public/src/js/jsqrcode/bmparser.js', 'public/src/js/jsqrcode/datamask.js', 'public/src/js/jsqrcode/rsdecoder.js', 'public/src/js/jsqrcode/gf256poly.js', 'public/src/js/jsqrcode/gf256.js', 'public/src/js/jsqrcode/decoder.js', 'public/src/js/jsqrcode/qrcode.js', 'public/src/js/jsqrcode/findpat.js', 'public/src/js/jsqrcode/alignpat.js', 'public/src/js/jsqrcode/databr.js', 'public/lib/moment/min/moment.min.js', 'public/lib/moment/lang/es.js', 'public/lib/zeroclipboard/ZeroClipboard.min.js',
30 | 'public/lib/c3/c3.min.js',
31 | 'public/lib/d3/d3.min.js'
32 | ],
33 | dest: 'public/js/vendors.js'
34 | },
35 | angular: {
36 | src: ['public/lib/angular/angular.min.js', 'public/lib/angular-resource/angular-resource.min.js', 'public/lib/angular-route/angular-route.min.js', 'public/lib/angular-qrcode/qrcode.js', 'public/lib/angular-animate/angular-animate.min.js', 'public/lib/angular-bootstrap/ui-bootstrap.js', 'public/lib/angular-bootstrap/ui-bootstrap-tpls.js', 'public/lib/angular-ui-utils/ui-utils.min.js', 'public/lib/ngprogress/build/ngProgress.min.js', 'public/lib/angular-gettext/dist/angular-gettext.min.js', 'public/lib/angular-moment/angular-moment.min.js'],
37 | dest: 'public/js/angularjs-all.js'
38 | },
39 | main: {
40 | src: ['public/src/js/app.js', 'public/src/js/controllers/*.js', 'public/src/js/services/*.js', 'public/src/js/directives.js', 'public/src/js/filters.js', 'public/src/js/config.js', 'public/src/js/init.js', 'public/src/js/translations.js'],
41 | dest: 'public/js/main.js'
42 | },
43 | css: {
44 | src: [
45 | 'public/lib/bootstrap/dist/css/bootstrap.min.css',
46 | 'public/lib/c3/c3.min.css',
47 | 'public/src/css/**/*.css'
48 | ],
49 | dest: 'public/css/main.css'
50 | }
51 | },
52 | uglify: {
53 | options: {
54 | banner: '/*! <%= pkg.name %> <%= pkg.version %> */\n',
55 | mangle: false
56 | },
57 | vendors: {
58 | src: 'public/js/vendors.js',
59 | dest: 'public/js/vendors.min.js'
60 | },
61 | angular: {
62 | src: 'public/js/angularjs-all.js',
63 | dest: 'public/js/angularjs-all.min.js'
64 | },
65 | main: {
66 | src: 'public/js/main.js',
67 | dest: 'public/js/main.min.js'
68 | }
69 | },
70 | cssmin: {
71 | css: {
72 | src: 'public/css/main.css',
73 | dest: 'public/css/main.min.css'
74 | }
75 | },
76 | markdown: {
77 | all: {
78 | files: [
79 | {
80 | expand: true,
81 | src: 'README.md',
82 | dest: '.',
83 | ext: '.html'
84 | }
85 | ]
86 | }
87 | },
88 | macreload: {
89 | chrome: {
90 | browser: 'chrome',
91 | editor: 'macvim'
92 | }
93 | },
94 | watch: {
95 | main: {
96 | files: ['public/src/js/**/*.js'],
97 | tasks: ['concat:main', 'uglify:main'],
98 | },
99 | css: {
100 | files: ['public/src/css/**/*.css'],
101 | tasks: ['concat:css', 'cssmin'],
102 | },
103 | },
104 | nggettext_extract: {
105 | pot: {
106 | files: {
107 | 'po/template.pot': ['public/views/*.html', 'public/views/**/*.html']
108 | }
109 | },
110 | },
111 | nggettext_compile: {
112 | all: {
113 | options: {
114 | module: 'insight'
115 | },
116 | files: {
117 | 'public/src/js/translations.js': ['po/*.po']
118 | }
119 | },
120 | }
121 | });
122 |
123 | //Making grunt default to force in order not to break the project.
124 | grunt.option('force', true);
125 |
126 | //Default task(s).
127 | grunt.registerTask('default', ['watch']);
128 |
129 | //Update .pot file
130 | grunt.registerTask('translate', ['nggettext_extract']);
131 |
132 | //Compile task (concat + minify)
133 | grunt.registerTask('compile', ['nggettext_compile', 'concat', 'uglify', 'cssmin']);
134 |
135 |
136 | };
137 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Insight UI
2 |
3 | A Bitcoin blockchain explorer web application service for [Bitcore Node](https://github.com/bitpay/bitcore-node) using the [Insight API](https://github.com/zcash-hackworks/insight-api-zcash).
4 |
5 | ## Quick Start
6 |
7 | Please see the guide at [https://bitcore.io/guides/full-node](https://bitcore.io/guides/full-node) for information about getting a block explorer running. This is only the front-end component of the block explorer, and is packaged together with all of the necessary components in [Bitcore](https://github.com/bitpay/bitcore).
8 |
9 | ## Getting Started
10 |
11 | To manually install all of the necessary components, you can run these commands:
12 |
13 | ```bash
14 | npm install -g bitcore-node
15 | bitcore-node create mynode
16 | cd mynode
17 | bitcore-node install insight-api
18 | bitcore-node install insight-ui
19 | bitcore-node start
20 | ```
21 |
22 | Open a web browser to `http://localhost:3001/insight/`
23 |
24 | ## Development
25 |
26 | To run Insight UI locally in development mode:
27 |
28 | Install bower dependencies:
29 |
30 | ```
31 | $ bower install
32 | ```
33 |
34 | To compile and minify the web application's assets:
35 |
36 | ```
37 | $ grunt compile
38 | ```
39 |
40 | There is a convenient Gruntfile.js for automation during editing the code
41 |
42 | ```
43 | $ grunt
44 | ```
45 |
46 | ## Multilanguage support
47 |
48 | Insight UI uses [angular-gettext](http://angular-gettext.rocketeer.be) for multilanguage support.
49 |
50 | To enable a text to be translated, add the ***translate*** directive to html tags. See more details [here](http://angular-gettext.rocketeer.be/dev-guide/annotate/). Then, run:
51 |
52 | ```
53 | grunt compile
54 | ```
55 |
56 | This action will create a template.pot file in ***po/*** folder. You can open it with some PO editor ([Poedit](http://poedit.net)). Read this [guide](http://angular-gettext.rocketeer.be/dev-guide/translate/) to learn how to edit/update/import PO files from a generated POT file. PO file will be generated inside po/ folder.
57 |
58 | If you make new changes, simply run **grunt compile** again to generate a new .pot template and the angular javascript ***js/translations.js***. Then (if use Poedit), open .po file and choose ***update from POT File*** from **Catalog** menu.
59 |
60 | Finally changes your default language from ***public/src/js/config***
61 |
62 | ```
63 | gettextCatalog.currentLanguage = 'es';
64 | ```
65 |
66 | This line will take a look at any *.po files inside ***po/*** folder, e.g.
67 | **po/es.po**, **po/nl.po**. After any change do not forget to run ***grunt
68 | compile***.
69 |
70 |
71 | ## Note
72 |
73 | For more details about the [Insight API](https://github.com/zcash-hackworks/insight-api-zcash) configuration and end-points, go to [Insight API GitHub repository](https://github.com/zcash-hackworks/insight-api-zcash).
74 |
75 | ## Contribute
76 |
77 | Contributions and suggestions are welcomed at the [Insight UI GitHub repository](https://github.com/zcash-hackworks/insight-ui-zcash).
78 |
79 |
80 | ## License
81 | (The MIT License)
82 |
83 | Permission is hereby granted, free of charge, to any person obtaining
84 | a copy of this software and associated documentation files (the
85 | 'Software'), to deal in the Software without restriction, including
86 | without limitation the rights to use, copy, modify, merge, publish,
87 | distribute, sublicense, and/or sell copies of the Software, and to
88 | permit persons to whom the Software is furnished to do so, subject to
89 | the following conditions:
90 |
91 | The above copyright notice and this permission notice shall be
92 | included in all copies or substantial portions of the Software.
93 |
94 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
95 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
96 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
97 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
98 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
99 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
100 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
101 |
--------------------------------------------------------------------------------
/bitcore-node-zcash/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var BaseService = require('./service');
4 | var inherits = require('util').inherits;
5 | var fs = require('fs');
6 |
7 | var InsightUI = function(options) {
8 | BaseService.call(this, options);
9 | if (typeof options.apiPrefix !== 'undefined') {
10 | this.apiPrefix = options.apiPrefix;
11 | } else {
12 | this.apiPrefix = 'insight-api-zcash';
13 | }
14 | if (typeof options.routePrefix !== 'undefined') {
15 | this.routePrefix = options.routePrefix;
16 | } else {
17 | this.routePrefix = 'insight';
18 | }
19 | };
20 |
21 | InsightUI.dependencies = ['insight-api-zcash'];
22 |
23 | inherits(InsightUI, BaseService);
24 |
25 | InsightUI.prototype.start = function(callback) {
26 | this.indexFile = this.filterIndexHTML(fs.readFileSync(__dirname + '/../public/index.html', {encoding: 'utf8'}));
27 | setImmediate(callback);
28 | };
29 |
30 | InsightUI.prototype.getRoutePrefix = function() {
31 | return this.routePrefix;
32 | };
33 |
34 | InsightUI.prototype.setupRoutes = function(app, express) {
35 | var self = this;
36 |
37 | app.use('/', function(req, res, next){
38 | if (req.headers.accept && req.headers.accept.indexOf('text/html') !== -1 &&
39 | req.headers["X-Requested-With"] !== 'XMLHttpRequest'
40 | ) {
41 | res.setHeader('Content-Type', 'text/html');
42 | res.send(self.indexFile);
43 | } else {
44 | express.static(__dirname + '/../public')(req, res, next);
45 | }
46 | });
47 | };
48 |
49 | InsightUI.prototype.filterIndexHTML = function(data) {
50 | var transformed = data
51 | .replace(/apiPrefix = '\/api'/, "apiPrefix = '/" + this.apiPrefix + "'");
52 |
53 | if (this.routePrefix) {
54 | transformed = transformed.replace(/ insight is an open-source Zcash blockchain explorer with complete REST "
27 | "and websocket APIs that can be used for writing web wallets and other apps "
28 | "that need more advanced blockchain queries than provided by zcashd RPC. "
29 | "Check out the source code ."
31 | msgstr ""
32 | "insight es un explorador de bloques de Zcash open-source con un completo "
34 | "conjunto de REST y APIs de websockets que pueden ser usadas para escribir "
35 | "monederos de Zcashs y otras aplicaciones que requieran consultar un "
36 | "explorador de bloques. Obtén el código en el repositorio abierto de Github ."
38 |
39 | #: public/views/index.html
40 | msgid ""
41 | "insight is still in development, so be sure to report any "
42 | "bugs and provide feedback for improvement at our github issue tracker ."
44 | msgstr ""
45 | "insight esta en desarrollo aún, por ello agradecemos que "
46 | "nos reporten errores o sugerencias para mejorar el software. Github issue "
48 | "tracker ."
49 |
50 | #: public/views/index.html
51 | msgid "About"
52 | msgstr "Acerca de"
53 |
54 | #: public/views/address.html
55 | msgid "Address"
56 | msgstr "Dirección"
57 |
58 | #: public/views/index.html
59 | msgid "Age"
60 | msgstr "Edad"
61 |
62 | #: public/views/status.html
63 | msgid "Application Status"
64 | msgstr "Estado de la Aplicación"
65 |
66 | #: public/views/status.html
67 | msgid "Best Block"
68 | msgstr "Mejor Bloque"
69 |
70 | #: public/views/status.html
71 | msgid "Zcash node information"
72 | msgstr "Información del nodo Zcash"
73 |
74 | #: public/views/block.html
75 | msgid "Block"
76 | msgstr "Bloque"
77 |
78 | #: public/views/block.html
79 | msgid "Block Reward"
80 | msgstr "Bloque Recompensa"
81 |
82 | #: public/views/block_list.html public/views/dummy-translations.html
83 | #: public/views/status.html
84 | msgid "Blocks"
85 | msgstr "Bloques"
86 |
87 | #: public/views/status.html
88 | msgid "Bytes Serialized"
89 | msgstr "Bytes Serializados"
90 |
91 | #: public/views/includes/connection.html
92 | msgid ""
93 | "Can't connect to zcashd to get live updates from the p2p network. (Tried "
94 | "connecting to zcashd at {{host}}:{{port}} and failed.)"
95 | msgstr ""
96 | "No se pudo conectar a zcashd para obtener actualizaciones en vivo de la "
97 | "red p2p. (Se intentó conectar a zcashd de {{host}}:{{port}} y falló.)"
98 |
99 | #: public/views/includes/connection.html
100 | msgid "Can't connect to insight server. Attempting to reconnect..."
101 | msgstr "No se pudo conectar al servidor insight. Intentando re-conectar..."
102 |
103 | #: public/views/includes/connection.html
104 | msgid "Can't connect to internet. Please, check your connection."
105 | msgstr "No se pudo conectar a Internet. Por favor, verifique su conexión."
106 |
107 | #: public/views/status.html
108 | msgid "Complete"
109 | msgstr "Completado"
110 |
111 | #: public/views/transaction.html public/views/transaction/tx.html
112 | msgid "Confirmations"
113 | msgstr "Confirmaciones"
114 |
115 | #: public/views/includes/header.html
116 | msgid "Conn"
117 | msgstr "Con"
118 |
119 | #: public/views/status.html
120 | msgid "Connections to other nodes"
121 | msgstr "Conexiones a otros nodos"
122 |
123 | #: public/views/status.html
124 | msgid "Current Blockchain Tip (insight)"
125 | msgstr "Actual Blockchain Tip (insight)"
126 |
127 | #: public/views/status.html
128 | msgid "Current Sync Status"
129 | msgstr "Actual Estado de Sincronización"
130 |
131 | #: public/views/transaction.html
132 | msgid "Details"
133 | msgstr "Detalles"
134 |
135 | #: public/views/block.html
136 | msgid "Difficulty"
137 | msgstr "Dificultad"
138 |
139 | #: public/views/transaction/tx.html
140 | msgid "Double spent attempt detected. From tx:"
141 | msgstr "Intento de doble gasto detectado. De la transacción:"
142 |
143 | #: public/views/includes/connection.html
144 | msgid "Error!"
145 | msgstr "¡Error!"
146 |
147 | #: public/views/transaction/tx.html
148 | msgid "Fee"
149 | msgstr "Tasa"
150 |
151 | #: public/views/address.html
152 | msgid "Final Balance"
153 | msgstr "Balance Final"
154 |
155 | #: public/views/status.html
156 | msgid "Finish Date"
157 | msgstr "Fecha Final"
158 |
159 | #: public/views/404.html
160 | msgid "Go to home"
161 | msgstr "Volver al Inicio"
162 |
163 | #: public/views/status.html
164 | msgid "Hash Serialized"
165 | msgstr "Hash Serializado"
166 |
167 | #: public/views/block.html public/views/block_list.html
168 | #: public/views/index.html public/views/status.html
169 | #: public/views/includes/header.html
170 | msgid "Height"
171 | msgstr "Altura"
172 |
173 | #: public/views/transaction.html public/views/transaction/tx.html
174 | msgid "Included in Block"
175 | msgstr "Incluido en el Bloque"
176 |
177 | #: public/views/transaction/tx.html
178 | msgid "Incoherence in levelDB detected:"
179 | msgstr "Detectada una incoherencia en levelDB:"
180 |
181 | #: public/views/status.html
182 | msgid "Info Errors"
183 | msgstr "Errores de Información"
184 |
185 | #: public/views/status.html
186 | msgid "Initial Block Chain Height"
187 | msgstr "Altura de la Cadena en Bloque Inicial"
188 |
189 | #: public/views/transaction.html
190 | msgid "Input"
191 | msgstr "Entrada"
192 |
193 | #: public/views/status.html
194 | msgid "Last Block"
195 | msgstr "Último Bloque"
196 |
197 | #: public/views/status.html
198 | msgid "Last Block Hash (Zcashd)"
199 | msgstr "Último Bloque Hash (Zcashd)"
200 |
201 | #: public/views/index.html
202 | msgid "Latest Blocks"
203 | msgstr "Últimos Bloques"
204 |
205 | #: public/views/index.html
206 | msgid "Latest Transactions"
207 | msgstr "Últimas Transacciones"
208 |
209 | #: public/views/address.html
210 | msgid "Loading Address Information"
211 | msgstr "Cargando Información de la Dirección"
212 |
213 | #: public/views/block.html
214 | msgid "Loading Block Information"
215 | msgstr "Cargando Información del Bloque"
216 |
217 | #: public/views/block_list.html
218 | msgid "Loading Selected Date..."
219 | msgstr "Cargando Fecha Seleccionada..."
220 |
221 | #: public/views/transaction.html
222 | msgid "Loading Transaction Details"
223 | msgstr "Cargando Detalles de la Transacción"
224 |
225 | #: public/views/transaction/list.html
226 | msgid "Loading Transactions..."
227 | msgstr "Cargando Transacciones..."
228 |
229 | #: public/views/includes/infoStatus.html
230 | msgid "Loading..."
231 | msgstr "Cargando..."
232 |
233 | #: public/views/transaction.html
234 | msgid "Mined Time"
235 | msgstr "Hora de Minado"
236 |
237 | #: public/views/block.html public/views/block_list.html
238 | #: public/views/index.html
239 | msgid "Mined by"
240 | msgstr "Minado por"
241 |
242 | #: public/views/status.html
243 | msgid "Mining Difficulty"
244 | msgstr "Dificultad de Minado"
245 |
246 | #: public/views/block.html
247 | msgid "Next Block"
248 | msgstr "Próximo Bloque"
249 |
250 | #: public/views/transaction/tx.html
251 | msgid "No Inputs (Newly Generated Coins)"
252 | msgstr "Sin Entradas (Monedas Recién Generadas)"
253 |
254 | #: public/views/block_list.html
255 | msgid "No blocks yet."
256 | msgstr "No hay bloques aún."
257 |
258 | #: public/views/includes/header.html public/views/includes/search.html
259 | msgid "No matching records found!"
260 | msgstr "¡No se encontraron registros coincidentes!"
261 |
262 | #: public/views/address.html
263 | msgid "No. Transactions"
264 | msgstr "Nro. de Transacciones"
265 |
266 | #: public/views/block.html
267 | msgid "Number Of Transactions"
268 | msgstr "Número de Transacciones"
269 |
270 | #: public/views/transaction.html
271 | msgid "Output"
272 | msgstr "Salida"
273 |
274 | #: public/views/index.html
275 | msgid "Powered by"
276 | msgstr "Funciona con"
277 |
278 | #: public/views/block.html
279 | msgid "Previous Block"
280 | msgstr "Bloque Anterior"
281 |
282 | #: public/views/status.html
283 | msgid "Protocol version"
284 | msgstr "Versión del protocolo"
285 |
286 | #: public/views/status.html
287 | msgid "Proxy setting"
288 | msgstr "Opción de proxy"
289 |
290 | #: public/views/transaction.html
291 | msgid "Received Time"
292 | msgstr "Hora de Recibido"
293 |
294 | #: public/views/redirect.html
295 | msgid "Redirecting..."
296 | msgstr "Redireccionando..."
297 |
298 | #: public/views/includes/header.html
299 | msgid "Search for block, transaction or address"
300 | msgstr "Buscar bloques, transacciones o direcciones"
301 |
302 | #: public/views/index.html
303 | msgid "See all blocks"
304 | msgstr "Ver todos los bloques"
305 |
306 | #: public/views/status.html
307 | msgid "Show Transaction Output data"
308 | msgstr "Mostrar dato de Salida de la Transacción"
309 |
310 | #: public/views/transaction/tx.html
311 | msgid "Show all"
312 | msgstr "Mostrar todos"
313 |
314 | #: public/views/transaction/tx.html
315 | msgid "Show input"
316 | msgstr "Mostrar entrada"
317 |
318 | #: public/views/transaction/tx.html
319 | msgid "Show less"
320 | msgstr "Ver menos"
321 |
322 | #: public/views/transaction/tx.html
323 | msgid "Show more"
324 | msgstr "Ver más"
325 |
326 | #: public/views/block_list.html public/views/index.html
327 | #: public/views/transaction.html
328 | msgid "Size"
329 | msgstr "Tamaño"
330 |
331 | #: public/views/block.html
332 | msgid "Size (bytes)"
333 | msgstr "Tamaño (bytes)"
334 |
335 | #: public/views/status.html
336 | msgid "Skipped Blocks (previously synced)"
337 | msgstr "Bloques Saltados (previamente sincronizado)"
338 |
339 | #: public/views/status.html
340 | msgid "Start Date"
341 | msgstr "Fecha de Inicio"
342 |
343 | #: public/views/dummy-translations.html
344 | msgid "Status"
345 | msgstr "Estado"
346 |
347 | #: public/views/block.html public/views/transaction.html
348 | msgid "Summary"
349 | msgstr "Resumen"
350 |
351 | #: public/views/address.html
352 | msgid "Summary confirmed "
353 | msgstr "Resumen confirmados "
354 |
355 | #: public/views/status.html
356 | msgid "Sync Progress"
357 | msgstr "Proceso de Sincronización"
358 |
359 | #: public/views/status.html
360 | msgid "Sync Status"
361 | msgstr "Estado de Sincronización"
362 |
363 | #: public/views/status.html
364 | msgid "Sync Type"
365 | msgstr "Tipo de Sincronización"
366 |
367 | #: public/views/status.html
368 | msgid "Synced Blocks"
369 | msgstr "Bloques Sincornizados"
370 |
371 | #: public/views/status.html
372 | msgid "Testnet"
373 | msgstr "Red de prueba"
374 |
375 | #: public/views/transaction/list.html
376 | msgid "There are no transactions involving this address."
377 | msgstr "No hay transacciones para esta dirección"
378 |
379 | #: public/views/status.html
380 | msgid "Time Offset"
381 | msgstr "Desplazamiento de hora"
382 |
383 | #: public/views/block.html
384 | msgid "Timestamp"
385 | msgstr "Fecha y hora"
386 |
387 | #: public/views/block_list.html
388 | msgid "Today"
389 | msgstr "Hoy"
390 |
391 | #: public/views/status.html
392 | msgid "Total Amount"
393 | msgstr "Cantidad Total"
394 |
395 | #: public/views/address.html
396 | msgid "Total Received"
397 | msgstr "Total Recibido"
398 |
399 | #: public/views/address.html
400 | msgid "Total Sent"
401 | msgstr "Total Enviado"
402 |
403 | #: public/views/transaction.html
404 | msgid "Transaction"
405 | msgstr "Transacción"
406 |
407 | #: public/views/status.html
408 | msgid "Transaction Output Set Information"
409 | msgstr "Información del Conjunto de Salida de la Transacción"
410 |
411 | #: public/views/status.html
412 | msgid "Transaction Outputs"
413 | msgstr "Salidas de la Transacción"
414 |
415 | #: public/views/address.html public/views/block.html
416 | #: public/views/block_list.html public/views/index.html
417 | #: public/views/status.html
418 | msgid "Transactions"
419 | msgstr "Transacciones"
420 |
421 | #: public/views/transaction/tx.html
422 | msgid "Type"
423 | msgstr "Tipo"
424 |
425 | #: public/views/address.html
426 | msgid "Unconfirmed"
427 | msgstr "Sin confirmar"
428 |
429 | #: public/views/transaction.html public/views/transaction/tx.html
430 | msgid "Unconfirmed Transaction!"
431 | msgstr "¡Transacción sin confirmar!"
432 |
433 | #: public/views/address.html
434 | msgid "Unconfirmed Txs Balance"
435 | msgstr "Balance sin confirmar"
436 |
437 | #: public/views/index.html
438 | msgid "Value Out"
439 | msgstr "Valor de Salida"
440 |
441 | #: public/views/block.html public/views/status.html
442 | msgid "Version"
443 | msgstr "Versión"
444 |
445 | #: public/views/block_list.html public/views/index.html
446 | msgid "Waiting for blocks..."
447 | msgstr "Esperando bloques..."
448 |
449 | #: public/views/index.html
450 | msgid "Waiting for transactions..."
451 | msgstr "Esperando transacciones..."
452 |
453 | #: public/views/block_list.html
454 | msgid "by date."
455 | msgstr "por fecha."
456 |
457 | #: public/views/transaction/tx.html
458 | msgid "first seen at"
459 | msgstr "Visto a"
460 |
461 | #: public/views/transaction/tx.html
462 | msgid "mined"
463 | msgstr "minado"
464 |
465 | #: public/views/block_list.html
466 | msgid "mined on:"
467 | msgstr "minado el:"
468 |
469 | #~ msgid "Waiting for blocks"
470 | #~ msgstr "Esperando bloques"
471 |
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/img/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/.gitignore
--------------------------------------------------------------------------------
/public/img/angularjs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/angularjs.png
--------------------------------------------------------------------------------
/public/img/icons/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/icons/copy.png
--------------------------------------------------------------------------------
/public/img/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/icons/favicon.ico
--------------------------------------------------------------------------------
/public/img/leveldb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/leveldb.png
--------------------------------------------------------------------------------
/public/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/loading.gif
--------------------------------------------------------------------------------
/public/img/nodejs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/img/nodejs.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Testnet Insight
10 | Insight
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
43 |
44 |
48 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/public/lib/zeroclipboard/ZeroClipboard.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/lib/zeroclipboard/ZeroClipboard.swf
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /address
3 | Disallow: /api
4 | Disallow: /transaction
5 |
--------------------------------------------------------------------------------
/public/sound/transaction.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/str4d/insight-ui-zcash/5a5fdc2aad05194d3b34ab9fce8470b873c7d636/public/sound/transaction.mp3
--------------------------------------------------------------------------------
/public/src/js/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var testnet = false;
4 | var netSymbol = testnet ? 'TAZ' : 'ZEC';
5 |
6 | var defaultLanguage = localStorage.getItem('insight-language') || 'en';
7 | var defaultCurrency = localStorage.getItem('insight-currency') || netSymbol;
8 |
9 | angular.module('insight',[
10 | 'ngAnimate',
11 | 'ngResource',
12 | 'ngRoute',
13 | 'ngProgress',
14 | 'ui.bootstrap',
15 | 'ui.route',
16 | 'monospaced.qrcode',
17 | 'gettext',
18 | 'angularMoment',
19 | 'insight.system',
20 | 'insight.socket',
21 | 'insight.blocks',
22 | 'insight.transactions',
23 | 'insight.address',
24 | 'insight.search',
25 | 'insight.charts',
26 | 'insight.status',
27 | 'insight.connection',
28 | 'insight.currency',
29 | 'insight.messages'
30 | ]);
31 |
32 | angular.module('insight.system', []);
33 | angular.module('insight.socket', []);
34 | angular.module('insight.blocks', []);
35 | angular.module('insight.transactions', []);
36 | angular.module('insight.address', []);
37 | angular.module('insight.search', []);
38 | angular.module('insight.charts', []);
39 | angular.module('insight.status', []);
40 | angular.module('insight.connection', []);
41 | angular.module('insight.currency', []);
42 | angular.module('insight.messages', []);
43 |
--------------------------------------------------------------------------------
/public/src/js/config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //Setting up route
4 | angular.module('insight').config(function($routeProvider) {
5 | $routeProvider.
6 | when('/block/:blockHash', {
7 | templateUrl: 'views/block.html',
8 | title: 'Zcash Block '
9 | }).
10 | when('/block-index/:blockHeight', {
11 | controller: 'BlocksController',
12 | templateUrl: 'views/redirect.html'
13 | }).
14 | when('/tx/send', {
15 | templateUrl: 'views/transaction_sendraw.html',
16 | title: 'Broadcast Raw Transaction'
17 | }).
18 | when('/tx/:txId/:v_type?/:v_index?', {
19 | templateUrl: 'views/transaction.html',
20 | title: 'Zcash Transaction '
21 | }).
22 | when('/', {
23 | templateUrl: 'views/index.html',
24 | title: 'Home'
25 | }).
26 | when('/blocks', {
27 | templateUrl: 'views/block_list.html',
28 | title: 'Zcash Blocks solved Today'
29 | }).
30 | when('/blocks-date/:blockDate/:startTimestamp?', {
31 | templateUrl: 'views/block_list.html',
32 | title: 'Zcash Blocks solved '
33 | }).
34 | when('/address/:addrStr', {
35 | templateUrl: 'views/address.html',
36 | title: 'Zcash Address '
37 | }).
38 | when('/charts/:chartType?', {
39 | templateUrl: 'views/charts.html',
40 | title: 'Charts'
41 | }).
42 | when('/status', {
43 | templateUrl: 'views/status.html',
44 | title: 'Status'
45 | }).
46 | when('/messages/verify', {
47 | templateUrl: 'views/messages_verify.html',
48 | title: 'Verify Message'
49 | })
50 | .otherwise({
51 | templateUrl: 'views/404.html',
52 | title: 'Error'
53 | });
54 | });
55 |
56 | //Setting HTML5 Location Mode
57 | angular.module('insight')
58 | .config(function($locationProvider) {
59 | $locationProvider.html5Mode(true);
60 | $locationProvider.hashPrefix('!');
61 | })
62 | .run(function($rootScope, $route, $location, $routeParams, $anchorScroll, ngProgress, gettextCatalog, amMoment) {
63 | gettextCatalog.currentLanguage = defaultLanguage;
64 | amMoment.changeLocale(defaultLanguage);
65 | $rootScope.$on('$routeChangeStart', function() {
66 | ngProgress.start();
67 | });
68 |
69 | $rootScope.$on('$routeChangeSuccess', function() {
70 | ngProgress.complete();
71 |
72 | //Change page title, based on Route information
73 | $rootScope.titleDetail = '';
74 | $rootScope.title = $route.current.title;
75 | $rootScope.isCollapsed = true;
76 | $rootScope.currentAddr = null;
77 |
78 | $location.hash($routeParams.scrollTo);
79 | $anchorScroll();
80 | });
81 | });
82 |
--------------------------------------------------------------------------------
/public/src/js/controllers/address.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.address').controller('AddressController',
4 | function($scope, $rootScope, $routeParams, $location, Global, Address, getSocket) {
5 | $scope.global = Global;
6 |
7 | var socket = getSocket($scope);
8 | var addrStr = $routeParams.addrStr;
9 |
10 | var _startSocket = function() {
11 | socket.on('bitcoind/addresstxid', function(data) {
12 | if (data.address === addrStr) {
13 | $rootScope.$broadcast('tx', data.txid);
14 | var base = document.querySelector('base');
15 | var beep = new Audio(base.href + '/sound/transaction.mp3');
16 | beep.play();
17 | }
18 | });
19 | socket.emit('subscribe', 'bitcoind/addresstxid', [addrStr]);
20 | };
21 |
22 | var _stopSocket = function () {
23 | socket.emit('unsubscribe', 'bitcoind/addresstxid', [addrStr]);
24 | };
25 |
26 | socket.on('connect', function() {
27 | _startSocket();
28 | });
29 |
30 | $scope.$on('$destroy', function(){
31 | _stopSocket();
32 | });
33 |
34 | $scope.params = $routeParams;
35 |
36 | $scope.findOne = function() {
37 | $rootScope.currentAddr = $routeParams.addrStr;
38 | _startSocket();
39 |
40 | Address.get({
41 | addrStr: $routeParams.addrStr
42 | },
43 | function(address) {
44 | $rootScope.titleDetail = address.addrStr.substring(0, 7) + '...';
45 | $rootScope.flashMessage = null;
46 | $scope.address = address;
47 | },
48 | function(e) {
49 | if (e.status === 400) {
50 | $rootScope.flashMessage = 'Invalid Address: ' + $routeParams.addrStr;
51 | } else if (e.status === 503) {
52 | $rootScope.flashMessage = 'Backend Error. ' + e.data;
53 | } else {
54 | $rootScope.flashMessage = 'Address Not Found';
55 | }
56 | $location.path('/');
57 | });
58 | };
59 |
60 | });
61 |
--------------------------------------------------------------------------------
/public/src/js/controllers/blocks.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.blocks').controller('BlocksController',
4 | function($scope, $rootScope, $routeParams, $location, Global, Block, Blocks, BlockByHeight) {
5 | $scope.global = Global;
6 | $scope.loading = false;
7 |
8 | if ($routeParams.blockHeight) {
9 | BlockByHeight.get({
10 | blockHeight: $routeParams.blockHeight
11 | }, function(hash) {
12 | $location.path('/block/' + hash.blockHash);
13 | }, function() {
14 | $rootScope.flashMessage = 'Bad Request';
15 | $location.path('/');
16 | });
17 | }
18 |
19 | //Datepicker
20 | var _formatTimestamp = function (date) {
21 | var yyyy = date.getUTCFullYear().toString();
22 | var mm = (date.getUTCMonth() + 1).toString(); // getMonth() is zero-based
23 | var dd = date.getUTCDate().toString();
24 |
25 | return yyyy + '-' + (mm[1] ? mm : '0' + mm[0]) + '-' + (dd[1] ? dd : '0' + dd[0]); //padding
26 | };
27 |
28 | $scope.$watch('dt', function(newValue, oldValue) {
29 | if (newValue !== oldValue) {
30 | $location.path('/blocks-date/' + _formatTimestamp(newValue));
31 | }
32 | });
33 |
34 | $scope.openCalendar = function($event) {
35 | $event.preventDefault();
36 | $event.stopPropagation();
37 |
38 | $scope.opened = true;
39 | };
40 |
41 | $scope.humanSince = function(time) {
42 | var m = moment.unix(time).startOf('day');
43 | var b = moment().startOf('day');
44 | return moment.min(m).from(b);
45 | };
46 |
47 |
48 | $scope.list = function() {
49 | $scope.loading = true;
50 |
51 | if ($routeParams.blockDate) {
52 | $scope.detail = 'On ' + $routeParams.blockDate;
53 | }
54 |
55 | if ($routeParams.startTimestamp) {
56 | var d=new Date($routeParams.startTimestamp*1000);
57 | var m=d.getMinutes();
58 | if (m<10) m = '0' + m;
59 | $scope.before = ' before ' + d.getHours() + ':' + m;
60 | }
61 |
62 | $rootScope.titleDetail = $scope.detail;
63 |
64 | Blocks.get({
65 | blockDate: $routeParams.blockDate,
66 | startTimestamp: $routeParams.startTimestamp
67 | }, function(res) {
68 | $scope.loading = false;
69 | $scope.blocks = res.blocks;
70 | $scope.pagination = res.pagination;
71 | });
72 | };
73 |
74 | $scope.findOne = function() {
75 | $scope.loading = true;
76 |
77 | Block.get({
78 | blockHash: $routeParams.blockHash
79 | }, function(block) {
80 | $rootScope.titleDetail = block.height;
81 | $rootScope.flashMessage = null;
82 | $scope.loading = false;
83 | $scope.block = block;
84 | }, function(e) {
85 | if (e.status === 400) {
86 | $rootScope.flashMessage = 'Invalid Transaction ID: ' + $routeParams.txId;
87 | }
88 | else if (e.status === 503) {
89 | $rootScope.flashMessage = 'Backend Error. ' + e.data;
90 | }
91 | else {
92 | $rootScope.flashMessage = 'Block Not Found';
93 | }
94 | $location.path('/');
95 | });
96 | };
97 |
98 | $scope.params = $routeParams;
99 |
100 | });
101 |
--------------------------------------------------------------------------------
/public/src/js/controllers/charts.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.charts').controller('ChartsController',
4 | function($scope, $rootScope, $routeParams, $location, Chart, Charts) {
5 | $scope.loading = false;
6 |
7 | $scope.list = function() {
8 | Charts.get({
9 | }, function(res) {
10 | $scope.charts = res.charts;
11 | });
12 |
13 | if ($routeParams.chartType) {
14 | $scope.chart();
15 | }
16 | };
17 |
18 | $scope.chart = function() {
19 | $scope.loading = true;
20 |
21 | Chart.get({
22 | chartType: $routeParams.chartType
23 | }, function(chart) {
24 | $scope.loading = false;
25 | $scope.chartType = $routeParams.chartType;
26 | $scope.chartName = chart.name;
27 | $scope.chart = c3.generate(chart);
28 | }, function(e) {
29 | if (e.status === 400) {
30 | $rootScope.flashMessage = 'Invalid chart: ' + $routeParams.chartType;
31 | }
32 | else if (e.status === 503) {
33 | $rootScope.flashMessage = 'Backend Error. ' + e.data;
34 | }
35 | else {
36 | $rootScope.flashMessage = 'Chart Not Found';
37 | }
38 | $location.path('/');
39 | });
40 | };
41 |
42 | $scope.params = $routeParams;
43 |
44 | });
45 |
--------------------------------------------------------------------------------
/public/src/js/controllers/connection.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.connection').controller('ConnectionController',
4 | function($scope, $window, Status, getSocket, PeerSync) {
5 |
6 | // Set initial values
7 | $scope.apiOnline = true;
8 | $scope.serverOnline = true;
9 | $scope.clienteOnline = true;
10 |
11 | var socket = getSocket($scope);
12 |
13 | // Check for the node server connection
14 | socket.on('connect', function() {
15 | $scope.serverOnline = true;
16 | socket.on('disconnect', function() {
17 | $scope.serverOnline = false;
18 | });
19 | });
20 |
21 | // Check for the api connection
22 | $scope.getConnStatus = function() {
23 | PeerSync.get({},
24 | function(peer) {
25 | $scope.apiOnline = peer.connected;
26 | $scope.host = peer.host;
27 | $scope.port = peer.port;
28 | },
29 | function() {
30 | $scope.apiOnline = false;
31 | });
32 | };
33 |
34 | socket.emit('subscribe', 'sync');
35 | socket.on('status', function(sync) {
36 | $scope.sync = sync;
37 | $scope.apiOnline = (sync.status !== 'aborted' && sync.status !== 'error');
38 | });
39 |
40 | // Check for the client conneciton
41 | $window.addEventListener('offline', function() {
42 | $scope.$apply(function() {
43 | $scope.clienteOnline = false;
44 | });
45 | }, true);
46 |
47 | $window.addEventListener('online', function() {
48 | $scope.$apply(function() {
49 | $scope.clienteOnline = true;
50 | });
51 | }, true);
52 |
53 | });
54 |
--------------------------------------------------------------------------------
/public/src/js/controllers/currency.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.currency').controller('CurrencyController',
4 | function($scope, $rootScope, Currency) {
5 | $rootScope.currency.symbol = defaultCurrency;
6 |
7 | var _roundFloat = function(x, n) {
8 | if(!parseInt(n, 10) || !parseFloat(x)) n = 0;
9 |
10 | return Math.round(x * Math.pow(10, n)) / Math.pow(10, n);
11 | };
12 |
13 | $rootScope.currency.getConvertion = function(value) {
14 | value = value * 1; // Convert to number
15 |
16 | if (!isNaN(value) && typeof value !== 'undefined' && value !== null) {
17 | if (value === 0.00000000) return '0 ' + this.symbol; // fix value to show
18 |
19 | var response;
20 |
21 | if (this.symbol === 'USD') {
22 | response = _roundFloat((value * this.factor), 2);
23 | } else if (this.symbol === 'm'+netSymbol) {
24 | this.factor = 1000;
25 | response = _roundFloat((value * this.factor), 5);
26 | } else if (this.symbol === 'bits') {
27 | this.factor = 1000000;
28 | response = _roundFloat((value * this.factor), 2);
29 | } else {
30 | this.factor = 1;
31 | response = value;
32 | }
33 | // prevent sci notation
34 | if (response < 1e-7) response=response.toFixed(8);
35 |
36 | return response + ' ' + this.symbol;
37 | }
38 |
39 | return 'value error';
40 | };
41 |
42 | $scope.setCurrency = function(currency) {
43 | $rootScope.currency.symbol = currency;
44 | localStorage.setItem('insight-currency', currency);
45 |
46 | if (currency === 'USD') {
47 | Currency.get({}, function(res) {
48 | $rootScope.currency.factor = $rootScope.currency.bitstamp = res.data.bitstamp;
49 | });
50 | } else if (currency === 'm'+netSymbol) {
51 | $rootScope.currency.factor = 1000;
52 | } else if (currency === 'bits') {
53 | $rootScope.currency.factor = 1000000;
54 | } else {
55 | $rootScope.currency.factor = 1;
56 | }
57 | };
58 |
59 | // Get initial value
60 | Currency.get({}, function(res) {
61 | $rootScope.currency.factor = $rootScope.currency.bitstamp = res.data.bitstamp;
62 | });
63 |
64 | });
65 |
--------------------------------------------------------------------------------
/public/src/js/controllers/footer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.system').controller('FooterController',
4 | function($scope, $route, $templateCache, gettextCatalog, amMoment, Version) {
5 |
6 | $scope.defaultLanguage = defaultLanguage;
7 |
8 | var _getVersion = function() {
9 | Version.get({},
10 | function(res) {
11 | $scope.version = res.version;
12 | });
13 | };
14 |
15 | $scope.version = _getVersion();
16 |
17 | $scope.availableLanguages = [{
18 | name: 'Deutsch',
19 | isoCode: 'de_DE',
20 | }, {
21 | name: 'English',
22 | isoCode: 'en',
23 | }, {
24 | name: 'Spanish',
25 | isoCode: 'es',
26 | }, {
27 | name: 'Japanese',
28 | isoCode: 'ja',
29 | }];
30 |
31 | $scope.setLanguage = function(isoCode) {
32 | gettextCatalog.currentLanguage = $scope.defaultLanguage = defaultLanguage = isoCode;
33 | amMoment.changeLocale(isoCode);
34 | localStorage.setItem('insight-language', isoCode);
35 | var currentPageTemplate = $route.current.templateUrl;
36 | $templateCache.remove(currentPageTemplate);
37 | $route.reload();
38 | };
39 |
40 | });
41 |
--------------------------------------------------------------------------------
/public/src/js/controllers/header.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.system').controller('HeaderController',
4 | function($scope, $rootScope, $modal, getSocket, Global, Block) {
5 | $scope.global = Global;
6 |
7 | $rootScope.currency = {
8 | factor: 1,
9 | bitstamp: 0,
10 | testnet: testnet,
11 | netSymbol: netSymbol,
12 | symbol: netSymbol
13 | };
14 |
15 | $scope.menu = [{
16 | 'title': 'Blocks',
17 | 'link': 'blocks'
18 | }, {
19 | 'title': 'Charts',
20 | 'link': 'charts'
21 | }, {
22 | 'title': 'Status',
23 | 'link': 'status'
24 | }];
25 |
26 | $scope.openScannerModal = function() {
27 | var modalInstance = $modal.open({
28 | templateUrl: 'scannerModal.html',
29 | controller: 'ScannerController'
30 | });
31 | };
32 |
33 | var _getBlock = function(hash) {
34 | Block.get({
35 | blockHash: hash
36 | }, function(res) {
37 | $scope.totalBlocks = res.height;
38 | });
39 | };
40 |
41 | var socket = getSocket($scope);
42 | socket.on('connect', function() {
43 | socket.emit('subscribe', 'inv');
44 |
45 | socket.on('block', function(block) {
46 | var blockHash = block.toString();
47 | _getBlock(blockHash);
48 | });
49 | });
50 |
51 | $rootScope.isCollapsed = true;
52 | });
53 |
--------------------------------------------------------------------------------
/public/src/js/controllers/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var TRANSACTION_DISPLAYED = 10;
4 | var BLOCKS_DISPLAYED = 5;
5 |
6 | angular.module('insight.system').controller('IndexController',
7 | function($scope, Global, getSocket, Blocks) {
8 | $scope.global = Global;
9 |
10 | var _getBlocks = function() {
11 | Blocks.get({
12 | limit: BLOCKS_DISPLAYED
13 | }, function(res) {
14 | $scope.blocks = res.blocks;
15 | $scope.blocksLength = res.length;
16 | });
17 | };
18 |
19 | var socket = getSocket($scope);
20 |
21 | var _startSocket = function() {
22 | socket.emit('subscribe', 'inv');
23 | socket.on('tx', function(tx) {
24 | $scope.txs.unshift(tx);
25 | if (parseInt($scope.txs.length, 10) >= parseInt(TRANSACTION_DISPLAYED, 10)) {
26 | $scope.txs = $scope.txs.splice(0, TRANSACTION_DISPLAYED);
27 | }
28 | });
29 |
30 | socket.on('block', function() {
31 | _getBlocks();
32 | });
33 | };
34 |
35 | socket.on('connect', function() {
36 | _startSocket();
37 | });
38 |
39 |
40 |
41 | $scope.humanSince = function(time) {
42 | var m = moment.unix(time);
43 | return moment.min(m).fromNow();
44 | };
45 |
46 | $scope.index = function() {
47 | _getBlocks();
48 | _startSocket();
49 | };
50 |
51 | $scope.txs = [];
52 | $scope.blocks = [];
53 | });
54 |
--------------------------------------------------------------------------------
/public/src/js/controllers/messages.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.messages').controller('VerifyMessageController',
4 | function($scope, $http) {
5 | $scope.message = {
6 | address: '',
7 | signature: '',
8 | message: ''
9 | };
10 | $scope.verification = {
11 | status: 'unverified', // ready|loading|verified|error
12 | result: null,
13 | error: null,
14 | address: ''
15 | };
16 |
17 | $scope.verifiable = function() {
18 | return ($scope.message.address
19 | && $scope.message.signature
20 | && $scope.message.message);
21 | };
22 | $scope.verify = function() {
23 | $scope.verification.status = 'loading';
24 | $scope.verification.address = $scope.message.address;
25 | $http.post(window.apiPrefix + '/messages/verify', $scope.message)
26 | .success(function(data, status, headers, config) {
27 | if(typeof(data.result) != 'boolean') {
28 | // API returned 200 but result was not true or false
29 | $scope.verification.status = 'error';
30 | $scope.verification.error = null;
31 | return;
32 | }
33 |
34 | $scope.verification.status = 'verified';
35 | $scope.verification.result = data.result;
36 | })
37 | .error(function(data, status, headers, config) {
38 | $scope.verification.status = 'error';
39 | $scope.verification.error = data;
40 | });
41 | };
42 |
43 | // Hide the verify status message on form change
44 | var unverify = function() {
45 | $scope.verification.status = 'unverified';
46 | };
47 | $scope.$watch('message.address', unverify);
48 | $scope.$watch('message.signature', unverify);
49 | $scope.$watch('message.message', unverify);
50 | });
51 |
--------------------------------------------------------------------------------
/public/src/js/controllers/scanner.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.system').controller('ScannerController',
4 | function($scope, $rootScope, $modalInstance, Global) {
5 | $scope.global = Global;
6 |
7 | // Detect mobile devices
8 | var isMobile = {
9 | Android: function() {
10 | return navigator.userAgent.match(/Android/i);
11 | },
12 | BlackBerry: function() {
13 | return navigator.userAgent.match(/BlackBerry/i);
14 | },
15 | iOS: function() {
16 | return navigator.userAgent.match(/iPhone|iPad|iPod/i);
17 | },
18 | Opera: function() {
19 | return navigator.userAgent.match(/Opera Mini/i);
20 | },
21 | Windows: function() {
22 | return navigator.userAgent.match(/IEMobile/i);
23 | },
24 | any: function() {
25 | return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
26 | }
27 | };
28 |
29 | navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
30 | window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
31 |
32 | $scope.isMobile = isMobile.any();
33 | $scope.scannerLoading = false;
34 |
35 | var $searchInput = angular.element(document.getElementById('search')),
36 | cameraInput,
37 | video,
38 | canvas,
39 | $video,
40 | context,
41 | localMediaStream;
42 |
43 | var _scan = function(evt) {
44 | if ($scope.isMobile) {
45 | $scope.scannerLoading = true;
46 | var files = evt.target.files;
47 |
48 | if (files.length === 1 && files[0].type.indexOf('image/') === 0) {
49 | var file = files[0];
50 |
51 | var reader = new FileReader();
52 | reader.onload = (function(theFile) {
53 | return function(e) {
54 | var mpImg = new MegaPixImage(file);
55 | mpImg.render(canvas, { maxWidth: 200, maxHeight: 200, orientation: 6 });
56 |
57 | setTimeout(function() {
58 | qrcode.width = canvas.width;
59 | qrcode.height = canvas.height;
60 | qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);
61 |
62 | try {
63 | //alert(JSON.stringify(qrcode.process(context)));
64 | qrcode.decode();
65 | } catch (e) {
66 | alert(e);
67 | }
68 | }, 1500);
69 | };
70 | })(file);
71 |
72 | // Read in the file as a data URL
73 | reader.readAsDataURL(file);
74 | }
75 | } else {
76 | if (localMediaStream) {
77 | context.drawImage(video, 0, 0, 300, 225);
78 |
79 | try {
80 | qrcode.decode();
81 | } catch(e) {
82 | //qrcodeError(e);
83 | }
84 | }
85 |
86 | setTimeout(_scan, 500);
87 | }
88 | };
89 |
90 | var _successCallback = function(stream) {
91 | video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
92 | localMediaStream = stream;
93 | video.play();
94 | setTimeout(_scan, 1000);
95 | };
96 |
97 | var _scanStop = function() {
98 | $scope.scannerLoading = false;
99 | $modalInstance.close();
100 | if (!$scope.isMobile) {
101 | if (localMediaStream.stop) localMediaStream.stop();
102 | localMediaStream = null;
103 | video.src = '';
104 | }
105 | };
106 |
107 | var _videoError = function(err) {
108 | console.log('Video Error: ' + JSON.stringify(err));
109 | _scanStop();
110 | };
111 |
112 | qrcode.callback = function(data) {
113 | _scanStop();
114 |
115 | var str = (data.indexOf('zcash:') === 0) ? data.substring(8) : data;
116 | console.log('QR code detected: ' + str);
117 | $searchInput
118 | .val(str)
119 | .triggerHandler('change')
120 | .triggerHandler('submit');
121 | };
122 |
123 | $scope.cancel = function() {
124 | _scanStop();
125 | };
126 |
127 | $modalInstance.opened.then(function() {
128 | $rootScope.isCollapsed = true;
129 |
130 | // Start the scanner
131 | setTimeout(function() {
132 | canvas = document.getElementById('qr-canvas');
133 | context = canvas.getContext('2d');
134 |
135 | if ($scope.isMobile) {
136 | cameraInput = document.getElementById('qrcode-camera');
137 | cameraInput.addEventListener('change', _scan, false);
138 | } else {
139 | video = document.getElementById('qrcode-scanner-video');
140 | $video = angular.element(video);
141 | canvas.width = 300;
142 | canvas.height = 225;
143 | context.clearRect(0, 0, 300, 225);
144 |
145 | navigator.getUserMedia({video: true}, _successCallback, _videoError);
146 | }
147 | }, 500);
148 | });
149 | });
150 |
--------------------------------------------------------------------------------
/public/src/js/controllers/search.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.search').controller('SearchController',
4 | function($scope, $routeParams, $location, $timeout, Global, Block, Transaction, Address, BlockByHeight) {
5 | $scope.global = Global;
6 | $scope.loading = false;
7 |
8 | var _badQuery = function() {
9 | $scope.badQuery = true;
10 |
11 | $timeout(function() {
12 | $scope.badQuery = false;
13 | }, 2000);
14 | };
15 |
16 | var _resetSearch = function() {
17 | $scope.q = '';
18 | $scope.loading = false;
19 | };
20 |
21 | $scope.search = function() {
22 | var q = $scope.q;
23 | $scope.badQuery = false;
24 | $scope.loading = true;
25 |
26 | Block.get({
27 | blockHash: q
28 | }, function() {
29 | _resetSearch();
30 | $location.path('block/' + q);
31 | }, function() { //block not found, search on TX
32 | Transaction.get({
33 | txId: q
34 | }, function() {
35 | _resetSearch();
36 | $location.path('tx/' + q);
37 | }, function() { //tx not found, search on Address
38 | Address.get({
39 | addrStr: q
40 | }, function() {
41 | _resetSearch();
42 | $location.path('address/' + q);
43 | }, function() { // block by height not found
44 | if (isFinite(q)) { // ensure that q is a finite number. A logical height value.
45 | BlockByHeight.get({
46 | blockHeight: q
47 | }, function(hash) {
48 | _resetSearch();
49 | $location.path('/block/' + hash.blockHash);
50 | }, function() { //not found, fail :(
51 | $scope.loading = false;
52 | _badQuery();
53 | });
54 | }
55 | else {
56 | $scope.loading = false;
57 | _badQuery();
58 | }
59 | });
60 | });
61 | });
62 | };
63 |
64 | });
65 |
--------------------------------------------------------------------------------
/public/src/js/controllers/status.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.status').controller('StatusController',
4 | function($scope, $routeParams, $location, Global, Status, Sync, getSocket) {
5 | $scope.global = Global;
6 |
7 | $scope.getStatus = function(q) {
8 | Status.get({
9 | q: 'get' + q
10 | },
11 | function(d) {
12 | $scope.loaded = 1;
13 | angular.extend($scope, d);
14 | },
15 | function(e) {
16 | $scope.error = 'API ERROR: ' + e.data;
17 | });
18 | };
19 |
20 | $scope.humanSince = function(time) {
21 | var m = moment.unix(time / 1000);
22 | return moment.min(m).fromNow();
23 | };
24 |
25 | var _onSyncUpdate = function(sync) {
26 | $scope.sync = sync;
27 | };
28 |
29 | var _startSocket = function () {
30 | socket.emit('subscribe', 'sync');
31 | socket.on('status', function(sync) {
32 | _onSyncUpdate(sync);
33 | });
34 | };
35 |
36 | var socket = getSocket($scope);
37 | socket.on('connect', function() {
38 | _startSocket();
39 | });
40 |
41 |
42 | $scope.getSync = function() {
43 | _startSocket();
44 | Sync.get({},
45 | function(sync) {
46 | _onSyncUpdate(sync);
47 | },
48 | function(e) {
49 | var err = 'Could not get sync information' + e.toString();
50 | $scope.sync = {
51 | error: err
52 | };
53 | });
54 | };
55 | });
56 |
--------------------------------------------------------------------------------
/public/src/js/controllers/transactions.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.transactions').controller('transactionsController',
4 | function($scope, $rootScope, $routeParams, $location, Global, Transaction, TransactionsByBlock, TransactionsByAddress) {
5 | $scope.global = Global;
6 | $scope.loading = false;
7 | $scope.loadedBy = null;
8 |
9 | var pageNum = 0;
10 | var pagesTotal = 1;
11 | var COIN = 100000000;
12 |
13 | var _aggregateItems = function(items) {
14 | if (!items) return [];
15 |
16 | var l = items.length;
17 |
18 | var ret = [];
19 | var tmp = {};
20 | var u = 0;
21 |
22 | for(var i=0; i < l; i++) {
23 |
24 | var notAddr = false;
25 | // non standard input
26 | if (items[i].scriptSig && !items[i].addr) {
27 | items[i].addr = 'Unparsed address [' + u++ + ']';
28 | items[i].notAddr = true;
29 | notAddr = true;
30 | }
31 |
32 | // non standard output
33 | if (items[i].scriptPubKey && !items[i].scriptPubKey.addresses) {
34 | items[i].scriptPubKey.addresses = ['Unparsed address [' + u++ + ']'];
35 | items[i].notAddr = true;
36 | notAddr = true;
37 | }
38 |
39 | // multiple addr at output
40 | if (items[i].scriptPubKey && items[i].scriptPubKey.addresses.length > 1) {
41 | items[i].addr = items[i].scriptPubKey.addresses.join(',');
42 | ret.push(items[i]);
43 | continue;
44 | }
45 |
46 | var addr = items[i].addr || (items[i].scriptPubKey && items[i].scriptPubKey.addresses[0]);
47 |
48 | if (!tmp[addr]) {
49 | tmp[addr] = {};
50 | tmp[addr].valueSat = 0;
51 | tmp[addr].count = 0;
52 | tmp[addr].addr = addr;
53 | tmp[addr].items = [];
54 | }
55 | tmp[addr].isSpent = items[i].spentTxId;
56 |
57 | tmp[addr].doubleSpentTxID = tmp[addr].doubleSpentTxID || items[i].doubleSpentTxID;
58 | tmp[addr].doubleSpentIndex = tmp[addr].doubleSpentIndex || items[i].doubleSpentIndex;
59 | tmp[addr].dbError = tmp[addr].dbError || items[i].dbError;
60 | tmp[addr].valueSat += Math.round(items[i].value * COIN);
61 | tmp[addr].items.push(items[i]);
62 | tmp[addr].notAddr = notAddr;
63 |
64 | if (items[i].unconfirmedInput)
65 | tmp[addr].unconfirmedInput = true;
66 |
67 | tmp[addr].count++;
68 | }
69 |
70 | angular.forEach(tmp, function(v) {
71 | v.value = v.value || parseInt(v.valueSat) / COIN;
72 | ret.push(v);
73 | });
74 | return ret;
75 | };
76 |
77 | var _processTX = function(tx) {
78 | tx.vinSimple = _aggregateItems(tx.vin);
79 | tx.voutSimple = _aggregateItems(tx.vout);
80 | };
81 |
82 | var _paginate = function(data) {
83 | $scope.loading = false;
84 |
85 | pagesTotal = data.pagesTotal;
86 | pageNum += 1;
87 |
88 | data.txs.forEach(function(tx) {
89 | _processTX(tx);
90 | $scope.txs.push(tx);
91 | });
92 | };
93 |
94 | var _byBlock = function() {
95 | TransactionsByBlock.get({
96 | block: $routeParams.blockHash,
97 | pageNum: pageNum
98 | }, function(data) {
99 | _paginate(data);
100 | });
101 | };
102 |
103 | var _byAddress = function () {
104 | TransactionsByAddress.get({
105 | address: $routeParams.addrStr,
106 | pageNum: pageNum
107 | }, function(data) {
108 | _paginate(data);
109 | });
110 | };
111 |
112 | var _findTx = function(txid) {
113 | Transaction.get({
114 | txId: txid
115 | }, function(tx) {
116 | $rootScope.titleDetail = tx.txid.substring(0,7) + '...';
117 | $rootScope.flashMessage = null;
118 | $scope.tx = tx;
119 | _processTX(tx);
120 | $scope.txs.unshift(tx);
121 | }, function(e) {
122 | if (e.status === 400) {
123 | $rootScope.flashMessage = 'Invalid Transaction ID: ' + $routeParams.txId;
124 | }
125 | else if (e.status === 503) {
126 | $rootScope.flashMessage = 'Backend Error. ' + e.data;
127 | }
128 | else {
129 | $rootScope.flashMessage = 'Transaction Not Found';
130 | }
131 |
132 | $location.path('/');
133 | });
134 | };
135 |
136 | $scope.findThis = function() {
137 | _findTx($routeParams.txId);
138 | };
139 |
140 | //Initial load
141 | $scope.load = function(from) {
142 | $scope.loadedBy = from;
143 | $scope.loadMore();
144 | };
145 |
146 | //Load more transactions for pagination
147 | $scope.loadMore = function() {
148 | if (pageNum < pagesTotal && !$scope.loading) {
149 | $scope.loading = true;
150 |
151 | if ($scope.loadedBy === 'address') {
152 | _byAddress();
153 | }
154 | else {
155 | _byBlock();
156 | }
157 | }
158 | };
159 |
160 | // Highlighted txout
161 | if ($routeParams.v_type == '>' || $routeParams.v_type == '<') {
162 | $scope.from_vin = $routeParams.v_type == '<' ? true : false;
163 | $scope.from_vout = $routeParams.v_type == '>' ? true : false;
164 | $scope.v_index = parseInt($routeParams.v_index);
165 | $scope.itemsExpanded = true;
166 | }
167 |
168 | //Init without txs
169 | $scope.txs = [];
170 |
171 | $scope.$on('tx', function(event, txid) {
172 | _findTx(txid);
173 | });
174 |
175 | });
176 |
177 | angular.module('insight.transactions').controller('SendRawTransactionController',
178 | function($scope, $http) {
179 | $scope.transaction = '';
180 | $scope.status = 'ready'; // ready|loading|sent|error
181 | $scope.txid = '';
182 | $scope.error = null;
183 |
184 | $scope.formValid = function() {
185 | return !!$scope.transaction;
186 | };
187 | $scope.send = function() {
188 | var postData = {
189 | rawtx: $scope.transaction
190 | };
191 | $scope.status = 'loading';
192 | $http.post(window.apiPrefix + '/tx/send', postData)
193 | .success(function(data, status, headers, config) {
194 | if(typeof(data.txid) != 'string') {
195 | // API returned 200 but the format is not known
196 | $scope.status = 'error';
197 | $scope.error = 'The transaction was sent but no transaction id was got back';
198 | return;
199 | }
200 |
201 | $scope.status = 'sent';
202 | $scope.txid = data.txid;
203 | })
204 | .error(function(data, status, headers, config) {
205 | $scope.status = 'error';
206 | if(data) {
207 | $scope.error = data;
208 | } else {
209 | $scope.error = "No error message given (connection error?)"
210 | }
211 | });
212 | };
213 | });
214 |
--------------------------------------------------------------------------------
/public/src/js/directives.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var ZeroClipboard = window.ZeroClipboard;
4 |
5 | angular.module('insight')
6 | .directive('scroll', function ($window) {
7 | return function(scope, element, attrs) {
8 | angular.element($window).bind('scroll', function() {
9 | if (this.pageYOffset >= 200) {
10 | scope.secondaryNavbar = true;
11 | } else {
12 | scope.secondaryNavbar = false;
13 | }
14 | scope.$apply();
15 | });
16 | };
17 | })
18 | .directive('whenScrolled', function($window) {
19 | return {
20 | restric: 'A',
21 | link: function(scope, elm, attr) {
22 | var pageHeight, clientHeight, scrollPos;
23 | $window = angular.element($window);
24 |
25 | var handler = function() {
26 | pageHeight = window.document.documentElement.scrollHeight;
27 | clientHeight = window.document.documentElement.clientHeight;
28 | scrollPos = window.pageYOffset;
29 |
30 | if (pageHeight - (scrollPos + clientHeight) === 0) {
31 | scope.$apply(attr.whenScrolled);
32 | }
33 | };
34 |
35 | $window.on('scroll', handler);
36 |
37 | scope.$on('$destroy', function() {
38 | return $window.off('scroll', handler);
39 | });
40 | }
41 | };
42 | })
43 | .directive('clipCopy', function() {
44 | ZeroClipboard.config({
45 | moviePath: '/lib/zeroclipboard/ZeroClipboard.swf',
46 | trustedDomains: ['*'],
47 | allowScriptAccess: 'always',
48 | forceHandCursor: true
49 | });
50 |
51 | return {
52 | restric: 'A',
53 | scope: { clipCopy: '=clipCopy' },
54 | template: '',
55 | link: function(scope, elm) {
56 | var clip = new ZeroClipboard(elm);
57 |
58 | clip.on('load', function(client) {
59 | var onMousedown = function(client) {
60 | client.setText(scope.clipCopy);
61 | };
62 |
63 | client.on('mousedown', onMousedown);
64 |
65 | scope.$on('$destroy', function() {
66 | client.off('mousedown', onMousedown);
67 | });
68 | });
69 |
70 | clip.on('noFlash wrongflash', function() {
71 | return elm.remove();
72 | });
73 | }
74 | };
75 | })
76 | .directive('focus', function ($timeout) {
77 | return {
78 | scope: {
79 | trigger: '@focus'
80 | },
81 | link: function (scope, element) {
82 | scope.$watch('trigger', function (value) {
83 | if (value === "true") {
84 | $timeout(function () {
85 | element[0].focus();
86 | });
87 | }
88 | });
89 | }
90 | };
91 | });
92 |
--------------------------------------------------------------------------------
/public/src/js/filters.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight')
4 | .filter('startFrom', function() {
5 | return function(input, start) {
6 | start = +start; //parse to int
7 | return input.slice(start);
8 | }
9 | })
10 | .filter('split', function() {
11 | return function(input, delimiter) {
12 | var delimiter = delimiter || ',';
13 | return input.split(delimiter);
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/public/src/js/init.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.element(document).ready(function() {
4 | // Init the app
5 | // angular.bootstrap(document, ['insight']);
6 | });
7 |
--------------------------------------------------------------------------------
/public/src/js/ios-imagefile-megapixel/megapix-image.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Mega pixel image rendering library for iOS6 Safari
3 | *
4 | * Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel),
5 | * which causes unexpected subsampling when drawing it in canvas.
6 | * By using this library, you can safely render the image with proper stretching.
7 | *
8 | * Copyright (c) 2012 Shinichi Tomita
9 | * Released under the MIT license
10 | */
11 | (function() {
12 |
13 | /**
14 | * Detect subsampling in loaded image.
15 | * In iOS, larger images than 2M pixels may be subsampled in rendering.
16 | */
17 | function detectSubsampling(img) {
18 | var iw = img.naturalWidth, ih = img.naturalHeight;
19 | if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image
20 | var canvas = document.createElement('canvas');
21 | canvas.width = canvas.height = 1;
22 | var ctx = canvas.getContext('2d');
23 | ctx.drawImage(img, -iw + 1, 0);
24 | // subsampled image becomes half smaller in rendering size.
25 | // check alpha channel value to confirm image is covering edge pixel or not.
26 | // if alpha value is 0 image is not covering, hence subsampled.
27 | return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
28 | } else {
29 | return false;
30 | }
31 | }
32 |
33 | /**
34 | * Detecting vertical squash in loaded image.
35 | * Fixes a bug which squash image vertically while drawing into canvas for some images.
36 | */
37 | function detectVerticalSquash(img, iw, ih) {
38 | var canvas = document.createElement('canvas');
39 | canvas.width = 1;
40 | canvas.height = ih;
41 | var ctx = canvas.getContext('2d');
42 | ctx.drawImage(img, 0, 0);
43 | var data = ctx.getImageData(0, 0, 1, ih).data;
44 | // search image edge pixel position in case it is squashed vertically.
45 | var sy = 0;
46 | var ey = ih;
47 | var py = ih;
48 | while (py > sy) {
49 | var alpha = data[(py - 1) * 4 + 3];
50 | if (alpha === 0) {
51 | ey = py;
52 | } else {
53 | sy = py;
54 | }
55 | py = (ey + sy) >> 1;
56 | }
57 | var ratio = (py / ih);
58 | return (ratio===0)?1:ratio;
59 | }
60 |
61 | /**
62 | * Rendering image element (with resizing) and get its data URL
63 | */
64 | function renderImageToDataURL(img, options, doSquash) {
65 | var canvas = document.createElement('canvas');
66 | renderImageToCanvas(img, canvas, options, doSquash);
67 | return canvas.toDataURL("image/jpeg", options.quality || 0.8);
68 | }
69 |
70 | /**
71 | * Rendering image element (with resizing) into the canvas element
72 | */
73 | function renderImageToCanvas(img, canvas, options, doSquash) {
74 | var iw = img.naturalWidth, ih = img.naturalHeight;
75 | var width = options.width, height = options.height;
76 | var ctx = canvas.getContext('2d');
77 | ctx.save();
78 | transformCoordinate(canvas, width, height, options.orientation);
79 | var subsampled = detectSubsampling(img);
80 | if (subsampled) {
81 | iw /= 2;
82 | ih /= 2;
83 | }
84 | var d = 1024; // size of tiling canvas
85 | var tmpCanvas = document.createElement('canvas');
86 | tmpCanvas.width = tmpCanvas.height = d;
87 | var tmpCtx = tmpCanvas.getContext('2d');
88 | var vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1;
89 | var dw = Math.ceil(d * width / iw);
90 | var dh = Math.ceil(d * height / ih / vertSquashRatio);
91 | var sy = 0;
92 | var dy = 0;
93 | while (sy < ih) {
94 | var sx = 0;
95 | var dx = 0;
96 | while (sx < iw) {
97 | tmpCtx.clearRect(0, 0, d, d);
98 | tmpCtx.drawImage(img, -sx, -sy);
99 | ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
100 | sx += d;
101 | dx += dw;
102 | }
103 | sy += d;
104 | dy += dh;
105 | }
106 | ctx.restore();
107 | tmpCanvas = tmpCtx = null;
108 | }
109 |
110 | /**
111 | * Transform canvas coordination according to specified frame size and orientation
112 | * Orientation value is from EXIF tag
113 | */
114 | function transformCoordinate(canvas, width, height, orientation) {
115 | switch (orientation) {
116 | case 5:
117 | case 6:
118 | case 7:
119 | case 8:
120 | canvas.width = height;
121 | canvas.height = width;
122 | break;
123 | default:
124 | canvas.width = width;
125 | canvas.height = height;
126 | }
127 | var ctx = canvas.getContext('2d');
128 | switch (orientation) {
129 | case 2:
130 | // horizontal flip
131 | ctx.translate(width, 0);
132 | ctx.scale(-1, 1);
133 | break;
134 | case 3:
135 | // 180 rotate left
136 | ctx.translate(width, height);
137 | ctx.rotate(Math.PI);
138 | break;
139 | case 4:
140 | // vertical flip
141 | ctx.translate(0, height);
142 | ctx.scale(1, -1);
143 | break;
144 | case 5:
145 | // vertical flip + 90 rotate right
146 | ctx.rotate(0.5 * Math.PI);
147 | ctx.scale(1, -1);
148 | break;
149 | case 6:
150 | // 90 rotate right
151 | ctx.rotate(0.5 * Math.PI);
152 | ctx.translate(0, -height);
153 | break;
154 | case 7:
155 | // horizontal flip + 90 rotate right
156 | ctx.rotate(0.5 * Math.PI);
157 | ctx.translate(width, -height);
158 | ctx.scale(-1, 1);
159 | break;
160 | case 8:
161 | // 90 rotate left
162 | ctx.rotate(-0.5 * Math.PI);
163 | ctx.translate(-width, 0);
164 | break;
165 | default:
166 | break;
167 | }
168 | }
169 |
170 |
171 | /**
172 | * MegaPixImage class
173 | */
174 | function MegaPixImage(srcImage) {
175 | if (window.Blob && srcImage instanceof Blob) {
176 | var img = new Image();
177 | var URL = window.URL && window.URL.createObjectURL ? window.URL :
178 | window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :
179 | null;
180 | if (!URL) { throw Error("No createObjectURL function found to create blob url"); }
181 | img.src = URL.createObjectURL(srcImage);
182 | this.blob = srcImage;
183 | srcImage = img;
184 | }
185 | if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
186 | var _this = this;
187 | srcImage.onload = function() {
188 | var listeners = _this.imageLoadListeners;
189 | if (listeners) {
190 | _this.imageLoadListeners = null;
191 | for (var i=0, len=listeners.length; i maxWidth) {
224 | width = maxWidth;
225 | height = (imgHeight * width / imgWidth) << 0;
226 | }
227 | if (maxHeight && height > maxHeight) {
228 | height = maxHeight;
229 | width = (imgWidth * height / imgHeight) << 0;
230 | }
231 | var opt = { width : width, height : height };
232 | for (var k in options) opt[k] = options[k];
233 |
234 | var tagName = target.tagName.toLowerCase();
235 | if (tagName === 'img') {
236 | target.src = renderImageToDataURL(this.srcImage, opt, doSquash);
237 | } else if (tagName === 'canvas') {
238 | renderImageToCanvas(this.srcImage, target, opt, doSquash);
239 | }
240 | if (typeof this.onrender === 'function') {
241 | this.onrender(target);
242 | }
243 | };
244 |
245 | /**
246 | * Export class to global
247 | */
248 | if (typeof define === 'function' && define.amd) {
249 | define([], function() { return MegaPixImage; }); // for AMD loader
250 | } else {
251 | this.MegaPixImage = MegaPixImage;
252 | }
253 |
254 | })();
255 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/alignpat.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function AlignmentPattern(posX, posY, estimatedModuleSize)
27 | {
28 | this.x=posX;
29 | this.y=posY;
30 | this.count = 1;
31 | this.estimatedModuleSize = estimatedModuleSize;
32 |
33 | this.__defineGetter__("EstimatedModuleSize", function()
34 | {
35 | return this.estimatedModuleSize;
36 | });
37 | this.__defineGetter__("Count", function()
38 | {
39 | return this.count;
40 | });
41 | this.__defineGetter__("X", function()
42 | {
43 | return Math.floor(this.x);
44 | });
45 | this.__defineGetter__("Y", function()
46 | {
47 | return Math.floor(this.y);
48 | });
49 | this.incrementCount = function()
50 | {
51 | this.count++;
52 | }
53 | this.aboutEquals=function( moduleSize, i, j)
54 | {
55 | if (Math.abs(i - this.y) <= moduleSize && Math.abs(j - this.x) <= moduleSize)
56 | {
57 | var moduleSizeDiff = Math.abs(moduleSize - this.estimatedModuleSize);
58 | return moduleSizeDiff <= 1.0 || moduleSizeDiff / this.estimatedModuleSize <= 1.0;
59 | }
60 | return false;
61 | }
62 |
63 | }
64 |
65 | function AlignmentPatternFinder( image, startX, startY, width, height, moduleSize, resultPointCallback)
66 | {
67 | this.image = image;
68 | this.possibleCenters = new Array();
69 | this.startX = startX;
70 | this.startY = startY;
71 | this.width = width;
72 | this.height = height;
73 | this.moduleSize = moduleSize;
74 | this.crossCheckStateCount = new Array(0,0,0);
75 | this.resultPointCallback = resultPointCallback;
76 |
77 | this.centerFromEnd=function(stateCount, end)
78 | {
79 | return (end - stateCount[2]) - stateCount[1] / 2.0;
80 | }
81 | this.foundPatternCross = function(stateCount)
82 | {
83 | var moduleSize = this.moduleSize;
84 | var maxVariance = moduleSize / 2.0;
85 | for (var i = 0; i < 3; i++)
86 | {
87 | if (Math.abs(moduleSize - stateCount[i]) >= maxVariance)
88 | {
89 | return false;
90 | }
91 | }
92 | return true;
93 | }
94 |
95 | this.crossCheckVertical=function( startI, centerJ, maxCount, originalStateCountTotal)
96 | {
97 | var image = this.image;
98 |
99 | var maxI = qrcode.height;
100 | var stateCount = this.crossCheckStateCount;
101 | stateCount[0] = 0;
102 | stateCount[1] = 0;
103 | stateCount[2] = 0;
104 |
105 | // Start counting up from center
106 | var i = startI;
107 | while (i >= 0 && image[centerJ + i*qrcode.width] && stateCount[1] <= maxCount)
108 | {
109 | stateCount[1]++;
110 | i--;
111 | }
112 | // If already too many modules in this state or ran off the edge:
113 | if (i < 0 || stateCount[1] > maxCount)
114 | {
115 | return NaN;
116 | }
117 | while (i >= 0 && !image[centerJ + i*qrcode.width] && stateCount[0] <= maxCount)
118 | {
119 | stateCount[0]++;
120 | i--;
121 | }
122 | if (stateCount[0] > maxCount)
123 | {
124 | return NaN;
125 | }
126 |
127 | // Now also count down from center
128 | i = startI + 1;
129 | while (i < maxI && image[centerJ + i*qrcode.width] && stateCount[1] <= maxCount)
130 | {
131 | stateCount[1]++;
132 | i++;
133 | }
134 | if (i == maxI || stateCount[1] > maxCount)
135 | {
136 | return NaN;
137 | }
138 | while (i < maxI && !image[centerJ + i*qrcode.width] && stateCount[2] <= maxCount)
139 | {
140 | stateCount[2]++;
141 | i++;
142 | }
143 | if (stateCount[2] > maxCount)
144 | {
145 | return NaN;
146 | }
147 |
148 | var stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
149 | if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal)
150 | {
151 | return NaN;
152 | }
153 |
154 | return this.foundPatternCross(stateCount)?this.centerFromEnd(stateCount, i):NaN;
155 | }
156 |
157 | this.handlePossibleCenter=function( stateCount, i, j)
158 | {
159 | var stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
160 | var centerJ = this.centerFromEnd(stateCount, j);
161 | var centerI = this.crossCheckVertical(i, Math.floor (centerJ), 2 * stateCount[1], stateCountTotal);
162 | if (!isNaN(centerI))
163 | {
164 | var estimatedModuleSize = (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0;
165 | var max = this.possibleCenters.length;
166 | for (var index = 0; index < max; index++)
167 | {
168 | var center = this.possibleCenters[index];
169 | // Look for about the same center and module size:
170 | if (center.aboutEquals(estimatedModuleSize, centerI, centerJ))
171 | {
172 | return new AlignmentPattern(centerJ, centerI, estimatedModuleSize);
173 | }
174 | }
175 | // Hadn't found this before; save it
176 | var point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize);
177 | this.possibleCenters.push(point);
178 | if (this.resultPointCallback != null)
179 | {
180 | this.resultPointCallback.foundPossibleResultPoint(point);
181 | }
182 | }
183 | return null;
184 | }
185 |
186 | this.find = function()
187 | {
188 | var startX = this.startX;
189 | var height = this.height;
190 | var maxJ = startX + width;
191 | var middleI = startY + (height >> 1);
192 | // We are looking for black/white/black modules in 1:1:1 ratio;
193 | // this tracks the number of black/white/black modules seen so far
194 | var stateCount = new Array(0,0,0);
195 | for (var iGen = 0; iGen < height; iGen++)
196 | {
197 | // Search from middle outwards
198 | var i = middleI + ((iGen & 0x01) == 0?((iGen + 1) >> 1):- ((iGen + 1) >> 1));
199 | stateCount[0] = 0;
200 | stateCount[1] = 0;
201 | stateCount[2] = 0;
202 | var j = startX;
203 | // Burn off leading white pixels before anything else; if we start in the middle of
204 | // a white run, it doesn't make sense to count its length, since we don't know if the
205 | // white run continued to the left of the start point
206 | while (j < maxJ && !image[j + qrcode.width* i])
207 | {
208 | j++;
209 | }
210 | var currentState = 0;
211 | while (j < maxJ)
212 | {
213 | if (image[j + i*qrcode.width])
214 | {
215 | // Black pixel
216 | if (currentState == 1)
217 | {
218 | // Counting black pixels
219 | stateCount[currentState]++;
220 | }
221 | else
222 | {
223 | // Counting white pixels
224 | if (currentState == 2)
225 | {
226 | // A winner?
227 | if (this.foundPatternCross(stateCount))
228 | {
229 | // Yes
230 | var confirmed = this.handlePossibleCenter(stateCount, i, j);
231 | if (confirmed != null)
232 | {
233 | return confirmed;
234 | }
235 | }
236 | stateCount[0] = stateCount[2];
237 | stateCount[1] = 1;
238 | stateCount[2] = 0;
239 | currentState = 1;
240 | }
241 | else
242 | {
243 | stateCount[++currentState]++;
244 | }
245 | }
246 | }
247 | else
248 | {
249 | // White pixel
250 | if (currentState == 1)
251 | {
252 | // Counting black pixels
253 | currentState++;
254 | }
255 | stateCount[currentState]++;
256 | }
257 | j++;
258 | }
259 | if (this.foundPatternCross(stateCount))
260 | {
261 | var confirmed = this.handlePossibleCenter(stateCount, i, maxJ);
262 | if (confirmed != null)
263 | {
264 | return confirmed;
265 | }
266 | }
267 | }
268 |
269 | // Hmm, nothing we saw was observed and confirmed twice. If we had
270 | // any guess at all, return it.
271 | if (!(this.possibleCenters.length == 0))
272 | {
273 | return this.possibleCenters[0];
274 | }
275 |
276 | throw "Couldn't find enough alignment patterns";
277 | }
278 |
279 | }
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/bitmat.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function BitMatrix( width, height)
27 | {
28 | if(!height)
29 | height=width;
30 | if (width < 1 || height < 1)
31 | {
32 | throw "Both dimensions must be greater than 0";
33 | }
34 | this.width = width;
35 | this.height = height;
36 | var rowSize = width >> 5;
37 | if ((width & 0x1f) != 0)
38 | {
39 | rowSize++;
40 | }
41 | this.rowSize = rowSize;
42 | this.bits = new Array(rowSize * height);
43 | for(var i=0;i> 5);
66 | return ((URShift(this.bits[offset], (x & 0x1f))) & 1) != 0;
67 | }
68 | this.set_Renamed=function( x, y)
69 | {
70 | var offset = y * this.rowSize + (x >> 5);
71 | this.bits[offset] |= 1 << (x & 0x1f);
72 | }
73 | this.flip=function( x, y)
74 | {
75 | var offset = y * this.rowSize + (x >> 5);
76 | this.bits[offset] ^= 1 << (x & 0x1f);
77 | }
78 | this.clear=function()
79 | {
80 | var max = this.bits.length;
81 | for (var i = 0; i < max; i++)
82 | {
83 | this.bits[i] = 0;
84 | }
85 | }
86 | this.setRegion=function( left, top, width, height)
87 | {
88 | if (top < 0 || left < 0)
89 | {
90 | throw "Left and top must be nonnegative";
91 | }
92 | if (height < 1 || width < 1)
93 | {
94 | throw "Height and width must be at least 1";
95 | }
96 | var right = left + width;
97 | var bottom = top + height;
98 | if (bottom > this.height || right > this.width)
99 | {
100 | throw "The region must fit inside the matrix";
101 | }
102 | for (var y = top; y < bottom; y++)
103 | {
104 | var offset = y * this.rowSize;
105 | for (var x = left; x < right; x++)
106 | {
107 | this.bits[offset + (x >> 5)] |= 1 << (x & 0x1f);
108 | }
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/bmparser.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function BitMatrixParser(bitMatrix)
27 | {
28 | var dimension = bitMatrix.Dimension;
29 | if (dimension < 21 || (dimension & 0x03) != 1)
30 | {
31 | throw "Error BitMatrixParser";
32 | }
33 | this.bitMatrix = bitMatrix;
34 | this.parsedVersion = null;
35 | this.parsedFormatInfo = null;
36 |
37 | this.copyBit=function( i, j, versionBits)
38 | {
39 | return this.bitMatrix.get_Renamed(i, j)?(versionBits << 1) | 0x1:versionBits << 1;
40 | }
41 |
42 | this.readFormatInformation=function()
43 | {
44 | if (this.parsedFormatInfo != null)
45 | {
46 | return this.parsedFormatInfo;
47 | }
48 |
49 | // Read top-left format info bits
50 | var formatInfoBits = 0;
51 | for (var i = 0; i < 6; i++)
52 | {
53 | formatInfoBits = this.copyBit(i, 8, formatInfoBits);
54 | }
55 | // .. and skip a bit in the timing pattern ...
56 | formatInfoBits = this.copyBit(7, 8, formatInfoBits);
57 | formatInfoBits = this.copyBit(8, 8, formatInfoBits);
58 | formatInfoBits = this.copyBit(8, 7, formatInfoBits);
59 | // .. and skip a bit in the timing pattern ...
60 | for (var j = 5; j >= 0; j--)
61 | {
62 | formatInfoBits = this.copyBit(8, j, formatInfoBits);
63 | }
64 |
65 | this.parsedFormatInfo = FormatInformation.decodeFormatInformation(formatInfoBits);
66 | if (this.parsedFormatInfo != null)
67 | {
68 | return this.parsedFormatInfo;
69 | }
70 |
71 | // Hmm, failed. Try the top-right/bottom-left pattern
72 | var dimension = this.bitMatrix.Dimension;
73 | formatInfoBits = 0;
74 | var iMin = dimension - 8;
75 | for (var i = dimension - 1; i >= iMin; i--)
76 | {
77 | formatInfoBits = this.copyBit(i, 8, formatInfoBits);
78 | }
79 | for (var j = dimension - 7; j < dimension; j++)
80 | {
81 | formatInfoBits = this.copyBit(8, j, formatInfoBits);
82 | }
83 |
84 | this.parsedFormatInfo = FormatInformation.decodeFormatInformation(formatInfoBits);
85 | if (this.parsedFormatInfo != null)
86 | {
87 | return this.parsedFormatInfo;
88 | }
89 | throw "Error readFormatInformation";
90 | }
91 | this.readVersion=function()
92 | {
93 |
94 | if (this.parsedVersion != null)
95 | {
96 | return this.parsedVersion;
97 | }
98 |
99 | var dimension = this.bitMatrix.Dimension;
100 |
101 | var provisionalVersion = (dimension - 17) >> 2;
102 | if (provisionalVersion <= 6)
103 | {
104 | return Version.getVersionForNumber(provisionalVersion);
105 | }
106 |
107 | // Read top-right version info: 3 wide by 6 tall
108 | var versionBits = 0;
109 | var ijMin = dimension - 11;
110 | for (var j = 5; j >= 0; j--)
111 | {
112 | for (var i = dimension - 9; i >= ijMin; i--)
113 | {
114 | versionBits = this.copyBit(i, j, versionBits);
115 | }
116 | }
117 |
118 | this.parsedVersion = Version.decodeVersionInformation(versionBits);
119 | if (this.parsedVersion != null && this.parsedVersion.DimensionForVersion == dimension)
120 | {
121 | return this.parsedVersion;
122 | }
123 |
124 | // Hmm, failed. Try bottom left: 6 wide by 3 tall
125 | versionBits = 0;
126 | for (var i = 5; i >= 0; i--)
127 | {
128 | for (var j = dimension - 9; j >= ijMin; j--)
129 | {
130 | versionBits = this.copyBit(i, j, versionBits);
131 | }
132 | }
133 |
134 | this.parsedVersion = Version.decodeVersionInformation(versionBits);
135 | if (this.parsedVersion != null && this.parsedVersion.DimensionForVersion == dimension)
136 | {
137 | return this.parsedVersion;
138 | }
139 | throw "Error readVersion";
140 | }
141 | this.readCodewords=function()
142 | {
143 |
144 | var formatInfo = this.readFormatInformation();
145 | var version = this.readVersion();
146 |
147 | // Get the data mask for the format used in this QR Code. This will exclude
148 | // some bits from reading as we wind through the bit matrix.
149 | var dataMask = DataMask.forReference( formatInfo.DataMask);
150 | var dimension = this.bitMatrix.Dimension;
151 | dataMask.unmaskBitMatrix(this.bitMatrix, dimension);
152 |
153 | var functionPattern = version.buildFunctionPattern();
154 |
155 | var readingUp = true;
156 | var result = new Array(version.TotalCodewords);
157 | var resultOffset = 0;
158 | var currentByte = 0;
159 | var bitsRead = 0;
160 | // Read columns in pairs, from right to left
161 | for (var j = dimension - 1; j > 0; j -= 2)
162 | {
163 | if (j == 6)
164 | {
165 | // Skip whole column with vertical alignment pattern;
166 | // saves time and makes the other code proceed more cleanly
167 | j--;
168 | }
169 | // Read alternatingly from bottom to top then top to bottom
170 | for (var count = 0; count < dimension; count++)
171 | {
172 | var i = readingUp?dimension - 1 - count:count;
173 | for (var col = 0; col < 2; col++)
174 | {
175 | // Ignore bits covered by the function pattern
176 | if (!functionPattern.get_Renamed(j - col, i))
177 | {
178 | // Read a bit
179 | bitsRead++;
180 | currentByte <<= 1;
181 | if (this.bitMatrix.get_Renamed(j - col, i))
182 | {
183 | currentByte |= 1;
184 | }
185 | // If we've made a whole byte, save it off
186 | if (bitsRead == 8)
187 | {
188 | result[resultOffset++] = currentByte;
189 | bitsRead = 0;
190 | currentByte = 0;
191 | }
192 | }
193 | }
194 | }
195 | readingUp ^= true; // readingUp = !readingUp; // switch directions
196 | }
197 | if (resultOffset != version.TotalCodewords)
198 | {
199 | throw "Error readCodewords";
200 | }
201 | return result;
202 | }
203 | }
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/datablock.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function DataBlock(numDataCodewords, codewords)
27 | {
28 | this.numDataCodewords = numDataCodewords;
29 | this.codewords = codewords;
30 |
31 | this.__defineGetter__("NumDataCodewords", function()
32 | {
33 | return this.numDataCodewords;
34 | });
35 | this.__defineGetter__("Codewords", function()
36 | {
37 | return this.codewords;
38 | });
39 | }
40 |
41 | DataBlock.getDataBlocks=function(rawCodewords, version, ecLevel)
42 | {
43 |
44 | if (rawCodewords.length != version.TotalCodewords)
45 | {
46 | throw "ArgumentException";
47 | }
48 |
49 | // Figure out the number and size of data blocks used by this version and
50 | // error correction level
51 | var ecBlocks = version.getECBlocksForLevel(ecLevel);
52 |
53 | // First count the total number of data blocks
54 | var totalBlocks = 0;
55 | var ecBlockArray = ecBlocks.getECBlocks();
56 | for (var i = 0; i < ecBlockArray.length; i++)
57 | {
58 | totalBlocks += ecBlockArray[i].Count;
59 | }
60 |
61 | // Now establish DataBlocks of the appropriate size and number of data codewords
62 | var result = new Array(totalBlocks);
63 | var numResultBlocks = 0;
64 | for (var j = 0; j < ecBlockArray.length; j++)
65 | {
66 | var ecBlock = ecBlockArray[j];
67 | for (var i = 0; i < ecBlock.Count; i++)
68 | {
69 | var numDataCodewords = ecBlock.DataCodewords;
70 | var numBlockCodewords = ecBlocks.ECCodewordsPerBlock + numDataCodewords;
71 | result[numResultBlocks++] = new DataBlock(numDataCodewords, new Array(numBlockCodewords));
72 | }
73 | }
74 |
75 | // All blocks have the same amount of data, except that the last n
76 | // (where n may be 0) have 1 more byte. Figure out where these start.
77 | var shorterBlocksTotalCodewords = result[0].codewords.length;
78 | var longerBlocksStartAt = result.length - 1;
79 | while (longerBlocksStartAt >= 0)
80 | {
81 | var numCodewords = result[longerBlocksStartAt].codewords.length;
82 | if (numCodewords == shorterBlocksTotalCodewords)
83 | {
84 | break;
85 | }
86 | longerBlocksStartAt--;
87 | }
88 | longerBlocksStartAt++;
89 |
90 | var shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ECCodewordsPerBlock;
91 | // The last elements of result may be 1 element longer;
92 | // first fill out as many elements as all of them have
93 | var rawCodewordsOffset = 0;
94 | for (var i = 0; i < shorterBlocksNumDataCodewords; i++)
95 | {
96 | for (var j = 0; j < numResultBlocks; j++)
97 | {
98 | result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
99 | }
100 | }
101 | // Fill out the last data block in the longer ones
102 | for (var j = longerBlocksStartAt; j < numResultBlocks; j++)
103 | {
104 | result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
105 | }
106 | // Now add in error correction blocks
107 | var max = result[0].codewords.length;
108 | for (var i = shorterBlocksNumDataCodewords; i < max; i++)
109 | {
110 | for (var j = 0; j < numResultBlocks; j++)
111 | {
112 | var iOffset = j < longerBlocksStartAt?i:i + 1;
113 | result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
114 | }
115 | }
116 | return result;
117 | }
118 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/databr.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function QRCodeDataBlockReader(blocks, version, numErrorCorrectionCode)
27 | {
28 | this.blockPointer = 0;
29 | this.bitPointer = 7;
30 | this.dataLength = 0;
31 | this.blocks = blocks;
32 | this.numErrorCorrectionCode = numErrorCorrectionCode;
33 | if (version <= 9)
34 | this.dataLengthMode = 0;
35 | else if (version >= 10 && version <= 26)
36 | this.dataLengthMode = 1;
37 | else if (version >= 27 && version <= 40)
38 | this.dataLengthMode = 2;
39 |
40 | this.getNextBits = function( numBits)
41 | {
42 | var bits = 0;
43 | if (numBits < this.bitPointer + 1)
44 | {
45 | // next word fits into current data block
46 | var mask = 0;
47 | for (var i = 0; i < numBits; i++)
48 | {
49 | mask += (1 << i);
50 | }
51 | mask <<= (this.bitPointer - numBits + 1);
52 |
53 | bits = (this.blocks[this.blockPointer] & mask) >> (this.bitPointer - numBits + 1);
54 | this.bitPointer -= numBits;
55 | return bits;
56 | }
57 | else if (numBits < this.bitPointer + 1 + 8)
58 | {
59 | // next word crosses 2 data blocks
60 | var mask1 = 0;
61 | for (var i = 0; i < this.bitPointer + 1; i++)
62 | {
63 | mask1 += (1 << i);
64 | }
65 | bits = (this.blocks[this.blockPointer] & mask1) << (numBits - (this.bitPointer + 1));
66 | this.blockPointer++;
67 | bits += ((this.blocks[this.blockPointer]) >> (8 - (numBits - (this.bitPointer + 1))));
68 |
69 | this.bitPointer = this.bitPointer - numBits % 8;
70 | if (this.bitPointer < 0)
71 | {
72 | this.bitPointer = 8 + this.bitPointer;
73 | }
74 | return bits;
75 | }
76 | else if (numBits < this.bitPointer + 1 + 16)
77 | {
78 | // next word crosses 3 data blocks
79 | var mask1 = 0; // mask of first block
80 | var mask3 = 0; // mask of 3rd block
81 | //bitPointer + 1 : number of bits of the 1st block
82 | //8 : number of the 2nd block (note that use already 8bits because next word uses 3 data blocks)
83 | //numBits - (bitPointer + 1 + 8) : number of bits of the 3rd block
84 | for (var i = 0; i < this.bitPointer + 1; i++)
85 | {
86 | mask1 += (1 << i);
87 | }
88 | var bitsFirstBlock = (this.blocks[this.blockPointer] & mask1) << (numBits - (this.bitPointer + 1));
89 | this.blockPointer++;
90 |
91 | var bitsSecondBlock = this.blocks[this.blockPointer] << (numBits - (this.bitPointer + 1 + 8));
92 | this.blockPointer++;
93 |
94 | for (var i = 0; i < numBits - (this.bitPointer + 1 + 8); i++)
95 | {
96 | mask3 += (1 << i);
97 | }
98 | mask3 <<= 8 - (numBits - (this.bitPointer + 1 + 8));
99 | var bitsThirdBlock = (this.blocks[this.blockPointer] & mask3) >> (8 - (numBits - (this.bitPointer + 1 + 8)));
100 |
101 | bits = bitsFirstBlock + bitsSecondBlock + bitsThirdBlock;
102 | this.bitPointer = this.bitPointer - (numBits - 8) % 8;
103 | if (this.bitPointer < 0)
104 | {
105 | this.bitPointer = 8 + this.bitPointer;
106 | }
107 | return bits;
108 | }
109 | else
110 | {
111 | return 0;
112 | }
113 | }
114 | this.NextMode=function()
115 | {
116 | if ((this.blockPointer > this.blocks.length - this.numErrorCorrectionCode - 2))
117 | return 0;
118 | else
119 | return this.getNextBits(4);
120 | }
121 | this.getDataLength=function( modeIndicator)
122 | {
123 | var index = 0;
124 | while (true)
125 | {
126 | if ((modeIndicator >> index) == 1)
127 | break;
128 | index++;
129 | }
130 |
131 | return this.getNextBits(qrcode.sizeOfDataLengthInfo[this.dataLengthMode][index]);
132 | }
133 | this.getRomanAndFigureString=function( dataLength)
134 | {
135 | var length = dataLength;
136 | var intData = 0;
137 | var strData = "";
138 | var tableRomanAndFigure = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':');
139 | do
140 | {
141 | if (length > 1)
142 | {
143 | intData = this.getNextBits(11);
144 | var firstLetter = Math.floor(intData / 45);
145 | var secondLetter = intData % 45;
146 | strData += tableRomanAndFigure[firstLetter];
147 | strData += tableRomanAndFigure[secondLetter];
148 | length -= 2;
149 | }
150 | else if (length == 1)
151 | {
152 | intData = this.getNextBits(6);
153 | strData += tableRomanAndFigure[intData];
154 | length -= 1;
155 | }
156 | }
157 | while (length > 0);
158 |
159 | return strData;
160 | }
161 | this.getFigureString=function( dataLength)
162 | {
163 | var length = dataLength;
164 | var intData = 0;
165 | var strData = "";
166 | do
167 | {
168 | if (length >= 3)
169 | {
170 | intData = this.getNextBits(10);
171 | if (intData < 100)
172 | strData += "0";
173 | if (intData < 10)
174 | strData += "0";
175 | length -= 3;
176 | }
177 | else if (length == 2)
178 | {
179 | intData = this.getNextBits(7);
180 | if (intData < 10)
181 | strData += "0";
182 | length -= 2;
183 | }
184 | else if (length == 1)
185 | {
186 | intData = this.getNextBits(4);
187 | length -= 1;
188 | }
189 | strData += intData;
190 | }
191 | while (length > 0);
192 |
193 | return strData;
194 | }
195 | this.get8bitByteArray=function( dataLength)
196 | {
197 | var length = dataLength;
198 | var intData = 0;
199 | var output = new Array();
200 |
201 | do
202 | {
203 | intData = this.getNextBits(8);
204 | output.push( intData);
205 | length--;
206 | }
207 | while (length > 0);
208 | return output;
209 | }
210 | this.getKanjiString=function( dataLength)
211 | {
212 | var length = dataLength;
213 | var intData = 0;
214 | var unicodeString = "";
215 | do
216 | {
217 | intData = getNextBits(13);
218 | var lowerByte = intData % 0xC0;
219 | var higherByte = intData / 0xC0;
220 |
221 | var tempWord = (higherByte << 8) + lowerByte;
222 | var shiftjisWord = 0;
223 | if (tempWord + 0x8140 <= 0x9FFC)
224 | {
225 | // between 8140 - 9FFC on Shift_JIS character set
226 | shiftjisWord = tempWord + 0x8140;
227 | }
228 | else
229 | {
230 | // between E040 - EBBF on Shift_JIS character set
231 | shiftjisWord = tempWord + 0xC140;
232 | }
233 |
234 | //var tempByte = new Array(0,0);
235 | //tempByte[0] = (sbyte) (shiftjisWord >> 8);
236 | //tempByte[1] = (sbyte) (shiftjisWord & 0xFF);
237 | //unicodeString += new String(SystemUtils.ToCharArray(SystemUtils.ToByteArray(tempByte)));
238 | unicodeString += String.fromCharCode(shiftjisWord);
239 | length--;
240 | }
241 | while (length > 0);
242 |
243 |
244 | return unicodeString;
245 | }
246 |
247 | this.__defineGetter__("DataByte", function()
248 | {
249 | var output = new Array();
250 | var MODE_NUMBER = 1;
251 | var MODE_ROMAN_AND_NUMBER = 2;
252 | var MODE_8BIT_BYTE = 4;
253 | var MODE_KANJI = 8;
254 | do
255 | {
256 | var mode = this.NextMode();
257 | //canvas.println("mode: " + mode);
258 | if (mode == 0)
259 | {
260 | if (output.length > 0)
261 | break;
262 | else
263 | throw "Empty data block";
264 | }
265 | //if (mode != 1 && mode != 2 && mode != 4 && mode != 8)
266 | // break;
267 | //}
268 | if (mode != MODE_NUMBER && mode != MODE_ROMAN_AND_NUMBER && mode != MODE_8BIT_BYTE && mode != MODE_KANJI)
269 | {
270 | /* canvas.println("Invalid mode: " + mode);
271 | mode = guessMode(mode);
272 | canvas.println("Guessed mode: " + mode); */
273 | throw "Invalid mode: " + mode + " in (block:" + this.blockPointer + " bit:" + this.bitPointer + ")";
274 | }
275 | dataLength = this.getDataLength(mode);
276 | if (dataLength < 1)
277 | throw "Invalid data length: " + dataLength;
278 | //canvas.println("length: " + dataLength);
279 | switch (mode)
280 | {
281 |
282 | case MODE_NUMBER:
283 | //canvas.println("Mode: Figure");
284 | var temp_str = this.getFigureString(dataLength);
285 | var ta = new Array(temp_str.length);
286 | for(var j=0;j 7)
31 | {
32 | throw "System.ArgumentException";
33 | }
34 | return DataMask.DATA_MASKS[reference];
35 | }
36 |
37 | function DataMask000()
38 | {
39 | this.unmaskBitMatrix=function(bits, dimension)
40 | {
41 | for (var i = 0; i < dimension; i++)
42 | {
43 | for (var j = 0; j < dimension; j++)
44 | {
45 | if (this.isMasked(i, j))
46 | {
47 | bits.flip(j, i);
48 | }
49 | }
50 | }
51 | }
52 | this.isMasked=function( i, j)
53 | {
54 | return ((i + j) & 0x01) == 0;
55 | }
56 | }
57 |
58 | function DataMask001()
59 | {
60 | this.unmaskBitMatrix=function(bits, dimension)
61 | {
62 | for (var i = 0; i < dimension; i++)
63 | {
64 | for (var j = 0; j < dimension; j++)
65 | {
66 | if (this.isMasked(i, j))
67 | {
68 | bits.flip(j, i);
69 | }
70 | }
71 | }
72 | }
73 | this.isMasked=function( i, j)
74 | {
75 | return (i & 0x01) == 0;
76 | }
77 | }
78 |
79 | function DataMask010()
80 | {
81 | this.unmaskBitMatrix=function(bits, dimension)
82 | {
83 | for (var i = 0; i < dimension; i++)
84 | {
85 | for (var j = 0; j < dimension; j++)
86 | {
87 | if (this.isMasked(i, j))
88 | {
89 | bits.flip(j, i);
90 | }
91 | }
92 | }
93 | }
94 | this.isMasked=function( i, j)
95 | {
96 | return j % 3 == 0;
97 | }
98 | }
99 |
100 | function DataMask011()
101 | {
102 | this.unmaskBitMatrix=function(bits, dimension)
103 | {
104 | for (var i = 0; i < dimension; i++)
105 | {
106 | for (var j = 0; j < dimension; j++)
107 | {
108 | if (this.isMasked(i, j))
109 | {
110 | bits.flip(j, i);
111 | }
112 | }
113 | }
114 | }
115 | this.isMasked=function( i, j)
116 | {
117 | return (i + j) % 3 == 0;
118 | }
119 | }
120 |
121 | function DataMask100()
122 | {
123 | this.unmaskBitMatrix=function(bits, dimension)
124 | {
125 | for (var i = 0; i < dimension; i++)
126 | {
127 | for (var j = 0; j < dimension; j++)
128 | {
129 | if (this.isMasked(i, j))
130 | {
131 | bits.flip(j, i);
132 | }
133 | }
134 | }
135 | }
136 | this.isMasked=function( i, j)
137 | {
138 | return (((URShift(i, 1)) + (j / 3)) & 0x01) == 0;
139 | }
140 | }
141 |
142 | function DataMask101()
143 | {
144 | this.unmaskBitMatrix=function(bits, dimension)
145 | {
146 | for (var i = 0; i < dimension; i++)
147 | {
148 | for (var j = 0; j < dimension; j++)
149 | {
150 | if (this.isMasked(i, j))
151 | {
152 | bits.flip(j, i);
153 | }
154 | }
155 | }
156 | }
157 | this.isMasked=function( i, j)
158 | {
159 | var temp = i * j;
160 | return (temp & 0x01) + (temp % 3) == 0;
161 | }
162 | }
163 |
164 | function DataMask110()
165 | {
166 | this.unmaskBitMatrix=function(bits, dimension)
167 | {
168 | for (var i = 0; i < dimension; i++)
169 | {
170 | for (var j = 0; j < dimension; j++)
171 | {
172 | if (this.isMasked(i, j))
173 | {
174 | bits.flip(j, i);
175 | }
176 | }
177 | }
178 | }
179 | this.isMasked=function( i, j)
180 | {
181 | var temp = i * j;
182 | return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
183 | }
184 | }
185 | function DataMask111()
186 | {
187 | this.unmaskBitMatrix=function(bits, dimension)
188 | {
189 | for (var i = 0; i < dimension; i++)
190 | {
191 | for (var j = 0; j < dimension; j++)
192 | {
193 | if (this.isMasked(i, j))
194 | {
195 | bits.flip(j, i);
196 | }
197 | }
198 | }
199 | }
200 | this.isMasked=function( i, j)
201 | {
202 | return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
203 | }
204 | }
205 |
206 | DataMask.DATA_MASKS = new Array(new DataMask000(), new DataMask001(), new DataMask010(), new DataMask011(), new DataMask100(), new DataMask101(), new DataMask110(), new DataMask111());
207 |
208 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/decoder.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | Decoder={};
27 | Decoder.rsDecoder = new ReedSolomonDecoder(GF256.QR_CODE_FIELD);
28 |
29 | Decoder.correctErrors=function( codewordBytes, numDataCodewords)
30 | {
31 | var numCodewords = codewordBytes.length;
32 | // First read into an array of ints
33 | var codewordsInts = new Array(numCodewords);
34 | for (var i = 0; i < numCodewords; i++)
35 | {
36 | codewordsInts[i] = codewordBytes[i] & 0xFF;
37 | }
38 | var numECCodewords = codewordBytes.length - numDataCodewords;
39 | try
40 | {
41 | Decoder.rsDecoder.decode(codewordsInts, numECCodewords);
42 | //var corrector = new ReedSolomon(codewordsInts, numECCodewords);
43 | //corrector.correct();
44 | }
45 | catch ( rse)
46 | {
47 | throw rse;
48 | }
49 | // Copy back into array of bytes -- only need to worry about the bytes that were data
50 | // We don't care about errors in the error-correction codewords
51 | for (var i = 0; i < numDataCodewords; i++)
52 | {
53 | codewordBytes[i] = codewordsInts[i];
54 | }
55 | }
56 |
57 | Decoder.decode=function(bits)
58 | {
59 | var parser = new BitMatrixParser(bits);
60 | var version = parser.readVersion();
61 | var ecLevel = parser.readFormatInformation().ErrorCorrectionLevel;
62 |
63 | // Read codewords
64 | var codewords = parser.readCodewords();
65 |
66 | // Separate into data blocks
67 | var dataBlocks = DataBlock.getDataBlocks(codewords, version, ecLevel);
68 |
69 | // Count total number of data bytes
70 | var totalBytes = 0;
71 | for (var i = 0; i < dataBlocks.length; i++)
72 | {
73 | totalBytes += dataBlocks[i].NumDataCodewords;
74 | }
75 | var resultBytes = new Array(totalBytes);
76 | var resultOffset = 0;
77 |
78 | // Error-correct and copy data blocks together into a stream of bytes
79 | for (var j = 0; j < dataBlocks.length; j++)
80 | {
81 | var dataBlock = dataBlocks[j];
82 | var codewordBytes = dataBlock.Codewords;
83 | var numDataCodewords = dataBlock.NumDataCodewords;
84 | Decoder.correctErrors(codewordBytes, numDataCodewords);
85 | for (var i = 0; i < numDataCodewords; i++)
86 | {
87 | resultBytes[resultOffset++] = codewordBytes[i];
88 | }
89 | }
90 |
91 | // Decode the contents of that stream of bytes
92 | var reader = new QRCodeDataBlockReader(resultBytes, version.VersionNumber, ecLevel.Bits);
93 | return reader;
94 | //return DecodedBitStreamParser.decode(resultBytes, version, ecLevel);
95 | }
96 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/errorlevel.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function ErrorCorrectionLevel(ordinal, bits, name)
27 | {
28 | this.ordinal_Renamed_Field = ordinal;
29 | this.bits = bits;
30 | this.name = name;
31 | this.__defineGetter__("Bits", function()
32 | {
33 | return this.bits;
34 | });
35 | this.__defineGetter__("Name", function()
36 | {
37 | return this.name;
38 | });
39 | this.ordinal=function()
40 | {
41 | return this.ordinal_Renamed_Field;
42 | }
43 | }
44 |
45 | ErrorCorrectionLevel.forBits=function( bits)
46 | {
47 | if (bits < 0 || bits >= FOR_BITS.length)
48 | {
49 | throw "ArgumentException";
50 | }
51 | return FOR_BITS[bits];
52 | }
53 |
54 | var L = new ErrorCorrectionLevel(0, 0x01, "L");
55 | var M = new ErrorCorrectionLevel(1, 0x00, "M");
56 | var Q = new ErrorCorrectionLevel(2, 0x03, "Q");
57 | var H = new ErrorCorrectionLevel(3, 0x02, "H");
58 | var FOR_BITS = new Array( M, L, H, Q);
59 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/formatinf.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | var FORMAT_INFO_MASK_QR = 0x5412;
27 | var FORMAT_INFO_DECODE_LOOKUP = new Array(new Array(0x5412, 0x00), new Array(0x5125, 0x01), new Array(0x5E7C, 0x02), new Array(0x5B4B, 0x03), new Array(0x45F9, 0x04), new Array(0x40CE, 0x05), new Array(0x4F97, 0x06), new Array(0x4AA0, 0x07), new Array(0x77C4, 0x08), new Array(0x72F3, 0x09), new Array(0x7DAA, 0x0A), new Array(0x789D, 0x0B), new Array(0x662F, 0x0C), new Array(0x6318, 0x0D), new Array(0x6C41, 0x0E), new Array(0x6976, 0x0F), new Array(0x1689, 0x10), new Array(0x13BE, 0x11), new Array(0x1CE7, 0x12), new Array(0x19D0, 0x13), new Array(0x0762, 0x14), new Array(0x0255, 0x15), new Array(0x0D0C, 0x16), new Array(0x083B, 0x17), new Array(0x355F, 0x18), new Array(0x3068, 0x19), new Array(0x3F31, 0x1A), new Array(0x3A06, 0x1B), new Array(0x24B4, 0x1C), new Array(0x2183, 0x1D), new Array(0x2EDA, 0x1E), new Array(0x2BED, 0x1F));
28 | var BITS_SET_IN_HALF_BYTE = new Array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
29 |
30 |
31 | function FormatInformation(formatInfo)
32 | {
33 | this.errorCorrectionLevel = ErrorCorrectionLevel.forBits((formatInfo >> 3) & 0x03);
34 | this.dataMask = (formatInfo & 0x07);
35 |
36 | this.__defineGetter__("ErrorCorrectionLevel", function()
37 | {
38 | return this.errorCorrectionLevel;
39 | });
40 | this.__defineGetter__("DataMask", function()
41 | {
42 | return this.dataMask;
43 | });
44 | this.GetHashCode=function()
45 | {
46 | return (this.errorCorrectionLevel.ordinal() << 3) | dataMask;
47 | }
48 | this.Equals=function( o)
49 | {
50 | var other = o;
51 | return this.errorCorrectionLevel == other.errorCorrectionLevel && this.dataMask == other.dataMask;
52 | }
53 | }
54 |
55 | FormatInformation.numBitsDiffering=function( a, b)
56 | {
57 | a ^= b; // a now has a 1 bit exactly where its bit differs with b's
58 | // Count bits set quickly with a series of lookups:
59 | return BITS_SET_IN_HALF_BYTE[a & 0x0F] + BITS_SET_IN_HALF_BYTE[(URShift(a, 4) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 8) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 12) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 16) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 20) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 24) & 0x0F)] + BITS_SET_IN_HALF_BYTE[(URShift(a, 28) & 0x0F)];
60 | }
61 |
62 | FormatInformation.decodeFormatInformation=function( maskedFormatInfo)
63 | {
64 | var formatInfo = FormatInformation.doDecodeFormatInformation(maskedFormatInfo);
65 | if (formatInfo != null)
66 | {
67 | return formatInfo;
68 | }
69 | // Should return null, but, some QR codes apparently
70 | // do not mask this info. Try again by actually masking the pattern
71 | // first
72 | return FormatInformation.doDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR);
73 | }
74 | FormatInformation.doDecodeFormatInformation=function( maskedFormatInfo)
75 | {
76 | // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
77 | var bestDifference = 0xffffffff;
78 | var bestFormatInfo = 0;
79 | for (var i = 0; i < FORMAT_INFO_DECODE_LOOKUP.length; i++)
80 | {
81 | var decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i];
82 | var targetInfo = decodeInfo[0];
83 | if (targetInfo == maskedFormatInfo)
84 | {
85 | // Found an exact match
86 | return new FormatInformation(decodeInfo[1]);
87 | }
88 | var bitsDifference = this.numBitsDiffering(maskedFormatInfo, targetInfo);
89 | if (bitsDifference < bestDifference)
90 | {
91 | bestFormatInfo = decodeInfo[1];
92 | bestDifference = bitsDifference;
93 | }
94 | }
95 | // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits
96 | // differing means we found a match
97 | if (bestDifference <= 3)
98 | {
99 | return new FormatInformation(bestFormatInfo);
100 | }
101 | return null;
102 | }
103 |
104 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/gf256.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function GF256( primitive)
27 | {
28 | this.expTable = new Array(256);
29 | this.logTable = new Array(256);
30 | var x = 1;
31 | for (var i = 0; i < 256; i++)
32 | {
33 | this.expTable[i] = x;
34 | x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
35 | if (x >= 0x100)
36 | {
37 | x ^= primitive;
38 | }
39 | }
40 | for (var i = 0; i < 255; i++)
41 | {
42 | this.logTable[this.expTable[i]] = i;
43 | }
44 | // logTable[0] == 0 but this should never be used
45 | var at0=new Array(1);at0[0]=0;
46 | this.zero = new GF256Poly(this, new Array(at0));
47 | var at1=new Array(1);at1[0]=1;
48 | this.one = new GF256Poly(this, new Array(at1));
49 |
50 | this.__defineGetter__("Zero", function()
51 | {
52 | return this.zero;
53 | });
54 | this.__defineGetter__("One", function()
55 | {
56 | return this.one;
57 | });
58 | this.buildMonomial=function( degree, coefficient)
59 | {
60 | if (degree < 0)
61 | {
62 | throw "System.ArgumentException";
63 | }
64 | if (coefficient == 0)
65 | {
66 | return zero;
67 | }
68 | var coefficients = new Array(degree + 1);
69 | for(var i=0;i 1 && coefficients[0] == 0)
35 | {
36 | // Leading term must be non-zero for anything except the constant polynomial "0"
37 | var firstNonZero = 1;
38 | while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0)
39 | {
40 | firstNonZero++;
41 | }
42 | if (firstNonZero == coefficientsLength)
43 | {
44 | this.coefficients = field.Zero.coefficients;
45 | }
46 | else
47 | {
48 | this.coefficients = new Array(coefficientsLength - firstNonZero);
49 | for(var i=0;i largerCoefficients.length)
121 | {
122 | var temp = smallerCoefficients;
123 | smallerCoefficients = largerCoefficients;
124 | largerCoefficients = temp;
125 | }
126 | var sumDiff = new Array(largerCoefficients.length);
127 | var lengthDiff = largerCoefficients.length - smallerCoefficients.length;
128 | // Copy high-order terms only found in higher-degree polynomial's coefficients
129 | //Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
130 | for(var ci=0;ci= other.Degree && !remainder.Zero)
219 | {
220 | var degreeDifference = remainder.Degree - other.Degree;
221 | var scale = this.field.multiply(remainder.getCoefficient(remainder.Degree), inverseDenominatorLeadingTerm);
222 | var term = other.multiplyByMonomial(degreeDifference, scale);
223 | var iterationQuotient = this.field.buildMonomial(degreeDifference, scale);
224 | quotient = quotient.addOrSubtract(iterationQuotient);
225 | remainder = remainder.addOrSubtract(term);
226 | }
227 |
228 | return new Array(quotient, remainder);
229 | }
230 | }
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/grid.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | GridSampler = {};
27 |
28 | GridSampler.checkAndNudgePoints=function( image, points)
29 | {
30 | var width = qrcode.width;
31 | var height = qrcode.height;
32 | // Check and nudge points from start until we see some that are OK:
33 | var nudged = true;
34 | for (var offset = 0; offset < points.length && nudged; offset += 2)
35 | {
36 | var x = Math.floor (points[offset]);
37 | var y = Math.floor( points[offset + 1]);
38 | if (x < - 1 || x > width || y < - 1 || y > height)
39 | {
40 | throw "Error.checkAndNudgePoints ";
41 | }
42 | nudged = false;
43 | if (x == - 1)
44 | {
45 | points[offset] = 0.0;
46 | nudged = true;
47 | }
48 | else if (x == width)
49 | {
50 | points[offset] = width - 1;
51 | nudged = true;
52 | }
53 | if (y == - 1)
54 | {
55 | points[offset + 1] = 0.0;
56 | nudged = true;
57 | }
58 | else if (y == height)
59 | {
60 | points[offset + 1] = height - 1;
61 | nudged = true;
62 | }
63 | }
64 | // Check and nudge points from end:
65 | nudged = true;
66 | for (var offset = points.length - 2; offset >= 0 && nudged; offset -= 2)
67 | {
68 | var x = Math.floor( points[offset]);
69 | var y = Math.floor( points[offset + 1]);
70 | if (x < - 1 || x > width || y < - 1 || y > height)
71 | {
72 | throw "Error.checkAndNudgePoints ";
73 | }
74 | nudged = false;
75 | if (x == - 1)
76 | {
77 | points[offset] = 0.0;
78 | nudged = true;
79 | }
80 | else if (x == width)
81 | {
82 | points[offset] = width - 1;
83 | nudged = true;
84 | }
85 | if (y == - 1)
86 | {
87 | points[offset + 1] = 0.0;
88 | nudged = true;
89 | }
90 | else if (y == height)
91 | {
92 | points[offset + 1] = height - 1;
93 | nudged = true;
94 | }
95 | }
96 | }
97 |
98 |
99 |
100 | GridSampler.sampleGrid3=function( image, dimension, transform)
101 | {
102 | var bits = new BitMatrix(dimension);
103 | var points = new Array(dimension << 1);
104 | for (var y = 0; y < dimension; y++)
105 | {
106 | var max = points.length;
107 | var iValue = y + 0.5;
108 | for (var x = 0; x < max; x += 2)
109 | {
110 | points[x] = (x >> 1) + 0.5;
111 | points[x + 1] = iValue;
112 | }
113 | transform.transformPoints1(points);
114 | // Quick check to see if points transformed to something inside the image;
115 | // sufficient to check the endpoints
116 | GridSampler.checkAndNudgePoints(image, points);
117 | try
118 | {
119 | for (var x = 0; x < max; x += 2)
120 | {
121 | var xpoint = (Math.floor( points[x]) * 4) + (Math.floor( points[x + 1]) * qrcode.width * 4);
122 | var bit = image[Math.floor( points[x])+ qrcode.width* Math.floor( points[x + 1])];
123 | qrcode.imagedata.data[xpoint] = bit?255:0;
124 | qrcode.imagedata.data[xpoint+1] = bit?255:0;
125 | qrcode.imagedata.data[xpoint+2] = 0;
126 | qrcode.imagedata.data[xpoint+3] = 255;
127 | //bits[x >> 1][ y]=bit;
128 | if(bit)
129 | bits.set_Renamed(x >> 1, y);
130 | }
131 | }
132 | catch ( aioobe)
133 | {
134 | // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
135 | // transform gets "twisted" such that it maps a straight line of points to a set of points
136 | // whose endpoints are in bounds, but others are not. There is probably some mathematical
137 | // way to detect this about the transformation that I don't know yet.
138 | // This results in an ugly runtime exception despite our clever checks above -- can't have
139 | // that. We could check each point's coordinates but that feels duplicative. We settle for
140 | // catching and wrapping ArrayIndexOutOfBoundsException.
141 | throw "Error.checkAndNudgePoints";
142 | }
143 | }
144 | return bits;
145 | }
146 |
147 | GridSampler.sampleGridx=function( image, dimension, p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY)
148 | {
149 | var transform = PerspectiveTransform.quadrilateralToQuadrilateral(p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
150 |
151 | return GridSampler.sampleGrid3(image, dimension, transform);
152 | }
153 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/qrcode.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2011 Lazar Laszlo (lazarsoft@gmail.com, www.lazarsoft.info)
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 |
18 | qrcode = window.qrcode || {};
19 | qrcode.imagedata = null;
20 | qrcode.width = 0;
21 | qrcode.height = 0;
22 | qrcode.qrCodeSymbol = null;
23 | qrcode.debug = false;
24 | qrcode.maxImgSize = 1024*1024;
25 |
26 | qrcode.sizeOfDataLengthInfo = [ [ 10, 9, 8, 8 ], [ 12, 11, 16, 10 ], [ 14, 13, 16, 12 ] ];
27 |
28 | qrcode.callback = null;
29 |
30 | qrcode.decode = function(src){
31 |
32 | if(arguments.length==0)
33 | {
34 | var canvas_qr = document.getElementById("qr-canvas");
35 | var context = canvas_qr.getContext('2d');
36 | qrcode.width = canvas_qr.width;
37 | qrcode.height = canvas_qr.height;
38 | qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);
39 | qrcode.result = qrcode.process(context);
40 | if(qrcode.callback!=null)
41 | qrcode.callback(qrcode.result);
42 | return qrcode.result;
43 | }
44 | else
45 | {
46 | var image = new Image();
47 | image.onload=function(){
48 | //var canvas_qr = document.getElementById("qr-canvas");
49 | var canvas_qr = document.createElement('canvas');
50 | var context = canvas_qr.getContext('2d');
51 | var nheight = image.height;
52 | var nwidth = image.width;
53 | if(image.width*image.height>qrcode.maxImgSize)
54 | {
55 | var ir = image.width / image.height;
56 | nheight = Math.sqrt(qrcode.maxImgSize/ir);
57 | nwidth=ir*nheight;
58 | }
59 |
60 | canvas_qr.width = nwidth;
61 | canvas_qr.height = nheight;
62 |
63 | context.drawImage(image, 0, 0, canvas_qr.width, canvas_qr.height );
64 | qrcode.width = canvas_qr.width;
65 | qrcode.height = canvas_qr.height;
66 | try{
67 | qrcode.imagedata = context.getImageData(0, 0, canvas_qr.width, canvas_qr.height);
68 | }catch(e){
69 | qrcode.result = "Cross domain image reading not supported in your browser! Save it to your computer then drag and drop the file!";
70 | if(qrcode.callback!=null)
71 | qrcode.callback(qrcode.result);
72 | return;
73 | }
74 |
75 | try
76 | {
77 | qrcode.result = qrcode.process(context);
78 | }
79 | catch(e)
80 | {
81 | console.log(e);
82 | qrcode.result = "error decoding QR Code";
83 | }
84 | if(qrcode.callback!=null)
85 | qrcode.callback(qrcode.result);
86 | }
87 | image.src = src;
88 | }
89 | }
90 |
91 | qrcode.isUrl = function(s)
92 | {
93 | var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
94 | return regexp.test(s);
95 | }
96 |
97 | qrcode.decode_url = function (s)
98 | {
99 | var escaped = "";
100 | try{
101 | escaped = escape( s );
102 | }
103 | catch(e)
104 | {
105 | console.log(e);
106 | escaped = s;
107 | }
108 | var ret = "";
109 | try{
110 | ret = decodeURIComponent( escaped );
111 | }
112 | catch(e)
113 | {
114 | console.log(e);
115 | ret = escaped;
116 | }
117 | return ret;
118 | }
119 |
120 | qrcode.decode_utf8 = function ( s )
121 | {
122 | if(qrcode.isUrl(s))
123 | return qrcode.decode_url(s);
124 | else
125 | return s;
126 | }
127 |
128 | qrcode.process = function(ctx){
129 |
130 | var start = new Date().getTime();
131 |
132 | var image = qrcode.grayScaleToBitmap(qrcode.grayscale());
133 | //var image = qrcode.binarize(128);
134 |
135 | if(qrcode.debug)
136 | {
137 | for (var y = 0; y < qrcode.height; y++)
138 | {
139 | for (var x = 0; x < qrcode.width; x++)
140 | {
141 | var point = (x * 4) + (y * qrcode.width * 4);
142 | qrcode.imagedata.data[point] = image[x+y*qrcode.width]?0:0;
143 | qrcode.imagedata.data[point+1] = image[x+y*qrcode.width]?0:0;
144 | qrcode.imagedata.data[point+2] = image[x+y*qrcode.width]?255:0;
145 | }
146 | }
147 | ctx.putImageData(qrcode.imagedata, 0, 0);
148 | }
149 |
150 | //var finderPatternInfo = new FinderPatternFinder().findFinderPattern(image);
151 |
152 | var detector = new Detector(image);
153 |
154 | var qRCodeMatrix = detector.detect();
155 |
156 | /*for (var y = 0; y < qRCodeMatrix.bits.Height; y++)
157 | {
158 | for (var x = 0; x < qRCodeMatrix.bits.Width; x++)
159 | {
160 | var point = (x * 4*2) + (y*2 * qrcode.width * 4);
161 | qrcode.imagedata.data[point] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
162 | qrcode.imagedata.data[point+1] = qRCodeMatrix.bits.get_Renamed(x,y)?0:0;
163 | qrcode.imagedata.data[point+2] = qRCodeMatrix.bits.get_Renamed(x,y)?255:0;
164 | }
165 | }*/
166 | if(qrcode.debug)
167 | ctx.putImageData(qrcode.imagedata, 0, 0);
168 |
169 | var reader = Decoder.decode(qRCodeMatrix.bits);
170 | var data = reader.DataByte;
171 | var str="";
172 | for(var i=0;i minmax[ax][ay][1])
240 | minmax[ax][ay][1] = target;
241 | }
242 | }
243 | //minmax[ax][ay][0] = (minmax[ax][ay][0] + minmax[ax][ay][1]) / 2;
244 | }
245 | }
246 | var middle = new Array(numSqrtArea);
247 | for (var i3 = 0; i3 < numSqrtArea; i3++)
248 | {
249 | middle[i3] = new Array(numSqrtArea);
250 | }
251 | for (var ay = 0; ay < numSqrtArea; ay++)
252 | {
253 | for (var ax = 0; ax < numSqrtArea; ax++)
254 | {
255 | middle[ax][ay] = Math.floor((minmax[ax][ay][0] + minmax[ax][ay][1]) / 2);
256 | //Console.out.print(middle[ax][ay] + ",");
257 | }
258 | //Console.out.println("");
259 | }
260 | //Console.out.println("");
261 |
262 | return middle;
263 | }
264 |
265 | qrcode.grayScaleToBitmap=function(grayScale)
266 | {
267 | var middle = qrcode.getMiddleBrightnessPerArea(grayScale);
268 | var sqrtNumArea = middle.length;
269 | var areaWidth = Math.floor(qrcode.width / sqrtNumArea);
270 | var areaHeight = Math.floor(qrcode.height / sqrtNumArea);
271 | var bitmap = new Array(qrcode.height*qrcode.width);
272 |
273 | for (var ay = 0; ay < sqrtNumArea; ay++)
274 | {
275 | for (var ax = 0; ax < sqrtNumArea; ax++)
276 | {
277 | for (var dy = 0; dy < areaHeight; dy++)
278 | {
279 | for (var dx = 0; dx < areaWidth; dx++)
280 | {
281 | bitmap[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] = (grayScale[areaWidth * ax + dx+ (areaHeight * ay + dy)*qrcode.width] < middle[ax][ay])?true:false;
282 | }
283 | }
284 | }
285 | }
286 | return bitmap;
287 | }
288 |
289 | qrcode.grayscale = function(){
290 | var ret = new Array(qrcode.width*qrcode.height);
291 | for (var y = 0; y < qrcode.height; y++)
292 | {
293 | for (var x = 0; x < qrcode.width; x++)
294 | {
295 | var gray = qrcode.getPixel(x, y);
296 |
297 | ret[x+y*qrcode.width] = gray;
298 | }
299 | }
300 | return ret;
301 | }
302 |
303 |
304 |
305 |
306 | function URShift( number, bits)
307 | {
308 | if (number >= 0)
309 | return number >> bits;
310 | else
311 | return (number >> bits) + (2 << ~bits);
312 | }
313 |
314 |
315 | Array.prototype.remove = function(from, to) {
316 | var rest = this.slice((to || from) + 1 || this.length);
317 | this.length = from < 0 ? this.length + from : from;
318 | return this.push.apply(this, rest);
319 | };
320 |
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/rsdecoder.js:
--------------------------------------------------------------------------------
1 | /*
2 | Ported to JavaScript by Lazar Laszlo 2011
3 |
4 | lazarsoft@gmail.com, www.lazarsoft.info
5 |
6 | */
7 |
8 | /*
9 | *
10 | * Copyright 2007 ZXing authors
11 | *
12 | * Licensed under the Apache License, Version 2.0 (the "License");
13 | * you may not use this file except in compliance with the License.
14 | * You may obtain a copy of the License at
15 | *
16 | * http://www.apache.org/licenses/LICENSE-2.0
17 | *
18 | * Unless required by applicable law or agreed to in writing, software
19 | * distributed under the License is distributed on an "AS IS" BASIS,
20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 | * See the License for the specific language governing permissions and
22 | * limitations under the License.
23 | */
24 |
25 |
26 | function ReedSolomonDecoder(field)
27 | {
28 | this.field = field;
29 | this.decode=function(received, twoS)
30 | {
31 | var poly = new GF256Poly(this.field, received);
32 | var syndromeCoefficients = new Array(twoS);
33 | for(var i=0;i= b's
70 | if (a.Degree < b.Degree)
71 | {
72 | var temp = a;
73 | a = b;
74 | b = temp;
75 | }
76 |
77 | var rLast = a;
78 | var r = b;
79 | var sLast = this.field.One;
80 | var s = this.field.Zero;
81 | var tLast = this.field.Zero;
82 | var t = this.field.One;
83 |
84 | // Run Euclidean algorithm until r's degree is less than R/2
85 | while (r.Degree >= Math.floor(R / 2))
86 | {
87 | var rLastLast = rLast;
88 | var sLastLast = sLast;
89 | var tLastLast = tLast;
90 | rLast = r;
91 | sLast = s;
92 | tLast = t;
93 |
94 | // Divide rLastLast by rLast, with quotient in q and remainder in r
95 | if (rLast.Zero)
96 | {
97 | // Oops, Euclidean algorithm already terminated?
98 | throw "r_{i-1} was zero";
99 | }
100 | r = rLastLast;
101 | var q = this.field.Zero;
102 | var denominatorLeadingTerm = rLast.getCoefficient(rLast.Degree);
103 | var dltInverse = this.field.inverse(denominatorLeadingTerm);
104 | while (r.Degree >= rLast.Degree && !r.Zero)
105 | {
106 | var degreeDiff = r.Degree - rLast.Degree;
107 | var scale = this.field.multiply(r.getCoefficient(r.Degree), dltInverse);
108 | q = q.addOrSubtract(this.field.buildMonomial(degreeDiff, scale));
109 | r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
110 | //r.EXE();
111 | }
112 |
113 | s = q.multiply1(sLast).addOrSubtract(sLastLast);
114 | t = q.multiply1(tLast).addOrSubtract(tLastLast);
115 | }
116 |
117 | var sigmaTildeAtZero = t.getCoefficient(0);
118 | if (sigmaTildeAtZero == 0)
119 | {
120 | throw "ReedSolomonException sigmaTilde(0) was zero";
121 | }
122 |
123 | var inverse = this.field.inverse(sigmaTildeAtZero);
124 | var sigma = t.multiply2(inverse);
125 | var omega = r.multiply2(inverse);
126 | return new Array(sigma, omega);
127 | }
128 | this.findErrorLocations=function( errorLocator)
129 | {
130 | // This is a direct application of Chien's search
131 | var numErrors = errorLocator.Degree;
132 | if (numErrors == 1)
133 | {
134 | // shortcut
135 | return new Array(errorLocator.getCoefficient(1));
136 | }
137 | var result = new Array(numErrors);
138 | var e = 0;
139 | for (var i = 1; i < 256 && e < numErrors; i++)
140 | {
141 | if (errorLocator.evaluateAt(i) == 0)
142 | {
143 | result[e] = this.field.inverse(i);
144 | e++;
145 | }
146 | }
147 | if (e != numErrors)
148 | {
149 | throw "Error locator degree does not match number of roots";
150 | }
151 | return result;
152 | }
153 | this.findErrorMagnitudes=function( errorEvaluator, errorLocations, dataMatrix)
154 | {
155 | // This is directly applying Forney's Formula
156 | var s = errorLocations.length;
157 | var result = new Array(s);
158 | for (var i = 0; i < s; i++)
159 | {
160 | var xiInverse = this.field.inverse(errorLocations[i]);
161 | var denominator = 1;
162 | for (var j = 0; j < s; j++)
163 | {
164 | if (i != j)
165 | {
166 | denominator = this.field.multiply(denominator, GF256.addOrSubtract(1, this.field.multiply(errorLocations[j], xiInverse)));
167 | }
168 | }
169 | result[i] = this.field.multiply(errorEvaluator.evaluateAt(xiInverse), this.field.inverse(denominator));
170 | // Thanks to sanfordsquires for this fix:
171 | if (dataMatrix)
172 | {
173 | result[i] = this.field.multiply(result[i], xiInverse);
174 | }
175 | }
176 | return result;
177 | }
178 | }
--------------------------------------------------------------------------------
/public/src/js/jsqrcode/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | QRCODE
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
131 |
132 |
133 |
134 |
135 |
145 | Capture
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/public/src/js/services/address.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.address').factory('Address',
4 | function($resource) {
5 | return $resource(window.apiPrefix + '/addr/:addrStr/?noTxList=1', {
6 | addrStr: '@addStr'
7 | }, {
8 | get: {
9 | method: 'GET',
10 | interceptor: {
11 | response: function (res) {
12 | return res.data;
13 | },
14 | responseError: function (res) {
15 | if (res.status === 404) {
16 | return res;
17 | }
18 | }
19 | }
20 | }
21 | });
22 | });
23 |
24 |
--------------------------------------------------------------------------------
/public/src/js/services/blocks.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.blocks')
4 | .factory('Block',
5 | function($resource) {
6 | return $resource(window.apiPrefix + '/block/:blockHash', {
7 | blockHash: '@blockHash'
8 | }, {
9 | get: {
10 | method: 'GET',
11 | interceptor: {
12 | response: function (res) {
13 | return res.data;
14 | },
15 | responseError: function (res) {
16 | if (res.status === 404) {
17 | return res;
18 | }
19 | }
20 | }
21 | }
22 | });
23 | })
24 | .factory('Blocks',
25 | function($resource) {
26 | return $resource(window.apiPrefix + '/blocks');
27 | })
28 | .factory('BlockByHeight',
29 | function($resource) {
30 | return $resource(window.apiPrefix + '/block-index/:blockHeight');
31 | });
32 |
--------------------------------------------------------------------------------
/public/src/js/services/charts.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.charts')
4 | .factory('Chart',
5 | function($resource) {
6 | return $resource(window.apiPrefix + '/chart/:chartType', {
7 | chartType: '@chartType'
8 | }, {
9 | get: {
10 | method: 'GET',
11 | interceptor: {
12 | response: function (res) {
13 | return res.data;
14 | },
15 | responseError: function (res) {
16 | if (res.status === 404) {
17 | return res;
18 | }
19 | }
20 | }
21 | }
22 | });
23 | })
24 | .factory('Charts',
25 | function($resource) {
26 | return $resource(window.apiPrefix + '/charts');
27 | });
28 |
--------------------------------------------------------------------------------
/public/src/js/services/currency.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.currency').factory('Currency',
4 | function($resource) {
5 | return $resource(window.apiPrefix + '/currency');
6 | });
7 |
--------------------------------------------------------------------------------
/public/src/js/services/global.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //Global service for global variables
4 | angular.module('insight.system')
5 | .factory('Global',[
6 | function() {
7 | return {};
8 | }
9 | ])
10 | .factory('Version',
11 | function($resource) {
12 | return $resource(window.apiPrefix + '/version');
13 | });
14 |
--------------------------------------------------------------------------------
/public/src/js/services/socket.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var ScopedSocket = function(socket, $rootScope) {
4 | this.socket = socket;
5 | this.$rootScope = $rootScope;
6 | this.listeners = [];
7 | };
8 |
9 | ScopedSocket.prototype.removeAllListeners = function(opts) {
10 | if (!opts) opts = {};
11 | for (var i = 0; i < this.listeners.length; i++) {
12 | var details = this.listeners[i];
13 | if (opts.skipConnect && details.event === 'connect') {
14 | continue;
15 | }
16 | this.socket.removeListener(details.event, details.fn);
17 | }
18 | this.listeners = [];
19 | };
20 |
21 | ScopedSocket.prototype.on = function(event, callback) {
22 | var socket = this.socket;
23 | var $rootScope = this.$rootScope;
24 |
25 | var wrapped_callback = function() {
26 | var args = arguments;
27 | $rootScope.$apply(function() {
28 | callback.apply(socket, args);
29 | });
30 | };
31 | socket.on(event, wrapped_callback);
32 |
33 | this.listeners.push({
34 | event: event,
35 | fn: wrapped_callback
36 | });
37 | };
38 |
39 | ScopedSocket.prototype.emit = function(event, data, callback) {
40 | var socket = this.socket;
41 | var $rootScope = this.$rootScope;
42 | var args = Array.prototype.slice.call(arguments);
43 |
44 | args.push(function() {
45 | var args = arguments;
46 | $rootScope.$apply(function() {
47 | if (callback) {
48 | callback.apply(socket, args);
49 | }
50 | });
51 | });
52 |
53 | socket.emit.apply(socket, args);
54 | };
55 |
56 | angular.module('insight.socket').factory('getSocket',
57 | function($rootScope) {
58 | var socket = io.connect(null, {
59 | 'reconnect': true,
60 | 'reconnection delay': 500,
61 | });
62 | return function(scope) {
63 | var scopedSocket = new ScopedSocket(socket, $rootScope);
64 | scope.$on('$destroy', function() {
65 | scopedSocket.removeAllListeners();
66 | });
67 | socket.on('connect', function() {
68 | scopedSocket.removeAllListeners({
69 | skipConnect: true
70 | });
71 | });
72 | return scopedSocket;
73 | };
74 | });
75 |
--------------------------------------------------------------------------------
/public/src/js/services/status.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.status')
4 | .factory('Status',
5 | function($resource) {
6 | return $resource(window.apiPrefix + '/status', {
7 | q: '@q'
8 | });
9 | })
10 | .factory('Sync',
11 | function($resource) {
12 | return $resource(window.apiPrefix + '/sync');
13 | })
14 | .factory('PeerSync',
15 | function($resource) {
16 | return $resource(window.apiPrefix + '/peer');
17 | });
18 |
--------------------------------------------------------------------------------
/public/src/js/services/transactions.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('insight.transactions')
4 | .factory('Transaction',
5 | function($resource) {
6 | return $resource(window.apiPrefix + '/tx/:txId', {
7 | txId: '@txId'
8 | }, {
9 | get: {
10 | method: 'GET',
11 | interceptor: {
12 | response: function (res) {
13 | return res.data;
14 | },
15 | responseError: function (res) {
16 | if (res.status === 404) {
17 | return res;
18 | }
19 | }
20 | }
21 | }
22 | });
23 | })
24 | .factory('TransactionsByBlock',
25 | function($resource) {
26 | return $resource(window.apiPrefix + '/txs', {
27 | block: '@block'
28 | });
29 | })
30 | .factory('TransactionsByAddress',
31 | function($resource) {
32 | return $resource(window.apiPrefix + '/txs', {
33 | address: '@address'
34 | });
35 | })
36 | .factory('Transactions',
37 | function($resource) {
38 | return $resource(window.apiPrefix + '/txs');
39 | });
40 |
--------------------------------------------------------------------------------
/public/views/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Ooops!
4 |
404 Page not found :(
5 |
Go to home
6 |
7 |
--------------------------------------------------------------------------------
/public/views/address.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Address {{address.addrStr}}
7 |
8 |
9 |
10 | Final Balance {{$root.currency.getConvertion(address.balance)}}
11 |
12 |
13 |
19 |
20 | Address {{$root.currency.getConvertion(address.balance)}}
21 |
22 | Loading Address Information
23 |
24 |
25 |
26 | Address
27 | {{address.addrStr}}
28 |
29 |
30 |
Summary confirmed
31 |
32 |
33 |
34 |
35 |
36 | Total Received
37 | {{$root.currency.getConvertion(address.totalReceived)}}
38 |
39 |
40 | Total Sent
41 | {{$root.currency.getConvertion(address.totalSent)}}
42 |
43 |
44 | Final Balance
45 | {{$root.currency.getConvertion(address.balance)}}
46 |
47 |
48 | No. Transactions
49 | {{address.txApperances}}
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
Unconfirmed
60 |
61 |
62 |
63 | Unconfirmed Txs Balance
64 | {{$root.currency.getConvertion(address.unconfirmedBalance)}}
65 |
66 |
67 | No. Transactions
68 | {{address.unconfirmedTxApperances}}
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
Transactions
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/public/views/block.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
Block #{{block.height}}
13 |
14 |
15 | Hash {{block.hash}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
33 |
34 | Block #{{block.height}}
35 |
36 | Loading Block Information
37 |
38 |
39 |
40 | BlockHash
41 | {{block.hash}}
42 |
43 |
44 |
Summary
45 |
46 |
47 |
48 |
49 |
50 | Number Of Transactions
51 | {{block.tx.length}}
52 |
53 |
54 | Height
55 | {{block.height}}
56 | (Mainchain)
57 | (Orphaned)
58 |
59 |
60 |
61 | Block Reward
62 | {{$root.currency.getConvertion(block.reward)}}
63 |
64 |
65 | Timestamp
66 | {{block.time * 1000 | date:'medium'}}
67 |
68 |
69 | Mined by
70 |
71 | {{block.poolInfo.poolName}}
72 |
73 |
74 |
75 | Merkle Root
76 |
77 |
78 |
79 | {{block.merkleroot}}
80 |
81 |
82 |
83 |
84 | Previous Block
85 | {{block.height-1}}
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | Difficulty
95 | {{block.difficulty}}
96 |
97 |
98 | Bits
99 | {{block.bits}}
100 |
101 |
102 | Size (bytes)
103 | {{block.size}}
104 |
105 |
106 | Version
107 | {{block.version}}
108 |
109 |
110 | Nonce
111 |
112 |
113 |
114 | {{block.nonce}}
115 |
116 |
117 |
118 |
119 | Solution
120 |
121 |
122 |
123 | {{block.solution}}
124 |
125 |
126 |
127 |
128 | Next Block
129 | {{block.height+1}}
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
Transactions
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/public/views/block_list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
Blocks
9 | mined on:
10 |
11 |
12 |
13 | {{pagination.current}} UTC
14 |
15 |
16 |
17 | Loading Selected Date...
18 |
19 |
20 |
21 |
Today
22 |
{{humanSince(pagination.currentTs)}}
23 |
24 |
28 |
29 |
30 |
31 |
37 |
38 |
39 |
40 | Height
41 | Timestamp
42 | Transactions
43 | Mined by
44 | Size
45 |
46 |
47 |
48 |
49 | Waiting for blocks...
50 |
51 |
52 | {{b.height}}
53 | {{b.time * 1000 | date:'medium'}}
54 | {{b.txlength}}
55 | {{b.poolInfo.poolName}}
56 | {{b.size}}
57 |
58 |
59 |
60 |
64 |
65 |
66 | No blocks yet.
68 |
69 |
70 |
--------------------------------------------------------------------------------
/public/views/charts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
Charts
9 |
10 |
11 |
12 |
13 | {{c.name}}
14 |
15 |
16 |
17 |
18 |
23 |
24 | Loading chart...
25 |
26 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/public/views/dummy-translations.html:
--------------------------------------------------------------------------------
1 | {{'Blocks'|translate}}
2 | {{'Status'|translate}}
3 |
--------------------------------------------------------------------------------
/public/views/includes/connection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
Error!
8 |
9 |
10 | Can't connect to zcashd to get live updates from the p2p network. (Tried connecting to zcashd at {{host}}:{{port}} and failed.)
11 |
12 |
13 |
14 | Can't connect to insight server. Attempting to reconnect...
15 |
16 |
17 |
18 | Can't connect to internet. Please, check your connection.
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/public/views/includes/currency.html:
--------------------------------------------------------------------------------
1 |
2 | {{currency.symbol}}
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/public/views/includes/header.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | ERROR
26 |
27 |
28 |
29 | {{sync.syncPercentage}}%
30 |
31 |
32 |
33 | ·
34 |
35 | {{'Conn'|translate}} {{info.connections}}
36 | ·
37 |
{{'Height'|translate}} {{totalBlocks || info.blocks}}
38 |
39 |
40 |
41 | Scan
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/public/views/includes/infoStatus.html:
--------------------------------------------------------------------------------
1 | Loading...
2 | {{error}}
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/views/includes/search.html:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/public/views/index.html:
--------------------------------------------------------------------------------
1 |
2 | {{$root.flashMessage}}
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
Latest Blocks
13 |
14 |
15 |
16 | Height
17 | Age
18 | Transactions
19 | Mined by
20 | Size
21 |
22 |
23 |
24 | Waiting for blocks...
25 |
26 |
27 | {{b.height}}
28 |
29 | {{humanSince(b.time)}}
30 | {{b.txlength}}
31 | {{b.poolInfo.poolName}}
32 | {{b.size}}
33 |
34 |
35 |
36 |
39 |
40 |
Latest Transactions
41 |
42 |
43 |
44 |
45 | Hash
46 | Value Out
47 |
48 |
49 |
50 | Waiting for transactions...
51 |
52 |
53 | {{tx.txid}}
54 |
55 | {{$root.currency.getConvertion(tx.valueOut)}}
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
About
64 |
insight is an open-source Zcash blockchain explorer with complete REST and websocket APIs that can be used for writing web wallets and other apps that need more advanced blockchain queries than provided by zcashd RPC. Check out the source code .
66 |
insight is still in development, so be sure to report any bugs and provide feedback for improvement at our github issue tracker .
67 |
This explorer is currently showing testnet Zcash!
68 |
69 |
70 | Powered by
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/public/views/messages_verify.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
46 |
47 |
49 |
50 | Loading...
51 |
52 |
54 | The message is verifiably from {{verification.address}}.
55 |
56 |
58 | The message failed to verify.
59 |
60 |
62 |
An error occured in the verification process.
63 |
64 | Error message:
65 | {{verification.error}}
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Zcash comes with a way of signing arbitrary messages.
74 |
75 |
76 | This form can be used to verify that a message comes from
77 | a specific Zcash address.
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/public/views/redirect.html:
--------------------------------------------------------------------------------
1 | Redirecting...
2 |
--------------------------------------------------------------------------------
/public/views/status.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
Sync Status
10 |
11 |
12 |
13 | Sync Progress
14 |
15 |
16 |
17 | {{sync.syncPercentage}}%
18 | Complete
19 |
20 |
21 |
22 |
23 |
24 |
25 | Current Sync Status
26 |
27 | {{sync.status}}
28 |
29 |
30 | {{sync.error}}
31 |
32 |
33 |
34 |
35 | Start Date
36 | {{humanSince(sync.startTs)}}
37 |
38 |
39 | Finish Date
40 | {{humanSince(sync.endTs)}}
41 |
42 |
43 | Initial Block Chain Height
44 | {{sync.blockChainHeight}}
45 |
46 |
47 | Synced Blocks
48 | {{sync.syncedBlocks}}
49 |
50 |
51 | Skipped Blocks (previously synced)
52 | {{sync.skippedBlocks}}
53 |
54 |
55 | Sync Type
56 | {{sync.type}}
57 |
58 |
59 |
60 |
61 |
Last Block
62 |
75 |
76 |
77 |
78 |
79 |
Zcash node information
80 |
81 |
82 |
83 |
84 | Version
85 | {{info.version}}
86 |
87 |
88 | Protocol version
89 | {{info.protocolversion}}
90 |
91 |
92 | Blocks
93 | {{info.blocks}}
94 |
95 |
96 | Time Offset
97 | {{info.timeoffset}}
98 |
99 |
100 | Connections to other nodes
101 | {{info.connections}}
102 |
103 |
104 | Mining Difficulty
105 | {{info.difficulty}}
106 |
107 |
108 | Network
109 | {{info.network}}
110 |
111 |
112 | Proxy setting
113 | {{info.proxy}}
114 |
115 |
116 | Info Errors
117 | {{info.infoErrors}}
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/public/views/transaction.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Transaction
7 |
8 | {{tx.txid}}
9 |
10 |
11 |
12 |
13 | {{tx.confirmations}}
15 | Confirmations
16 |
17 | Unconfirmed Transaction!
19 | {{$root.currency.getConvertion(tx.valueOut)}}
20 |
21 |
22 |
28 |
29 |
30 |
Transaction
31 |
32 | Input
33 | Output
34 | {{v_index}}
35 |
36 |
37 |
38 |
39 | Loading Transaction Details
40 |
41 |
42 |
43 |
44 | Transaction
45 | {{tx.txid}}
46 |
47 |
48 |
Summary
49 |
50 |
51 |
52 | Size
53 | {{tx.size}} (bytes)
54 |
55 |
56 | Fee Rate
57 | {{$root.currency.getConvertion((tx.fees * 1000) / tx.size) + ' per kB'}}
58 |
59 |
60 | Received Time
61 | {{tx.time * 1000|date:'medium'}}
62 | N/A
63 |
64 |
65 | Mined Time
66 | {{tx.blocktime * 1000|date:'medium'}}
67 | N/A
68 |
69 |
70 | Included in Block
71 |
72 |
75 | Unconfirmed
76 |
77 |
78 | LockTime
79 | {{tx.locktime}}
80 |
81 |
82 |
83 |
84 | Version
85 | {{tx.version}}
86 |
87 |
88 | Overwintered
89 | {{tx.fOverwintered}}
90 |
91 |
92 | VersionGroupId
93 |
94 | 0x{{tx.nVersionGroupId.toString(16).padStart(8, "0")}}
95 |
96 | N/A
97 |
98 |
99 | Expiry Height
100 | {{tx.nExpiryHeight}}
101 |
102 |
103 |
104 |
105 | Coinbase
106 |
107 |
108 |
109 | {{tx.vin[0].coinbase}}
110 |
111 |
112 |
113 |
114 |
115 |
116 |
Details
117 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/public/views/transaction/list.html:
--------------------------------------------------------------------------------
1 | There are no transactions involving this address.
4 |
7 |
8 |
9 | Loading Transactions...
10 |
11 |
12 |
--------------------------------------------------------------------------------
/public/views/transaction_sendraw.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
24 |
32 |
33 |
34 |
36 |
37 | Loading...
38 |
39 |
40 | Transaction succesfully broadcast. Transaction id: {{txid}}
41 |
42 |
43 | An error occured: {{error}}
44 |
45 |
46 |
47 |
48 |
49 |
50 | This form can be used to broadcast a raw transaction in hex format over
51 | the Zcash network.
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------