├── .gitignore
├── README.md
├── build
├── build.js
├── check-versions.js
├── logo.png
├── utils.js
├── vue-loader.conf.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
└── webpack.prod.conf.js
├── config
├── dev.env.js
├── index.js
└── prod.env.js
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── src
├── App.vue
├── base
│ ├── login.vue
│ ├── nav.vue
│ └── sidebar.vue
├── components
│ └── harmony.vue
├── main.js
└── router
│ └── index.js
├── static
├── .gitkeep
├── css
│ ├── fonts
│ │ ├── Gotham-Book.otf
│ │ ├── Gotham-Light.otf
│ │ └── Gotham-Medium.otf
│ └── index.css
├── img
│ ├── chain
│ │ ├── harmony_banner.jpg
│ │ └── harmony_icon@2x.png
│ ├── favicon.ico
│ └── icons
│ │ ├── MathWallet_Logo_Horizontal_White.png
│ │ ├── dropdown_black@2x.png
│ │ ├── dropdown_white@2x.png
│ │ ├── first@2x.png
│ │ ├── first_disabled@2x.png
│ │ ├── last@2x.png
│ │ ├── last_disabled@2x.png
│ │ ├── logout_blue@2x.png
│ │ ├── logout_grey@2x.png
│ │ ├── mathwallet_webwallet@2x.png
│ │ ├── next@2x.png
│ │ ├── next_disabled@2x.png
│ │ ├── phone_blue@2x.png
│ │ ├── previous.png
│ │ ├── previous_disabled.png
│ │ ├── refresh_blue@2x.png
│ │ ├── refresh_grey@2x.png
│ │ └── slider@2x.png
├── js
│ ├── bignumber.mjs
│ ├── coinUnit.js
│ ├── common.js
│ ├── config.js
│ ├── i18n.js
│ └── util.js
└── lang
│ ├── cn.js
│ ├── en.js
│ └── ko.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Editor directories and files
9 | .idea
10 | .vscode
11 | *.suo
12 | *.ntvs*
13 | *.njsproj
14 | *.sln
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # math-harmony-web-wallet
2 |
3 | ## Build Setup
4 |
5 | ``` bash
6 | # install dependencies
7 | npm install
8 |
9 | # serve with hot reload at localhost:8080
10 | npm run dev
11 |
12 | # build for production with minification
13 | npm run build
14 |
15 | # build for production and view the bundle analyzer report
16 | npm run build --report
17 | ```
18 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | require('./check-versions')()
3 |
4 | process.env.NODE_ENV = 'production'
5 |
6 | const ora = require('ora')
7 | const rm = require('rimraf')
8 | const path = require('path')
9 | const chalk = require('chalk')
10 | const webpack = require('webpack')
11 | const config = require('../config')
12 | const webpackConfig = require('./webpack.prod.conf')
13 |
14 | const spinner = ora('building for production...')
15 | spinner.start()
16 |
17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
18 | if (err) throw err
19 | webpack(webpackConfig, (err, stats) => {
20 | spinner.stop()
21 | if (err) throw err
22 | process.stdout.write(stats.toString({
23 | colors: true,
24 | modules: false,
25 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
26 | chunks: false,
27 | chunkModules: false
28 | }) + '\n\n')
29 |
30 | if (stats.hasErrors()) {
31 | console.log(chalk.red(' Build failed with errors.\n'))
32 | process.exit(1)
33 | }
34 |
35 | console.log(chalk.cyan(' Build complete.\n'))
36 | console.log(chalk.yellow(
37 | ' Tip: built files are meant to be served over an HTTP server.\n' +
38 | ' Opening index.html over file:// won\'t work.\n'
39 | ))
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const chalk = require('chalk')
3 | const semver = require('semver')
4 | const packageConfig = require('../package.json')
5 | const shell = require('shelljs')
6 |
7 | function exec (cmd) {
8 | return require('child_process').execSync(cmd).toString().trim()
9 | }
10 |
11 | const versionRequirements = [
12 | {
13 | name: 'node',
14 | currentVersion: semver.clean(process.version),
15 | versionRequirement: packageConfig.engines.node
16 | }
17 | ]
18 |
19 | if (shell.which('npm')) {
20 | versionRequirements.push({
21 | name: 'npm',
22 | currentVersion: exec('npm --version'),
23 | versionRequirement: packageConfig.engines.npm
24 | })
25 | }
26 |
27 | module.exports = function () {
28 | const warnings = []
29 |
30 | for (let i = 0; i < versionRequirements.length; i++) {
31 | const mod = versionRequirements[i]
32 |
33 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34 | warnings.push(mod.name + ': ' +
35 | chalk.red(mod.currentVersion) + ' should be ' +
36 | chalk.green(mod.versionRequirement)
37 | )
38 | }
39 | }
40 |
41 | if (warnings.length) {
42 | console.log('')
43 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
44 | console.log()
45 |
46 | for (let i = 0; i < warnings.length; i++) {
47 | const warning = warnings[i]
48 | console.log(' ' + warning)
49 | }
50 |
51 | console.log()
52 | process.exit(1)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/build/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/build/logo.png
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const config = require('../config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const packageConfig = require('../package.json')
6 |
7 | exports.assetsPath = function(_path) {
8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' ?
9 | config.build.assetsSubDirectory :
10 | config.dev.assetsSubDirectory
11 |
12 | return path.posix.join(assetsSubDirectory, _path)
13 | }
14 |
15 | exports.cssLoaders = function(options) {
16 | options = options || {}
17 |
18 | const cssLoader = {
19 | loader: 'css-loader',
20 | options: {
21 | sourceMap: options.sourceMap
22 | }
23 | }
24 |
25 | const postcssLoader = {
26 | loader: 'postcss-loader',
27 | options: {
28 | sourceMap: options.sourceMap
29 | }
30 | }
31 |
32 | // generate loader string to be used with extract text plugin
33 | function generateLoaders(loader, loaderOptions) {
34 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
35 |
36 | if (loader) {
37 | loaders.push({
38 | loader: loader + '-loader',
39 | options: Object.assign({}, loaderOptions, {
40 | sourceMap: options.sourceMap
41 | })
42 | })
43 | }
44 |
45 | // Extract CSS when that option is specified
46 | // (which is the case during production build)
47 | if (options.extract) {
48 | return ExtractTextPlugin.extract({
49 | use: loaders,
50 | fallback: 'vue-style-loader',
51 | publicPath: '../../'
52 | })
53 | } else {
54 | return ['vue-style-loader'].concat(loaders)
55 | }
56 | }
57 |
58 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html
59 | return {
60 | css: generateLoaders(),
61 | postcss: generateLoaders(),
62 | less: generateLoaders('less'),
63 | sass: generateLoaders('sass', { indentedSyntax: true }),
64 | scss: generateLoaders('sass'),
65 | stylus: generateLoaders('stylus'),
66 | styl: generateLoaders('stylus')
67 | }
68 | }
69 |
70 | // Generate loaders for standalone style files (outside of .vue)
71 | exports.styleLoaders = function(options) {
72 | const output = []
73 | const loaders = exports.cssLoaders(options)
74 |
75 | for (const extension in loaders) {
76 | const loader = loaders[extension]
77 | output.push({
78 | test: new RegExp('\\.' + extension + '$'),
79 | use: loader
80 | })
81 | }
82 |
83 | return output
84 | }
85 |
86 | exports.createNotifierCallback = () => {
87 | const notifier = require('node-notifier')
88 |
89 | return (severity, errors) => {
90 | if (severity !== 'error') return
91 |
92 | const error = errors[0]
93 | const filename = error.file && error.file.split('!').pop()
94 |
95 | notifier.notify({
96 | title: packageConfig.name,
97 | message: severity + ': ' + error.name,
98 | subtitle: filename || '',
99 | icon: path.join(__dirname, 'logo.png')
100 | })
101 | }
102 | }
--------------------------------------------------------------------------------
/build/vue-loader.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const config = require('../config')
4 | const isProduction = process.env.NODE_ENV === 'production'
5 | const sourceMapEnabled = isProduction
6 | ? config.build.productionSourceMap
7 | : config.dev.cssSourceMap
8 |
9 | module.exports = {
10 | loaders: utils.cssLoaders({
11 | sourceMap: sourceMapEnabled,
12 | extract: isProduction
13 | }),
14 | cssSourceMap: sourceMapEnabled,
15 | cacheBusting: config.dev.cacheBusting,
16 | transformToRequire: {
17 | video: ['src', 'poster'],
18 | source: 'src',
19 | img: 'src',
20 | image: 'xlink:href'
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const config = require('../config')
5 | const vueLoaderConfig = require('./vue-loader.conf')
6 | const webpack = require("webpack")
7 |
8 | function resolve(dir) {
9 | return path.join(__dirname, '..', dir)
10 | }
11 |
12 |
13 |
14 | module.exports = {
15 | context: path.resolve(__dirname, '../'),
16 | entry: {
17 | app: './src/main.js'
18 | },
19 | output: {
20 | path: config.build.assetsRoot,
21 | filename: '[name].js',
22 | publicPath: process.env.NODE_ENV === 'production' ?
23 | config.build.assetsPublicPath : config.dev.assetsPublicPath
24 | },
25 | resolve: {
26 | extensions: ['.js', '.vue', '.json'],
27 | alias: {
28 | 'vue$': 'vue/dist/vue.esm.js',
29 | '@': resolve('src'),
30 | 'static': resolve('static'),
31 | 'base': resolve('src/base'),
32 | 'jquery': 'jquery'
33 | }
34 | },
35 | plugins: [
36 | new webpack.ProvidePlugin({
37 | $: "jquery",
38 | jQuery: "jquery",
39 | 'window.jQuery': "jquery"
40 | })
41 | ],
42 | module: {
43 | rules: [{
44 | test: /\.vue$/,
45 | loader: 'vue-loader',
46 | options: vueLoaderConfig
47 | },
48 | {
49 | test: /\.js$/,
50 | loader: 'babel-loader',
51 | include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
52 | },
53 | {
54 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
55 | loader: 'url-loader',
56 | options: {
57 | limit: 10000,
58 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
59 | }
60 | },
61 | {
62 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
63 | loader: 'url-loader',
64 | options: {
65 | limit: 10000,
66 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
67 | }
68 | },
69 | {
70 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
71 | loader: 'url-loader',
72 | options: {
73 | limit: 10000,
74 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
75 | }
76 | }
77 | ]
78 | },
79 | node: {
80 | // prevent webpack from injecting useless setImmediate polyfill because Vue
81 | // source contains it (although only uses it if it's native).
82 | setImmediate: false,
83 | // prevent webpack from injecting mocks to Node native modules
84 | // that does not make sense for the client
85 | dgram: 'empty',
86 | fs: 'empty',
87 | net: 'empty',
88 | tls: 'empty',
89 | child_process: 'empty'
90 | }
91 | }
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const utils = require('./utils')
3 | const webpack = require('webpack')
4 | const config = require('../config')
5 | const merge = require('webpack-merge')
6 | const path = require('path')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11 | const portfinder = require('portfinder')
12 |
13 | const HOST = process.env.HOST
14 | const PORT = process.env.PORT && Number(process.env.PORT)
15 |
16 | const devWebpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
19 | },
20 | // cheap-module-eval-source-map is faster for development
21 | devtool: config.dev.devtool,
22 |
23 | // these devServer options should be customized in /config/index.js
24 | devServer: {
25 | clientLogLevel: 'warning',
26 | historyApiFallback: {
27 | rewrites: [
28 | { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
29 | ],
30 | },
31 | hot: true,
32 | contentBase: false, // since we use CopyWebpackPlugin.
33 | compress: true,
34 | host: HOST || config.dev.host,
35 | port: PORT || config.dev.port,
36 | open: config.dev.autoOpenBrowser,
37 | overlay: config.dev.errorOverlay
38 | ? { warnings: false, errors: true }
39 | : false,
40 | publicPath: config.dev.assetsPublicPath,
41 | proxy: config.dev.proxyTable,
42 | quiet: true, // necessary for FriendlyErrorsPlugin
43 | watchOptions: {
44 | poll: config.dev.poll,
45 | }
46 | },
47 | plugins: [
48 | new webpack.DefinePlugin({
49 | 'process.env': require('../config/dev.env')
50 | }),
51 | new webpack.HotModuleReplacementPlugin(),
52 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
53 | new webpack.NoEmitOnErrorsPlugin(),
54 | // https://github.com/ampedandwired/html-webpack-plugin
55 | new HtmlWebpackPlugin({
56 | filename: 'index.html',
57 | template: 'index.html',
58 | inject: true
59 | }),
60 | // copy custom static assets
61 | new CopyWebpackPlugin([
62 | {
63 | from: path.resolve(__dirname, '../static'),
64 | to: config.dev.assetsSubDirectory,
65 | ignore: ['.*']
66 | }
67 | ])
68 | ]
69 | })
70 |
71 | module.exports = new Promise((resolve, reject) => {
72 | portfinder.basePort = process.env.PORT || config.dev.port
73 | portfinder.getPort((err, port) => {
74 | if (err) {
75 | reject(err)
76 | } else {
77 | // publish the new Port, necessary for e2e tests
78 | process.env.PORT = port
79 | // add port to devServer config
80 | devWebpackConfig.devServer.port = port
81 |
82 | // Add FriendlyErrorsPlugin
83 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
84 | compilationSuccessInfo: {
85 | messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
86 | },
87 | onErrors: config.dev.notifyOnErrors
88 | ? utils.createNotifierCallback()
89 | : undefined
90 | }))
91 |
92 | resolve(devWebpackConfig)
93 | }
94 | })
95 | })
96 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const path = require('path')
3 | const utils = require('./utils')
4 | const webpack = require('webpack')
5 | const config = require('../config')
6 | const merge = require('webpack-merge')
7 | const baseWebpackConfig = require('./webpack.base.conf')
8 | const CopyWebpackPlugin = require('copy-webpack-plugin')
9 | const HtmlWebpackPlugin = require('html-webpack-plugin')
10 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
12 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
13 |
14 | const env = require('../config/prod.env')
15 |
16 | const webpackConfig = merge(baseWebpackConfig, {
17 | module: {
18 | rules: utils.styleLoaders({
19 | sourceMap: config.build.productionSourceMap,
20 | extract: true,
21 | usePostCSS: true
22 | })
23 | },
24 | devtool: config.build.productionSourceMap ? config.build.devtool : false,
25 | output: {
26 | path: config.build.assetsRoot,
27 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
29 | },
30 | plugins: [
31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
32 | new webpack.DefinePlugin({
33 | 'process.env': env
34 | }),
35 | new UglifyJsPlugin({
36 | uglifyOptions: {
37 | compress: {
38 | warnings: false
39 | }
40 | },
41 | sourceMap: config.build.productionSourceMap,
42 | parallel: true
43 | }),
44 | // extract css into its own file
45 | new ExtractTextPlugin({
46 | filename: utils.assetsPath('css/[name].[contenthash].css'),
47 | // Setting the following option to `false` will not extract CSS from codesplit chunks.
48 | // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
49 | // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
50 | // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
51 | allChunks: true,
52 | }),
53 | // Compress extracted CSS. We are using this plugin so that possible
54 | // duplicated CSS from different components can be deduped.
55 | new OptimizeCSSPlugin({
56 | cssProcessorOptions: config.build.productionSourceMap
57 | ? { safe: true, map: { inline: false } }
58 | : { safe: true }
59 | }),
60 | // generate dist index.html with correct asset hash for caching.
61 | // you can customize output by editing /index.html
62 | // see https://github.com/ampedandwired/html-webpack-plugin
63 | new HtmlWebpackPlugin({
64 | filename: config.build.index,
65 | template: 'index.html',
66 | inject: true,
67 | minify: {
68 | removeComments: true,
69 | collapseWhitespace: true,
70 | removeAttributeQuotes: true
71 | // more options:
72 | // https://github.com/kangax/html-minifier#options-quick-reference
73 | },
74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
75 | chunksSortMode: 'dependency'
76 | }),
77 | // keep module.id stable when vendor modules does not change
78 | new webpack.HashedModuleIdsPlugin(),
79 | // enable scope hoisting
80 | new webpack.optimize.ModuleConcatenationPlugin(),
81 | // split vendor js into its own file
82 | new webpack.optimize.CommonsChunkPlugin({
83 | name: 'vendor',
84 | minChunks (module) {
85 | // any required modules inside node_modules are extracted to vendor
86 | return (
87 | module.resource &&
88 | /\.js$/.test(module.resource) &&
89 | module.resource.indexOf(
90 | path.join(__dirname, '../node_modules')
91 | ) === 0
92 | )
93 | }
94 | }),
95 | // extract webpack runtime and module manifest to its own file in order to
96 | // prevent vendor hash from being updated whenever app bundle is updated
97 | new webpack.optimize.CommonsChunkPlugin({
98 | name: 'manifest',
99 | minChunks: Infinity
100 | }),
101 | // This instance extracts shared chunks from code splitted chunks and bundles them
102 | // in a separate chunk, similar to the vendor chunk
103 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
104 | new webpack.optimize.CommonsChunkPlugin({
105 | name: 'app',
106 | async: 'vendor-async',
107 | children: true,
108 | minChunks: 3
109 | }),
110 |
111 | // copy custom static assets
112 | new CopyWebpackPlugin([
113 | {
114 | from: path.resolve(__dirname, '../static'),
115 | to: config.build.assetsSubDirectory,
116 | ignore: ['.*']
117 | }
118 | ])
119 | ]
120 | })
121 |
122 | if (config.build.productionGzip) {
123 | const CompressionWebpackPlugin = require('compression-webpack-plugin')
124 |
125 | webpackConfig.plugins.push(
126 | new CompressionWebpackPlugin({
127 | asset: '[path].gz[query]',
128 | algorithm: 'gzip',
129 | test: new RegExp(
130 | '\\.(' +
131 | config.build.productionGzipExtensions.join('|') +
132 | ')$'
133 | ),
134 | threshold: 10240,
135 | minRatio: 0.8
136 | })
137 | )
138 | }
139 |
140 | if (config.build.bundleAnalyzerReport) {
141 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
142 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
143 | }
144 |
145 | module.exports = webpackConfig
146 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const merge = require('webpack-merge')
3 | const prodEnv = require('./prod.env')
4 |
5 | module.exports = merge(prodEnv, {
6 | NODE_ENV: '"development"'
7 | })
8 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | // Template version: 1.3.1
3 | // see http://vuejs-templates.github.io/webpack for documentation.
4 |
5 | const path = require('path')
6 |
7 | module.exports = {
8 | dev: {
9 |
10 | // Paths
11 | assetsSubDirectory: 'static',
12 | assetsPublicPath: '/',
13 | proxyTable: {},
14 |
15 | // Various Dev Server settings
16 | host: 'localhost', // can be overwritten by process.env.HOST
17 | port: 8081, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
18 | autoOpenBrowser: false,
19 | errorOverlay: true,
20 | notifyOnErrors: true,
21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
22 |
23 |
24 | /**
25 | * Source Maps
26 | */
27 |
28 | // https://webpack.js.org/configuration/devtool/#development
29 | devtool: 'cheap-module-eval-source-map',
30 |
31 | // If you have problems debugging vue-files in devtools,
32 | // set this to false - it *may* help
33 | // https://vue-loader.vuejs.org/en/options.html#cachebusting
34 | cacheBusting: true,
35 |
36 | cssSourceMap: true
37 | },
38 |
39 | build: {
40 | // Template for index.html
41 | index: path.resolve(__dirname, '../dist/index.html'),
42 |
43 | // Paths
44 | assetsRoot: path.resolve(__dirname, '../dist/'),
45 | assetsSubDirectory: 'static',
46 | assetsPublicPath: './',
47 |
48 | /**
49 | * Source Maps
50 | */
51 |
52 | productionSourceMap: true,
53 | // https://webpack.js.org/configuration/devtool/#production
54 | devtool: '#source-map',
55 |
56 | // Gzip off by default as many popular static hosts such as
57 | // Surge or Netlify already gzip all static assets for you.
58 | // Before setting to `true`, make sure to:
59 | // npm install --save-dev compression-webpack-plugin
60 | productionGzip: false,
61 | productionGzipExtensions: ['js', 'css'],
62 |
63 | // Run the build command with an extra argument to
64 | // View the bundle analyzer report after build finishes:
65 | // `npm run build --report`
66 | // Set to `true` or `false` to always turn it on or off
67 | bundleAnalyzerReport: process.env.npm_config_report
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | module.exports = {
3 | NODE_ENV: '"production"'
4 | }
5 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Math Wallet
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "math-harmony-web-wallet",
3 | "version": "1.0.0",
4 | "description": "math-harmony-web-wallet",
5 | "author": "math",
6 | "private": true,
7 | "scripts": {
8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
9 | "start": "npm run dev",
10 | "build": "node build/build.js"
11 | },
12 | "dependencies": {
13 | "@harmony-js/core": "^0.1.28",
14 | "bignumber.js": "^9.0.0",
15 | "bootstrap": "^4.3.1",
16 | "clipboard": "^2.0.4",
17 | "jquery": "^3.4.1",
18 | "popper.js": "^1.15.0",
19 | "tslib": "^1.10.0",
20 | "vue": "^2.5.2",
21 | "vue-i18n": "^8.11.2",
22 | "vue-resource": "^1.5.1",
23 | "vue-router": "^3.0.1",
24 | "wc-messagebox": "^1.10.1"
25 | },
26 | "devDependencies": {
27 | "autoprefixer": "^7.1.2",
28 | "babel-core": "^6.22.1",
29 | "babel-helper-vue-jsx-merge-props": "^2.0.3",
30 | "babel-loader": "^7.1.1",
31 | "babel-plugin-syntax-jsx": "^6.18.0",
32 | "babel-plugin-transform-runtime": "^6.22.0",
33 | "babel-plugin-transform-vue-jsx": "^3.5.0",
34 | "babel-preset-env": "^1.3.2",
35 | "babel-preset-stage-2": "^6.22.0",
36 | "chalk": "^2.0.1",
37 | "copy-webpack-plugin": "^4.0.1",
38 | "css-loader": "^0.28.0",
39 | "extract-text-webpack-plugin": "^3.0.0",
40 | "file-loader": "^1.1.4",
41 | "friendly-errors-webpack-plugin": "^1.6.1",
42 | "html-webpack-plugin": "^2.30.1",
43 | "node-notifier": "^5.1.2",
44 | "optimize-css-assets-webpack-plugin": "^3.2.0",
45 | "ora": "^1.2.0",
46 | "portfinder": "^1.0.13",
47 | "postcss-import": "^11.0.0",
48 | "postcss-loader": "^2.0.8",
49 | "postcss-url": "^7.2.1",
50 | "rimraf": "^2.6.0",
51 | "semver": "^5.3.0",
52 | "shelljs": "^0.7.6",
53 | "uglifyjs-webpack-plugin": "^1.1.1",
54 | "url-loader": "^0.5.8",
55 | "vue-loader": "^13.3.0",
56 | "vue-style-loader": "^3.0.1",
57 | "vue-template-compiler": "^2.5.2",
58 | "webpack": "^3.6.0",
59 | "webpack-bundle-analyzer": "^2.9.0",
60 | "webpack-dev-server": "^2.9.1",
61 | "webpack-merge": "^4.1.0"
62 | },
63 | "engines": {
64 | "node": ">= 6.0.0",
65 | "npm": ">= 3.0.0"
66 | },
67 | "browserslist": [
68 | "> 1%",
69 | "last 2 versions",
70 | "not ie <= 8"
71 | ]
72 | }
73 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | 'autoprefixer': { browsers: 'last 5 version' }
4 | }
5 | }
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
17 |
--------------------------------------------------------------------------------
/src/base/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
![]()
4 |
5 |
{{$t('webwallet_your')}} {{blockchain}} {{$t('webwallet_wallet')}}
6 |
{{$t('webwallet_home_des1')}} {{blockchain}} ({{token}} & Tokens) {{$t('webwallet_home_des2')}}
7 |
{{$t('webwallet_login')}}
8 |
9 |
10 |
11 |
55 |
--------------------------------------------------------------------------------
/src/base/nav.vue:
--------------------------------------------------------------------------------
1 |
2 |
54 |
55 |
111 |
121 |
--------------------------------------------------------------------------------
/src/base/sidebar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 | {{blockchain}} Wallet
8 | {{account}}
9 |
10 |
11 |
14 |
15 |
25 |
26 |
27 |
28 |
{{$t("webwallet_estimated_value")}}
29 |
{{loadingBalance?'---':webUtil.addCommas(balances.sum,5)}} {{token}}
30 |
≈ {{webUtil.addCommas(balances[unit])}} {{unit}}
31 |
37 |
38 |
39 |
45 |
46 |
47 |
65 |
156 |
--------------------------------------------------------------------------------
/src/components/harmony.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
15 |
127 |
128 |
129 |
130 |
799 |
800 |
801 |
802 |
811 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import router from './router'
6 | import vueResource from 'vue-resource'
7 | import i18n from 'static/js/i18n'
8 | import webUtil from 'static/js/util'
9 | import globalData from 'static/js/config.js'
10 | import webCoin from 'static/js/coinUnit.js'
11 | import 'bootstrap'
12 | import 'bootstrap/dist/css/bootstrap.min.css'
13 | import 'static/css/index.css'
14 | import clipboard from 'clipboard'
15 | import { Alert, Confirm, Toast, Loading } from "wc-messagebox";
16 | import "wc-messagebox/style.css";
17 |
18 | Vue.config.productionTip = false
19 | Vue.use(vueResource)
20 |
21 | /*注册到vue原型上*/
22 | Vue.prototype.globalData = globalData;
23 | Vue.prototype.clipboard = clipboard;
24 | Vue.prototype.webUtil = webUtil;
25 | Vue.prototype.webCoin = webCoin;
26 |
27 |
28 | /* eslint-disable no-new */
29 | var vue1 = new Vue({
30 | el: '#app',
31 | i18n,
32 | router,
33 | components: { App },
34 | template: ''
35 | });
36 |
37 | Vue.use(Alert, {
38 | title: vue1.$t('prompt'),
39 | btnText: 'OK'
40 | });
41 | Vue.use(Confirm, {
42 | title: vue1.$t('Confirm'),
43 | });
44 | Vue.use(Toast, {
45 | location: 'bottom',
46 | toastStyle: {
47 | height: '60px',
48 | width: '160px',
49 | fontSize: '16px'
50 | },
51 | });
52 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | Vue.use(Router)
4 |
5 | export default new Router({
6 | routes: [{
7 | path: '/',
8 | name: 'harmony',
9 | component: resolve => require(['@/components/harmony'], resolve)
10 | }]
11 | })
12 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/.gitkeep
--------------------------------------------------------------------------------
/static/css/fonts/Gotham-Book.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/css/fonts/Gotham-Book.otf
--------------------------------------------------------------------------------
/static/css/fonts/Gotham-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/css/fonts/Gotham-Light.otf
--------------------------------------------------------------------------------
/static/css/fonts/Gotham-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/css/fonts/Gotham-Medium.otf
--------------------------------------------------------------------------------
/static/css/index.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 | :root {
3 | --darkbg: #2c363f;
4 | --blueColor: #007aff;
5 | --greenColor: #4cd964;
6 | --greyColor: #8a8a8f;
7 | --pale-grey: #efeff4;
8 | }
9 |
10 | @font-face {
11 | font-family: Gotham-Book;
12 | src: url("fonts/Gotham-Book.otf")
13 | }
14 |
15 | @font-face {
16 | font-family: Gotham-Light;
17 | src: url("fonts/Gotham-Light.otf")
18 | }
19 |
20 | @font-face {
21 | font-family: Gotham-Medium;
22 | src: url("fonts/Gotham-Medium.otf")
23 | }
24 |
25 |
26 | /* 禁用iPhone中Safari的字号自动调整 */
27 |
28 | html {
29 | -webkit-text-size-adjust: 100%;
30 | -ms-text-size-adjust: 100%;
31 | /* 解决IOS默认滑动很卡的情况 */
32 | -webkit-overflow-scrolling: touch;
33 | font-size: 14px;
34 | }
35 |
36 | p,
37 | div,
38 | ul,
39 | li,
40 | h1,
41 | h2,
42 | h3,
43 | h4,
44 | h5,
45 | h6 {
46 | margin: 0;
47 | }
48 |
49 | body {
50 | font-family: Gotham-Book;
51 | color: #000;
52 | background-color: var(--pale-grey);
53 | min-width: 1272px;
54 | overflow: scroll;
55 | }
56 |
57 | ul,
58 | li {
59 | list-style: none;
60 | padding-left: 0;
61 | }
62 |
63 | a,
64 | a:hover,
65 | a:active,
66 | a:focus {
67 | text-decoration: none;
68 | cursor: pointer;
69 | }
70 |
71 | button,
72 | textarea,
73 | input,
74 | select {
75 | outline: none;
76 | resize: none;
77 | box-shadow: none;
78 | /*去掉ios阴影*/
79 | -webkit-appearance: none;
80 | -webkit-tap-highlight-color: transparent;
81 | box-sizing: border-box;
82 | -webkit-box-sizing: border-box;
83 | background: transparent;
84 | }
85 |
86 | img+span {
87 | vertical-align: middle;
88 | }
89 |
90 | i {
91 | font-style: normal;
92 | }
93 |
94 | [v-cloak] {
95 | display: none;
96 | }
97 | .wc-mask{
98 | user-select: text!important;
99 | }
100 | .wc-popup-text{
101 | word-break:break-all;
102 | }
103 | .wc-popup {
104 | top: 40%!important;
105 | }
106 | .caret {
107 | width: 12px;
108 | height: 12px;
109 | border: none;
110 | background: url(../img/icons/dropdown_white@2x.png) no-repeat center /12px;
111 | }
112 |
113 | .btn {
114 | color: #fff !important;
115 | background: var(--blueColor);
116 | padding: 12px 24px;
117 | font-family: Gotham-Medium;
118 | font-weight: 500;
119 | }
120 |
121 | .grey-fsz {
122 | font-size: 12px;
123 | line-height: 16px;
124 | color: var(--greyColor) !important;
125 | }
126 |
127 | .null {
128 | padding: 32px;
129 | text-align: center;
130 | }
131 |
132 |
133 | /*nav*/
134 |
135 | .math-nav {
136 | background: var(--darkbg);
137 | padding: 16px 24px;
138 | position: fixed;
139 | left: 0;
140 | right: 0;
141 | top: 0;
142 | z-index: 500;
143 | }
144 |
145 | .math-nav a,
146 | .math-nav a:hover {
147 | color: #fff;
148 | }
149 |
150 | .math-nav .dropdown {
151 | display: inline-block;
152 | padding-left: 24px;
153 | }
154 |
155 | .dropdown-menu {
156 | min-width: 0;
157 | margin-top: 10px;
158 | overflow: hidden;
159 | }
160 |
161 | .math-nav .dropdown li {
162 | cursor: pointer;
163 | padding: 6px 20px;
164 | }
165 |
166 | .math-nav .float-right .mobile {
167 | color: #5ac8fa;
168 | padding-right: 24px;
169 | border-right: 1px solid rgba(255, 255, 255, 0.2);
170 | }
171 |
172 | .math-nav .float-right {
173 | padding: 8px;
174 | line-height: 16px;
175 | }
176 |
177 | .math-nav img+span {
178 | vertical-align: text-top;
179 | }
180 |
181 |
182 | /*首页登录*/
183 |
184 | .main-container {
185 | overflow: hidden;
186 | margin: 96px auto 32px;
187 | width: 824px;
188 | background: #fff;
189 | }
190 |
191 | .login-container {
192 | text-align: center;
193 | margin-bottom: 96px;
194 | font-size: 16px;
195 | line-height: 1.5;
196 | color: var(--greyColor);
197 | }
198 |
199 | .login-container .info {
200 | padding: 64px 24px 48px;
201 | }
202 |
203 | .login-container h1 {
204 | font-size: 24px;
205 | font-family: Gotham-Medium;
206 | font-weight: 500;
207 | line-height: 1.33;
208 | margin-bottom: 8px;
209 | color: #000;
210 | }
211 |
212 | .login-container .btn {
213 | display: inline-block;
214 | margin-top: 48px;
215 | }
216 |
217 |
218 | /*copyright*/
219 |
220 | .copyright {
221 | text-align: center;
222 | font-size: 12px;
223 | line-height: 16px;
224 | padding: 16px;
225 | color: var(--greyColor);
226 | }
227 |
228 | .webwallet+.copyright {
229 | padding-left: 400px;
230 | }
231 |
232 |
233 | /*左边列表*/
234 |
235 | .user-info {
236 | position: fixed;
237 | left: 0;
238 | top: 64px;
239 | bottom: 48px;
240 | width: 400px;
241 | background: #fff;
242 | z-index: 100;
243 | padding: 32px 24px 0;
244 | font-size: 12px;
245 | line-height: 16px;
246 | overflow-y: scroll;
247 | }
248 |
249 | .user-info .avator {
250 | width: 96px;
251 | height: 96px;
252 | display: inline-block;
253 | border-radius: 50%;
254 | box-shadow: 0 0 1px 1px var(--pale-grey);
255 | border: 8px solid #fff;
256 | overflow: hidden;
257 | margin-bottom: 12px;
258 | }
259 |
260 | .user-info h4 {
261 | font-size: 20px;
262 | font-weight: 500;
263 | font-family: Gotham-Medium;
264 | line-height: 1.2;
265 | margin: 4px 0;
266 | }
267 |
268 | .user-info .operation-list {
269 | margin-top: 34px;
270 | cursor: pointer;
271 | }
272 |
273 | .user-info .token-info {
274 | margin-top: 32px;
275 | padding: 32px 0;
276 | border-top: 1px solid var(--pale-grey);
277 | }
278 |
279 | .user-info .token-list {
280 | margin-top: 32px;
281 | padding-left: 0;
282 | }
283 |
284 | .user-info .token-list li {
285 | display: flex;
286 | justify-content: space-between;
287 | padding: 4px 0;
288 | }
289 |
290 | .refresh-logout {
291 | position: fixed;
292 | bottom: 0;
293 | left: 0;
294 | width: 400px;
295 | padding: 16px 24px;
296 | background: #fff;
297 | text-align: left;
298 | }
299 |
300 | .refresh-logout a {
301 | padding-left: 20px;
302 | }
303 |
304 | .refresh-logout a:first-child {
305 | background: url(../img/icons/refresh_grey@2x.png) no-repeat left center/16px;
306 | }
307 |
308 | .refresh-logout a:last-child {
309 | background: url(../img/icons/logout_grey@2x.png) no-repeat left center/16px;
310 | }
311 |
312 | .refresh-logout a:hover:first-child {
313 | background: url(../img/icons/refresh_blue@2x.png) no-repeat left center/16px;
314 | }
315 |
316 | .refresh-logout a:hover:last-child {
317 | background: url(../img/icons/logout_blue@2x.png) no-repeat left center/16px;
318 | }
319 |
320 | .operation-list a:nth-child(2) {
321 | border-left: 1px solid var(--pale-grey);
322 | margin-left: 12px;
323 | padding-left: 12px;
324 | }
325 |
326 | .refresh-logout a:first-child {
327 | border-right: 1px solid var(--pale-grey);
328 | margin-right: 12px;
329 | padding-right: 12px;
330 | }
331 |
332 | .user-info a:hover,
333 | .refresh-logout a:hover {
334 | color: var(--blueColor) !important;
335 | cursor: pointer;
336 | }
337 |
338 |
339 | /*中间内容*/
340 |
341 | .main-info {
342 | margin-left: 400px;
343 | padding: 0 24px;
344 | }
345 |
346 | .transfer-container {
347 | padding: 16px 24px 32px;
348 | }
349 |
350 | .transfer-container .btn {
351 | display: block;
352 | }
353 |
354 | .tabs {
355 | border-bottom: 1px solid var(--pale-grey);
356 | display: flex;
357 | justify-content: flex-start;
358 | }
359 |
360 | .tabs .tab {
361 | margin-right: 24px;
362 | padding-bottom: 16px;
363 | color: var(--geryColor);
364 | font-size: 16px;
365 | line-height: 1.5;
366 | }
367 |
368 | .tabs .tab.active {
369 | font-weight: 500;
370 | font-family: Gotham-Medium;
371 | color: var(--blueColor);
372 | border-bottom: 2px solid var(--blueColor);
373 | }
374 |
375 | .basic-form label {
376 | font-size: 12px;
377 | line-height: 16px;
378 | margin: 32px 0 8px;
379 | font-weight: 400;
380 | }
381 |
382 | .basic-form input,
383 | .basic-form select,
384 | .basic-form .input {
385 | display: block;
386 | padding: 12px;
387 | line-height: 1.5;
388 | font-size: 16px;
389 | border: 1px solid var(--pale-grey);
390 | width: 100%;
391 | word-wrap: break-word;
392 | }
393 |
394 | .basic-form .btn {
395 | margin-top: 32px;
396 | width: 100%;
397 | }
398 |
399 | .basic-group li {
400 | float: left;
401 | }
402 |
403 | .basic-group .amount {
404 | width: calc(100% - 190px);
405 | }
406 |
407 | .basic-group .token {
408 | width: 164px;
409 | margin-left: 24px;
410 | float: right;
411 | }
412 |
413 | .basic-group select {
414 | background: url(../img/icons/dropdown_black@2x.png)no-repeat 140px center/12px;
415 | border-radius: 0;
416 | }
417 |
418 |
419 | /*table*/
420 |
421 | .transactions {
422 | font-size: 12px;
423 | line-height: 16px;
424 | }
425 |
426 | .transactions thead th {
427 | padding: 12px 0;
428 | }
429 |
430 | .transactions td {
431 | padding: 8px 0;
432 | padding-right: 24px;
433 | width: 160px;
434 | max-width: 160px;
435 | overflow: hidden;
436 | white-space: nowrap;
437 | text-overflow: ellipsis;
438 | }
439 |
440 | .transactions tr td a {
441 | color: #000;
442 | padding: 4px 0;
443 | font-size: 12px;
444 | }
445 |
446 | .transactions tr td:first-child a {
447 | color: var(--blueColor)!important;
448 | }
449 |
450 | .transactions tr td:nth-child(2) a {
451 | padding: 4px 8px;
452 | background: #f7f7fa;
453 | }
454 |
455 | .transactions tr td:nth-child(3) {
456 | width: 216px;
457 | max-width: 216px;
458 | }
459 |
460 | .transactions tr td:nth-child(4) {
461 | width: 104px;
462 | max-width: 104px;
463 | }
464 |
465 | .transactions tr td:nth-child(4) a {
466 | color: var(--greenColor);
467 | }
468 |
469 | .transactions tr td:last-child,
470 | .transactions tr th:last-child {
471 | text-align: right;
472 | padding-right: 0;
473 | }
474 |
475 | .page-pagination {
476 | text-align: right;
477 | margin-top: 15px;
478 | padding-top: 20px;
479 | border-top: 1px solid var(--pale-grey);
480 | }
481 |
482 | .page-pagination img,
483 | .page-pagination span {
484 | margin-left: 16px;
485 | vertical-align: middle;
486 | }
487 |
488 | .page-pagination .clickable {
489 | cursor: pointer;
490 | }
491 |
492 | .page-pagination i {
493 | color: var(--greyColor);
494 | }
495 |
496 | .transfer-container h5 {
497 | font-size: 16px;
498 | font-weight: 500;
499 | font-family: Gotham-Medium;
500 | line-height: 1.5;
501 | padding-bottom: 15px;
502 | }
503 |
504 | .trans_detail {
505 | font-size: 12px;
506 | line-height: 16px;
507 | padding-top: 32px;
508 | border-top: 1px solid var(--pale-grey);
509 | }
510 |
511 | .trans_detail h4 {
512 | font-size: 20px;
513 | font-weight: 500;
514 | font-family: Gotham-Medium;
515 | line-height: 1.2;
516 | margin: 4px 0;
517 | }
518 |
519 | .trans_detail ul {
520 | padding: 16px 0 0;
521 | }
522 |
523 | .trans_detail li {
524 | padding: 12px 0;
525 | display: flex;
526 | justify-content: flex-start;
527 | }
528 |
529 | .trans_detail li span {
530 | width: 164px;
531 | min-width: 164px;
532 | margin-right: 24px;
533 | color: var(--greyColor);
534 | }
535 |
536 | .trans_detail li:first-child p {
537 | color: var(--greenColor);
538 | }
539 |
540 | .trans_detail li p {
541 | word-wrap: break-word;
542 | }
543 |
544 | .trans_detail .txHash {
545 | padding-top: 28px;
546 | margin-top: 16px;
547 | border-top: 1px solid var(--pale-grey);
548 | }
549 |
550 | .fee-set .setBtn {
551 | cursor: pointer;
552 | color: var(--blueColor);
553 | padding-left: 12px;
554 | margin-left: 12px;
555 | border-left: 1px solid var(--pale-grey);
556 | }
557 |
558 | .fee-set li {
559 | position: relative;
560 | float: left;
561 | }
562 |
563 | .fee-set li span {
564 | position: absolute;
565 | top: 16px;
566 | left: 12px;
567 | font-size: 12px;
568 | line-height: 24px;
569 | }
570 |
571 | .fee-set .slider {
572 | position: relative;
573 | margin: 14px 0 30px;
574 | height: 4px;
575 | background: var(--pale-grey);
576 | cursor: pointer
577 | }
578 |
579 | .fee-set .slider .thunk {
580 | position: absolute;
581 | left: 100px;
582 | top: -14px;
583 | width: 32px;
584 | height: 32px
585 | }
586 |
587 | .fee-set .slider .block {
588 | width: 32px;
589 | height: 32px;
590 | border-radius: 50%;
591 | border: 1px solid var(--pale-grey);
592 | background: #fff;
593 | transition: .2s all;
594 | text-align: center;
595 | line-height: 32px;
596 | }
597 |
598 | .fee-set .slider .cheap,
599 | .fee-set .slider .fast {
600 | position: absolute;
601 | top: 18px;
602 | color: var(--greyColor);
603 | font-size: 12px;
604 | line-height: 16px;
605 | }
606 |
607 | .fee-set .slider .cheap {
608 | left: 0;
609 | }
610 |
611 | .fee-set .slider .fast {
612 | right: 0;
613 | }
614 |
615 | .fee-set .gas-price,
616 | .fee-set .gas-limit {
617 | width: 282px;
618 | }
619 |
620 | .fee-set .gas-limit {
621 | margin-left: 24px;
622 | }
623 |
624 | .fee-set .gas-price input,
625 | .fee-set .gas-limit input {
626 | text-align: right;
627 | padding-left: 130px;
628 | }
629 |
--------------------------------------------------------------------------------
/static/img/chain/harmony_banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/chain/harmony_banner.jpg
--------------------------------------------------------------------------------
/static/img/chain/harmony_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/chain/harmony_icon@2x.png
--------------------------------------------------------------------------------
/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/favicon.ico
--------------------------------------------------------------------------------
/static/img/icons/MathWallet_Logo_Horizontal_White.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/MathWallet_Logo_Horizontal_White.png
--------------------------------------------------------------------------------
/static/img/icons/dropdown_black@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/dropdown_black@2x.png
--------------------------------------------------------------------------------
/static/img/icons/dropdown_white@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/dropdown_white@2x.png
--------------------------------------------------------------------------------
/static/img/icons/first@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/first@2x.png
--------------------------------------------------------------------------------
/static/img/icons/first_disabled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/first_disabled@2x.png
--------------------------------------------------------------------------------
/static/img/icons/last@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/last@2x.png
--------------------------------------------------------------------------------
/static/img/icons/last_disabled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/last_disabled@2x.png
--------------------------------------------------------------------------------
/static/img/icons/logout_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/logout_blue@2x.png
--------------------------------------------------------------------------------
/static/img/icons/logout_grey@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/logout_grey@2x.png
--------------------------------------------------------------------------------
/static/img/icons/mathwallet_webwallet@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/mathwallet_webwallet@2x.png
--------------------------------------------------------------------------------
/static/img/icons/next@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/next@2x.png
--------------------------------------------------------------------------------
/static/img/icons/next_disabled@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/next_disabled@2x.png
--------------------------------------------------------------------------------
/static/img/icons/phone_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/phone_blue@2x.png
--------------------------------------------------------------------------------
/static/img/icons/previous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/previous.png
--------------------------------------------------------------------------------
/static/img/icons/previous_disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/previous_disabled.png
--------------------------------------------------------------------------------
/static/img/icons/refresh_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/refresh_blue@2x.png
--------------------------------------------------------------------------------
/static/img/icons/refresh_grey@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/refresh_grey@2x.png
--------------------------------------------------------------------------------
/static/img/icons/slider@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathwallet/math-harmony-web-wallet/5bfee0162a00c6189a529bdf2f250c5944fdd95e/static/img/icons/slider@2x.png
--------------------------------------------------------------------------------
/static/js/bignumber.mjs:
--------------------------------------------------------------------------------
1 | /*
2 | * bignumber.js v9.0.0
3 | * A JavaScript library for arbitrary-precision arithmetic.
4 | * https://github.com/MikeMcl/bignumber.js
5 | * Copyright (c) 2019 Michael Mclaughlin
6 | * MIT Licensed.
7 | *
8 | * BigNumber.prototype methods | BigNumber methods
9 | * |
10 | * absoluteValue abs | clone
11 | * comparedTo | config set
12 | * decimalPlaces dp | DECIMAL_PLACES
13 | * dividedBy div | ROUNDING_MODE
14 | * dividedToIntegerBy idiv | EXPONENTIAL_AT
15 | * exponentiatedBy pow | RANGE
16 | * integerValue | CRYPTO
17 | * isEqualTo eq | MODULO_MODE
18 | * isFinite | POW_PRECISION
19 | * isGreaterThan gt | FORMAT
20 | * isGreaterThanOrEqualTo gte | ALPHABET
21 | * isInteger | isBigNumber
22 | * isLessThan lt | maximum max
23 | * isLessThanOrEqualTo lte | minimum min
24 | * isNaN | random
25 | * isNegative | sum
26 | * isPositive |
27 | * isZero |
28 | * minus |
29 | * modulo mod |
30 | * multipliedBy times |
31 | * negated |
32 | * plus |
33 | * precision sd |
34 | * shiftedBy |
35 | * squareRoot sqrt |
36 | * toExponential |
37 | * toFixed |
38 | * toFormat |
39 | * toFraction |
40 | * toJSON |
41 | * toNumber |
42 | * toPrecision |
43 | * toString |
44 | * valueOf |
45 | *
46 | */
47 |
48 |
49 | var
50 | isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i,
51 |
52 | mathceil = Math.ceil,
53 | mathfloor = Math.floor,
54 |
55 | bignumberError = '[BigNumber Error] ',
56 | tooManyDigits = bignumberError + 'Number primitive has more than 15 significant digits: ',
57 |
58 | BASE = 1e14,
59 | LOG_BASE = 14,
60 | MAX_SAFE_INTEGER = 0x1fffffffffffff, // 2^53 - 1
61 | // MAX_INT32 = 0x7fffffff, // 2^31 - 1
62 | POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13],
63 | SQRT_BASE = 1e7,
64 |
65 | // EDITABLE
66 | // The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and
67 | // the arguments to toExponential, toFixed, toFormat, and toPrecision.
68 | MAX = 1E9; // 0 to MAX_INT32
69 |
70 |
71 | /*
72 | * Create and return a BigNumber constructor.
73 | */
74 | function clone(configObject) {
75 | var div, convertBase, parseNumeric,
76 | P = BigNumber.prototype = { constructor: BigNumber, toString: null, valueOf: null },
77 | ONE = new BigNumber(1),
78 |
79 |
80 | //----------------------------- EDITABLE CONFIG DEFAULTS -------------------------------
81 |
82 |
83 | // The default values below must be integers within the inclusive ranges stated.
84 | // The values can also be changed at run-time using BigNumber.set.
85 |
86 | // The maximum number of decimal places for operations involving division.
87 | DECIMAL_PLACES = 20, // 0 to MAX
88 |
89 | // The rounding mode used when rounding to the above decimal places, and when using
90 | // toExponential, toFixed, toFormat and toPrecision, and round (default value).
91 | // UP 0 Away from zero.
92 | // DOWN 1 Towards zero.
93 | // CEIL 2 Towards +Infinity.
94 | // FLOOR 3 Towards -Infinity.
95 | // HALF_UP 4 Towards nearest neighbour. If equidistant, up.
96 | // HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.
97 | // HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.
98 | // HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.
99 | // HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.
100 | ROUNDING_MODE = 4, // 0 to 8
101 |
102 | // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]
103 |
104 | // The exponent value at and beneath which toString returns exponential notation.
105 | // Number type: -7
106 | TO_EXP_NEG = -7, // 0 to -MAX
107 |
108 | // The exponent value at and above which toString returns exponential notation.
109 | // Number type: 21
110 | TO_EXP_POS = 21, // 0 to MAX
111 |
112 | // RANGE : [MIN_EXP, MAX_EXP]
113 |
114 | // The minimum exponent value, beneath which underflow to zero occurs.
115 | // Number type: -324 (5e-324)
116 | MIN_EXP = -1e7, // -1 to -MAX
117 |
118 | // The maximum exponent value, above which overflow to Infinity occurs.
119 | // Number type: 308 (1.7976931348623157e+308)
120 | // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow.
121 | MAX_EXP = 1e7, // 1 to MAX
122 |
123 | // Whether to use cryptographically-secure random number generation, if available.
124 | CRYPTO = false, // true or false
125 |
126 | // The modulo mode used when calculating the modulus: a mod n.
127 | // The quotient (q = a / n) is calculated according to the corresponding rounding mode.
128 | // The remainder (r) is calculated as: r = a - n * q.
129 | //
130 | // UP 0 The remainder is positive if the dividend is negative, else is negative.
131 | // DOWN 1 The remainder has the same sign as the dividend.
132 | // This modulo mode is commonly known as 'truncated division' and is
133 | // equivalent to (a % n) in JavaScript.
134 | // FLOOR 3 The remainder has the same sign as the divisor (Python %).
135 | // HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function.
136 | // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)).
137 | // The remainder is always positive.
138 | //
139 | // The truncated division, floored division, Euclidian division and IEEE 754 remainder
140 | // modes are commonly used for the modulus operation.
141 | // Although the other rounding modes can also be used, they may not give useful results.
142 | MODULO_MODE = 1, // 0 to 9
143 |
144 | // The maximum number of significant digits of the result of the exponentiatedBy operation.
145 | // If POW_PRECISION is 0, there will be unlimited significant digits.
146 | POW_PRECISION = 0, // 0 to MAX
147 |
148 | // The format specification used by the BigNumber.prototype.toFormat method.
149 | FORMAT = {
150 | prefix: '',
151 | groupSize: 3,
152 | secondaryGroupSize: 0,
153 | groupSeparator: ',',
154 | decimalSeparator: '.',
155 | fractionGroupSize: 0,
156 | fractionGroupSeparator: '\xA0', // non-breaking space
157 | suffix: ''
158 | },
159 |
160 | // The alphabet used for base conversion. It must be at least 2 characters long, with no '+',
161 | // '-', '.', whitespace, or repeated character.
162 | // '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_'
163 | ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
164 |
165 |
166 | //------------------------------------------------------------------------------------------
167 |
168 |
169 | // CONSTRUCTOR
170 |
171 |
172 | /*
173 | * The BigNumber constructor and exported function.
174 | * Create and return a new instance of a BigNumber object.
175 | *
176 | * v {number|string|BigNumber} A numeric value.
177 | * [b] {number} The base of v. Integer, 2 to ALPHABET.length inclusive.
178 | */
179 | function BigNumber(v, b) {
180 | var alphabet, c, caseChanged, e, i, isNum, len, str,
181 | x = this;
182 |
183 | // Enable constructor call without `new`.
184 | if (!(x instanceof BigNumber)) return new BigNumber(v, b);
185 |
186 | if (b == null) {
187 |
188 | if (v && v._isBigNumber === true) {
189 | x.s = v.s;
190 |
191 | if (!v.c || v.e > MAX_EXP) {
192 | x.c = x.e = null;
193 | } else if (v.e < MIN_EXP) {
194 | x.c = [x.e = 0];
195 | } else {
196 | x.e = v.e;
197 | x.c = v.c.slice();
198 | }
199 |
200 | return;
201 | }
202 |
203 | if ((isNum = typeof v == 'number') && v * 0 == 0) {
204 |
205 | // Use `1 / n` to handle minus zero also.
206 | x.s = 1 / v < 0 ? (v = -v, -1) : 1;
207 |
208 | // Fast path for integers, where n < 2147483648 (2**31).
209 | if (v === ~~v) {
210 | for (e = 0, i = v; i >= 10; i /= 10, e++);
211 |
212 | if (e > MAX_EXP) {
213 | x.c = x.e = null;
214 | } else {
215 | x.e = e;
216 | x.c = [v];
217 | }
218 |
219 | return;
220 | }
221 |
222 | str = String(v);
223 | } else {
224 |
225 | if (!isNumeric.test(str = String(v))) return parseNumeric(x, str, isNum);
226 |
227 | x.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1;
228 | }
229 |
230 | // Decimal point?
231 | if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
232 |
233 | // Exponential form?
234 | if ((i = str.search(/e/i)) > 0) {
235 |
236 | // Determine exponent.
237 | if (e < 0) e = i;
238 | e += +str.slice(i + 1);
239 | str = str.substring(0, i);
240 | } else if (e < 0) {
241 |
242 | // Integer.
243 | e = str.length;
244 | }
245 |
246 | } else {
247 |
248 | // '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}'
249 | intCheck(b, 2, ALPHABET.length, 'Base');
250 |
251 | // Allow exponential notation to be used with base 10 argument, while
252 | // also rounding to DECIMAL_PLACES as with other bases.
253 | if (b == 10) {
254 | x = new BigNumber(v);
255 | return round(x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE);
256 | }
257 |
258 | str = String(v);
259 |
260 | if (isNum = typeof v == 'number') {
261 |
262 | // Avoid potential interpretation of Infinity and NaN as base 44+ values.
263 | if (v * 0 != 0) return parseNumeric(x, str, isNum, b);
264 |
265 | x.s = 1 / v < 0 ? (str = str.slice(1), -1) : 1;
266 |
267 | // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}'
268 | if (BigNumber.DEBUG && str.replace(/^0\.0*|\./, '').length > 15) {
269 | throw Error
270 | (tooManyDigits + v);
271 | }
272 | } else {
273 | x.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1;
274 | }
275 |
276 | alphabet = ALPHABET.slice(0, b);
277 | e = i = 0;
278 |
279 | // Check that str is a valid base b number.
280 | // Don't use RegExp, so alphabet can contain special characters.
281 | for (len = str.length; i < len; i++) {
282 | if (alphabet.indexOf(c = str.charAt(i)) < 0) {
283 | if (c == '.') {
284 |
285 | // If '.' is not the first character and it has not be found before.
286 | if (i > e) {
287 | e = len;
288 | continue;
289 | }
290 | } else if (!caseChanged) {
291 |
292 | // Allow e.g. hexadecimal 'FF' as well as 'ff'.
293 | if (str == str.toUpperCase() && (str = str.toLowerCase()) ||
294 | str == str.toLowerCase() && (str = str.toUpperCase())) {
295 | caseChanged = true;
296 | i = -1;
297 | e = 0;
298 | continue;
299 | }
300 | }
301 |
302 | return parseNumeric(x, String(v), isNum, b);
303 | }
304 | }
305 |
306 | // Prevent later check for length on converted number.
307 | isNum = false;
308 | str = convertBase(str, b, 10, x.s);
309 |
310 | // Decimal point?
311 | if ((e = str.indexOf('.')) > -1) str = str.replace('.', '');
312 | else e = str.length;
313 | }
314 |
315 | // Determine leading zeros.
316 | for (i = 0; str.charCodeAt(i) === 48; i++);
317 |
318 | // Determine trailing zeros.
319 | for (len = str.length; str.charCodeAt(--len) === 48;);
320 |
321 | if (str = str.slice(i, ++len)) {
322 | len -= i;
323 |
324 | // '[BigNumber Error] Number primitive has more than 15 significant digits: {n}'
325 | if (isNum && BigNumber.DEBUG &&
326 | len > 15 && (v > MAX_SAFE_INTEGER || v !== mathfloor(v))) {
327 | throw Error
328 | (tooManyDigits + (x.s * v));
329 | }
330 |
331 | // Overflow?
332 | if ((e = e - i - 1) > MAX_EXP) {
333 |
334 | // Infinity.
335 | x.c = x.e = null;
336 |
337 | // Underflow?
338 | } else if (e < MIN_EXP) {
339 |
340 | // Zero.
341 | x.c = [x.e = 0];
342 | } else {
343 | x.e = e;
344 | x.c = [];
345 |
346 | // Transform base
347 |
348 | // e is the base 10 exponent.
349 | // i is where to slice str to get the first element of the coefficient array.
350 | i = (e + 1) % LOG_BASE;
351 | if (e < 0) i += LOG_BASE; // i < 1
352 |
353 | if (i < len) {
354 | if (i) x.c.push(+str.slice(0, i));
355 |
356 | for (len -= LOG_BASE; i < len;) {
357 | x.c.push(+str.slice(i, i += LOG_BASE));
358 | }
359 |
360 | i = LOG_BASE - (str = str.slice(i)).length;
361 | } else {
362 | i -= len;
363 | }
364 |
365 | for (; i--; str += '0');
366 | x.c.push(+str);
367 | }
368 | } else {
369 |
370 | // Zero.
371 | x.c = [x.e = 0];
372 | }
373 | }
374 |
375 |
376 | // CONSTRUCTOR PROPERTIES
377 |
378 |
379 | BigNumber.clone = clone;
380 |
381 | BigNumber.ROUND_UP = 0;
382 | BigNumber.ROUND_DOWN = 1;
383 | BigNumber.ROUND_CEIL = 2;
384 | BigNumber.ROUND_FLOOR = 3;
385 | BigNumber.ROUND_HALF_UP = 4;
386 | BigNumber.ROUND_HALF_DOWN = 5;
387 | BigNumber.ROUND_HALF_EVEN = 6;
388 | BigNumber.ROUND_HALF_CEIL = 7;
389 | BigNumber.ROUND_HALF_FLOOR = 8;
390 | BigNumber.EUCLID = 9;
391 |
392 |
393 | /*
394 | * Configure infrequently-changing library-wide settings.
395 | *
396 | * Accept an object with the following optional properties (if the value of a property is
397 | * a number, it must be an integer within the inclusive range stated):
398 | *
399 | * DECIMAL_PLACES {number} 0 to MAX
400 | * ROUNDING_MODE {number} 0 to 8
401 | * EXPONENTIAL_AT {number|number[]} -MAX to MAX or [-MAX to 0, 0 to MAX]
402 | * RANGE {number|number[]} -MAX to MAX (not zero) or [-MAX to -1, 1 to MAX]
403 | * CRYPTO {boolean} true or false
404 | * MODULO_MODE {number} 0 to 9
405 | * POW_PRECISION {number} 0 to MAX
406 | * ALPHABET {string} A string of two or more unique characters which does
407 | * not contain '.'.
408 | * FORMAT {object} An object with some of the following properties:
409 | * prefix {string}
410 | * groupSize {number}
411 | * secondaryGroupSize {number}
412 | * groupSeparator {string}
413 | * decimalSeparator {string}
414 | * fractionGroupSize {number}
415 | * fractionGroupSeparator {string}
416 | * suffix {string}
417 | *
418 | * (The values assigned to the above FORMAT object properties are not checked for validity.)
419 | *
420 | * E.g.
421 | * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })
422 | *
423 | * Ignore properties/parameters set to null or undefined, except for ALPHABET.
424 | *
425 | * Return an object with the properties current values.
426 | */
427 | BigNumber.config = BigNumber.set = function (obj) {
428 | var p, v;
429 |
430 | if (obj != null) {
431 |
432 | if (typeof obj == 'object') {
433 |
434 | // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive.
435 | // '[BigNumber Error] DECIMAL_PLACES {not a primitive number|not an integer|out of range}: {v}'
436 | if (obj.hasOwnProperty(p = 'DECIMAL_PLACES')) {
437 | v = obj[p];
438 | intCheck(v, 0, MAX, p);
439 | DECIMAL_PLACES = v;
440 | }
441 |
442 | // ROUNDING_MODE {number} Integer, 0 to 8 inclusive.
443 | // '[BigNumber Error] ROUNDING_MODE {not a primitive number|not an integer|out of range}: {v}'
444 | if (obj.hasOwnProperty(p = 'ROUNDING_MODE')) {
445 | v = obj[p];
446 | intCheck(v, 0, 8, p);
447 | ROUNDING_MODE = v;
448 | }
449 |
450 | // EXPONENTIAL_AT {number|number[]}
451 | // Integer, -MAX to MAX inclusive or
452 | // [integer -MAX to 0 inclusive, 0 to MAX inclusive].
453 | // '[BigNumber Error] EXPONENTIAL_AT {not a primitive number|not an integer|out of range}: {v}'
454 | if (obj.hasOwnProperty(p = 'EXPONENTIAL_AT')) {
455 | v = obj[p];
456 | if (v && v.pop) {
457 | intCheck(v[0], -MAX, 0, p);
458 | intCheck(v[1], 0, MAX, p);
459 | TO_EXP_NEG = v[0];
460 | TO_EXP_POS = v[1];
461 | } else {
462 | intCheck(v, -MAX, MAX, p);
463 | TO_EXP_NEG = -(TO_EXP_POS = v < 0 ? -v : v);
464 | }
465 | }
466 |
467 | // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or
468 | // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive].
469 | // '[BigNumber Error] RANGE {not a primitive number|not an integer|out of range|cannot be zero}: {v}'
470 | if (obj.hasOwnProperty(p = 'RANGE')) {
471 | v = obj[p];
472 | if (v && v.pop) {
473 | intCheck(v[0], -MAX, -1, p);
474 | intCheck(v[1], 1, MAX, p);
475 | MIN_EXP = v[0];
476 | MAX_EXP = v[1];
477 | } else {
478 | intCheck(v, -MAX, MAX, p);
479 | if (v) {
480 | MIN_EXP = -(MAX_EXP = v < 0 ? -v : v);
481 | } else {
482 | throw Error
483 | (bignumberError + p + ' cannot be zero: ' + v);
484 | }
485 | }
486 | }
487 |
488 | // CRYPTO {boolean} true or false.
489 | // '[BigNumber Error] CRYPTO not true or false: {v}'
490 | // '[BigNumber Error] crypto unavailable'
491 | if (obj.hasOwnProperty(p = 'CRYPTO')) {
492 | v = obj[p];
493 | if (v === !!v) {
494 | if (v) {
495 | if (typeof crypto != 'undefined' && crypto &&
496 | (crypto.getRandomValues || crypto.randomBytes)) {
497 | CRYPTO = v;
498 | } else {
499 | CRYPTO = !v;
500 | throw Error
501 | (bignumberError + 'crypto unavailable');
502 | }
503 | } else {
504 | CRYPTO = v;
505 | }
506 | } else {
507 | throw Error
508 | (bignumberError + p + ' not true or false: ' + v);
509 | }
510 | }
511 |
512 | // MODULO_MODE {number} Integer, 0 to 9 inclusive.
513 | // '[BigNumber Error] MODULO_MODE {not a primitive number|not an integer|out of range}: {v}'
514 | if (obj.hasOwnProperty(p = 'MODULO_MODE')) {
515 | v = obj[p];
516 | intCheck(v, 0, 9, p);
517 | MODULO_MODE = v;
518 | }
519 |
520 | // POW_PRECISION {number} Integer, 0 to MAX inclusive.
521 | // '[BigNumber Error] POW_PRECISION {not a primitive number|not an integer|out of range}: {v}'
522 | if (obj.hasOwnProperty(p = 'POW_PRECISION')) {
523 | v = obj[p];
524 | intCheck(v, 0, MAX, p);
525 | POW_PRECISION = v;
526 | }
527 |
528 | // FORMAT {object}
529 | // '[BigNumber Error] FORMAT not an object: {v}'
530 | if (obj.hasOwnProperty(p = 'FORMAT')) {
531 | v = obj[p];
532 | if (typeof v == 'object') FORMAT = v;
533 | else throw Error
534 | (bignumberError + p + ' not an object: ' + v);
535 | }
536 |
537 | // ALPHABET {string}
538 | // '[BigNumber Error] ALPHABET invalid: {v}'
539 | if (obj.hasOwnProperty(p = 'ALPHABET')) {
540 | v = obj[p];
541 |
542 | // Disallow if only one character,
543 | // or if it contains '+', '-', '.', whitespace, or a repeated character.
544 | if (typeof v == 'string' && !/^.$|[+-.\s]|(.).*\1/.test(v)) {
545 | ALPHABET = v;
546 | } else {
547 | throw Error
548 | (bignumberError + p + ' invalid: ' + v);
549 | }
550 | }
551 |
552 | } else {
553 |
554 | // '[BigNumber Error] Object expected: {v}'
555 | throw Error
556 | (bignumberError + 'Object expected: ' + obj);
557 | }
558 | }
559 |
560 | return {
561 | DECIMAL_PLACES: DECIMAL_PLACES,
562 | ROUNDING_MODE: ROUNDING_MODE,
563 | EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS],
564 | RANGE: [MIN_EXP, MAX_EXP],
565 | CRYPTO: CRYPTO,
566 | MODULO_MODE: MODULO_MODE,
567 | POW_PRECISION: POW_PRECISION,
568 | FORMAT: FORMAT,
569 | ALPHABET: ALPHABET
570 | };
571 | };
572 |
573 |
574 | /*
575 | * Return true if v is a BigNumber instance, otherwise return false.
576 | *
577 | * If BigNumber.DEBUG is true, throw if a BigNumber instance is not well-formed.
578 | *
579 | * v {any}
580 | *
581 | * '[BigNumber Error] Invalid BigNumber: {v}'
582 | */
583 | BigNumber.isBigNumber = function (v) {
584 | if (!v || v._isBigNumber !== true) return false;
585 | if (!BigNumber.DEBUG) return true;
586 |
587 | var i, n,
588 | c = v.c,
589 | e = v.e,
590 | s = v.s;
591 |
592 | out: if ({}.toString.call(c) == '[object Array]') {
593 |
594 | if ((s === 1 || s === -1) && e >= -MAX && e <= MAX && e === mathfloor(e)) {
595 |
596 | // If the first element is zero, the BigNumber value must be zero.
597 | if (c[0] === 0) {
598 | if (e === 0 && c.length === 1) return true;
599 | break out;
600 | }
601 |
602 | // Calculate number of digits that c[0] should have, based on the exponent.
603 | i = (e + 1) % LOG_BASE;
604 | if (i < 1) i += LOG_BASE;
605 |
606 | // Calculate number of digits of c[0].
607 | //if (Math.ceil(Math.log(c[0] + 1) / Math.LN10) == i) {
608 | if (String(c[0]).length == i) {
609 |
610 | for (i = 0; i < c.length; i++) {
611 | n = c[i];
612 | if (n < 0 || n >= BASE || n !== mathfloor(n)) break out;
613 | }
614 |
615 | // Last element cannot be zero, unless it is the only element.
616 | if (n !== 0) return true;
617 | }
618 | }
619 |
620 | // Infinity/NaN
621 | } else if (c === null && e === null && (s === null || s === 1 || s === -1)) {
622 | return true;
623 | }
624 |
625 | throw Error
626 | (bignumberError + 'Invalid BigNumber: ' + v);
627 | };
628 |
629 |
630 | /*
631 | * Return a new BigNumber whose value is the maximum of the arguments.
632 | *
633 | * arguments {number|string|BigNumber}
634 | */
635 | BigNumber.maximum = BigNumber.max = function () {
636 | return maxOrMin(arguments, P.lt);
637 | };
638 |
639 |
640 | /*
641 | * Return a new BigNumber whose value is the minimum of the arguments.
642 | *
643 | * arguments {number|string|BigNumber}
644 | */
645 | BigNumber.minimum = BigNumber.min = function () {
646 | return maxOrMin(arguments, P.gt);
647 | };
648 |
649 |
650 | /*
651 | * Return a new BigNumber with a random value equal to or greater than 0 and less than 1,
652 | * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing
653 | * zeros are produced).
654 | *
655 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
656 | *
657 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp}'
658 | * '[BigNumber Error] crypto unavailable'
659 | */
660 | BigNumber.random = (function () {
661 | var pow2_53 = 0x20000000000000;
662 |
663 | // Return a 53 bit integer n, where 0 <= n < 9007199254740992.
664 | // Check if Math.random() produces more than 32 bits of randomness.
665 | // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits.
666 | // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1.
667 | var random53bitInt = (Math.random() * pow2_53) & 0x1fffff
668 | ? function () { return mathfloor(Math.random() * pow2_53); }
669 | : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) +
670 | (Math.random() * 0x800000 | 0); };
671 |
672 | return function (dp) {
673 | var a, b, e, k, v,
674 | i = 0,
675 | c = [],
676 | rand = new BigNumber(ONE);
677 |
678 | if (dp == null) dp = DECIMAL_PLACES;
679 | else intCheck(dp, 0, MAX);
680 |
681 | k = mathceil(dp / LOG_BASE);
682 |
683 | if (CRYPTO) {
684 |
685 | // Browsers supporting crypto.getRandomValues.
686 | if (crypto.getRandomValues) {
687 |
688 | a = crypto.getRandomValues(new Uint32Array(k *= 2));
689 |
690 | for (; i < k;) {
691 |
692 | // 53 bits:
693 | // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2)
694 | // 11111 11111111 11111111 11111111 11100000 00000000 00000000
695 | // ((Math.pow(2, 32) - 1) >>> 11).toString(2)
696 | // 11111 11111111 11111111
697 | // 0x20000 is 2^21.
698 | v = a[i] * 0x20000 + (a[i + 1] >>> 11);
699 |
700 | // Rejection sampling:
701 | // 0 <= v < 9007199254740992
702 | // Probability that v >= 9e15, is
703 | // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251
704 | if (v >= 9e15) {
705 | b = crypto.getRandomValues(new Uint32Array(2));
706 | a[i] = b[0];
707 | a[i + 1] = b[1];
708 | } else {
709 |
710 | // 0 <= v <= 8999999999999999
711 | // 0 <= (v % 1e14) <= 99999999999999
712 | c.push(v % 1e14);
713 | i += 2;
714 | }
715 | }
716 | i = k / 2;
717 |
718 | // Node.js supporting crypto.randomBytes.
719 | } else if (crypto.randomBytes) {
720 |
721 | // buffer
722 | a = crypto.randomBytes(k *= 7);
723 |
724 | for (; i < k;) {
725 |
726 | // 0x1000000000000 is 2^48, 0x10000000000 is 2^40
727 | // 0x100000000 is 2^32, 0x1000000 is 2^24
728 | // 11111 11111111 11111111 11111111 11111111 11111111 11111111
729 | // 0 <= v < 9007199254740992
730 | v = ((a[i] & 31) * 0x1000000000000) + (a[i + 1] * 0x10000000000) +
731 | (a[i + 2] * 0x100000000) + (a[i + 3] * 0x1000000) +
732 | (a[i + 4] << 16) + (a[i + 5] << 8) + a[i + 6];
733 |
734 | if (v >= 9e15) {
735 | crypto.randomBytes(7).copy(a, i);
736 | } else {
737 |
738 | // 0 <= (v % 1e14) <= 99999999999999
739 | c.push(v % 1e14);
740 | i += 7;
741 | }
742 | }
743 | i = k / 7;
744 | } else {
745 | CRYPTO = false;
746 | throw Error
747 | (bignumberError + 'crypto unavailable');
748 | }
749 | }
750 |
751 | // Use Math.random.
752 | if (!CRYPTO) {
753 |
754 | for (; i < k;) {
755 | v = random53bitInt();
756 | if (v < 9e15) c[i++] = v % 1e14;
757 | }
758 | }
759 |
760 | k = c[--i];
761 | dp %= LOG_BASE;
762 |
763 | // Convert trailing digits to zeros according to dp.
764 | if (k && dp) {
765 | v = POWS_TEN[LOG_BASE - dp];
766 | c[i] = mathfloor(k / v) * v;
767 | }
768 |
769 | // Remove trailing elements which are zero.
770 | for (; c[i] === 0; c.pop(), i--);
771 |
772 | // Zero?
773 | if (i < 0) {
774 | c = [e = 0];
775 | } else {
776 |
777 | // Remove leading elements which are zero and adjust exponent accordingly.
778 | for (e = -1 ; c[0] === 0; c.splice(0, 1), e -= LOG_BASE);
779 |
780 | // Count the digits of the first element of c to determine leading zeros, and...
781 | for (i = 1, v = c[0]; v >= 10; v /= 10, i++);
782 |
783 | // adjust the exponent accordingly.
784 | if (i < LOG_BASE) e -= LOG_BASE - i;
785 | }
786 |
787 | rand.e = e;
788 | rand.c = c;
789 | return rand;
790 | };
791 | })();
792 |
793 |
794 | /*
795 | * Return a BigNumber whose value is the sum of the arguments.
796 | *
797 | * arguments {number|string|BigNumber}
798 | */
799 | BigNumber.sum = function () {
800 | var i = 1,
801 | args = arguments,
802 | sum = new BigNumber(args[0]);
803 | for (; i < args.length;) sum = sum.plus(args[i++]);
804 | return sum;
805 | };
806 |
807 |
808 | // PRIVATE FUNCTIONS
809 |
810 |
811 | // Called by BigNumber and BigNumber.prototype.toString.
812 | convertBase = (function () {
813 | var decimal = '0123456789';
814 |
815 | /*
816 | * Convert string of baseIn to an array of numbers of baseOut.
817 | * Eg. toBaseOut('255', 10, 16) returns [15, 15].
818 | * Eg. toBaseOut('ff', 16, 10) returns [2, 5, 5].
819 | */
820 | function toBaseOut(str, baseIn, baseOut, alphabet) {
821 | var j,
822 | arr = [0],
823 | arrL,
824 | i = 0,
825 | len = str.length;
826 |
827 | for (; i < len;) {
828 | for (arrL = arr.length; arrL--; arr[arrL] *= baseIn);
829 |
830 | arr[0] += alphabet.indexOf(str.charAt(i++));
831 |
832 | for (j = 0; j < arr.length; j++) {
833 |
834 | if (arr[j] > baseOut - 1) {
835 | if (arr[j + 1] == null) arr[j + 1] = 0;
836 | arr[j + 1] += arr[j] / baseOut | 0;
837 | arr[j] %= baseOut;
838 | }
839 | }
840 | }
841 |
842 | return arr.reverse();
843 | }
844 |
845 | // Convert a numeric string of baseIn to a numeric string of baseOut.
846 | // If the caller is toString, we are converting from base 10 to baseOut.
847 | // If the caller is BigNumber, we are converting from baseIn to base 10.
848 | return function (str, baseIn, baseOut, sign, callerIsToString) {
849 | var alphabet, d, e, k, r, x, xc, y,
850 | i = str.indexOf('.'),
851 | dp = DECIMAL_PLACES,
852 | rm = ROUNDING_MODE;
853 |
854 | // Non-integer.
855 | if (i >= 0) {
856 | k = POW_PRECISION;
857 |
858 | // Unlimited precision.
859 | POW_PRECISION = 0;
860 | str = str.replace('.', '');
861 | y = new BigNumber(baseIn);
862 | x = y.pow(str.length - i);
863 | POW_PRECISION = k;
864 |
865 | // Convert str as if an integer, then restore the fraction part by dividing the
866 | // result by its base raised to a power.
867 |
868 | y.c = toBaseOut(toFixedPoint(coeffToString(x.c), x.e, '0'),
869 | 10, baseOut, decimal);
870 | y.e = y.c.length;
871 | }
872 |
873 | // Convert the number as integer.
874 |
875 | xc = toBaseOut(str, baseIn, baseOut, callerIsToString
876 | ? (alphabet = ALPHABET, decimal)
877 | : (alphabet = decimal, ALPHABET));
878 |
879 | // xc now represents str as an integer and converted to baseOut. e is the exponent.
880 | e = k = xc.length;
881 |
882 | // Remove trailing zeros.
883 | for (; xc[--k] == 0; xc.pop());
884 |
885 | // Zero?
886 | if (!xc[0]) return alphabet.charAt(0);
887 |
888 | // Does str represent an integer? If so, no need for the division.
889 | if (i < 0) {
890 | --e;
891 | } else {
892 | x.c = xc;
893 | x.e = e;
894 |
895 | // The sign is needed for correct rounding.
896 | x.s = sign;
897 | x = div(x, y, dp, rm, baseOut);
898 | xc = x.c;
899 | r = x.r;
900 | e = x.e;
901 | }
902 |
903 | // xc now represents str converted to baseOut.
904 |
905 | // THe index of the rounding digit.
906 | d = e + dp + 1;
907 |
908 | // The rounding digit: the digit to the right of the digit that may be rounded up.
909 | i = xc[d];
910 |
911 | // Look at the rounding digits and mode to determine whether to round up.
912 |
913 | k = baseOut / 2;
914 | r = r || d < 0 || xc[d + 1] != null;
915 |
916 | r = rm < 4 ? (i != null || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
917 | : i > k || i == k &&(rm == 4 || r || rm == 6 && xc[d - 1] & 1 ||
918 | rm == (x.s < 0 ? 8 : 7));
919 |
920 | // If the index of the rounding digit is not greater than zero, or xc represents
921 | // zero, then the result of the base conversion is zero or, if rounding up, a value
922 | // such as 0.00001.
923 | if (d < 1 || !xc[0]) {
924 |
925 | // 1^-dp or 0
926 | str = r ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0);
927 | } else {
928 |
929 | // Truncate xc to the required number of decimal places.
930 | xc.length = d;
931 |
932 | // Round up?
933 | if (r) {
934 |
935 | // Rounding up may mean the previous digit has to be rounded up and so on.
936 | for (--baseOut; ++xc[--d] > baseOut;) {
937 | xc[d] = 0;
938 |
939 | if (!d) {
940 | ++e;
941 | xc = [1].concat(xc);
942 | }
943 | }
944 | }
945 |
946 | // Determine trailing zeros.
947 | for (k = xc.length; !xc[--k];);
948 |
949 | // E.g. [4, 11, 15] becomes 4bf.
950 | for (i = 0, str = ''; i <= k; str += alphabet.charAt(xc[i++]));
951 |
952 | // Add leading zeros, decimal point and trailing zeros as required.
953 | str = toFixedPoint(str, e, alphabet.charAt(0));
954 | }
955 |
956 | // The caller will add the sign.
957 | return str;
958 | };
959 | })();
960 |
961 |
962 | // Perform division in the specified base. Called by div and convertBase.
963 | div = (function () {
964 |
965 | // Assume non-zero x and k.
966 | function multiply(x, k, base) {
967 | var m, temp, xlo, xhi,
968 | carry = 0,
969 | i = x.length,
970 | klo = k % SQRT_BASE,
971 | khi = k / SQRT_BASE | 0;
972 |
973 | for (x = x.slice(); i--;) {
974 | xlo = x[i] % SQRT_BASE;
975 | xhi = x[i] / SQRT_BASE | 0;
976 | m = khi * xlo + xhi * klo;
977 | temp = klo * xlo + ((m % SQRT_BASE) * SQRT_BASE) + carry;
978 | carry = (temp / base | 0) + (m / SQRT_BASE | 0) + khi * xhi;
979 | x[i] = temp % base;
980 | }
981 |
982 | if (carry) x = [carry].concat(x);
983 |
984 | return x;
985 | }
986 |
987 | function compare(a, b, aL, bL) {
988 | var i, cmp;
989 |
990 | if (aL != bL) {
991 | cmp = aL > bL ? 1 : -1;
992 | } else {
993 |
994 | for (i = cmp = 0; i < aL; i++) {
995 |
996 | if (a[i] != b[i]) {
997 | cmp = a[i] > b[i] ? 1 : -1;
998 | break;
999 | }
1000 | }
1001 | }
1002 |
1003 | return cmp;
1004 | }
1005 |
1006 | function subtract(a, b, aL, base) {
1007 | var i = 0;
1008 |
1009 | // Subtract b from a.
1010 | for (; aL--;) {
1011 | a[aL] -= i;
1012 | i = a[aL] < b[aL] ? 1 : 0;
1013 | a[aL] = i * base + a[aL] - b[aL];
1014 | }
1015 |
1016 | // Remove leading zeros.
1017 | for (; !a[0] && a.length > 1; a.splice(0, 1));
1018 | }
1019 |
1020 | // x: dividend, y: divisor.
1021 | return function (x, y, dp, rm, base) {
1022 | var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0,
1023 | yL, yz,
1024 | s = x.s == y.s ? 1 : -1,
1025 | xc = x.c,
1026 | yc = y.c;
1027 |
1028 | // Either NaN, Infinity or 0?
1029 | if (!xc || !xc[0] || !yc || !yc[0]) {
1030 |
1031 | return new BigNumber(
1032 |
1033 | // Return NaN if either NaN, or both Infinity or 0.
1034 | !x.s || !y.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN :
1035 |
1036 | // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0.
1037 | xc && xc[0] == 0 || !yc ? s * 0 : s / 0
1038 | );
1039 | }
1040 |
1041 | q = new BigNumber(s);
1042 | qc = q.c = [];
1043 | e = x.e - y.e;
1044 | s = dp + e + 1;
1045 |
1046 | if (!base) {
1047 | base = BASE;
1048 | e = bitFloor(x.e / LOG_BASE) - bitFloor(y.e / LOG_BASE);
1049 | s = s / LOG_BASE | 0;
1050 | }
1051 |
1052 | // Result exponent may be one less then the current value of e.
1053 | // The coefficients of the BigNumbers from convertBase may have trailing zeros.
1054 | for (i = 0; yc[i] == (xc[i] || 0); i++);
1055 |
1056 | if (yc[i] > (xc[i] || 0)) e--;
1057 |
1058 | if (s < 0) {
1059 | qc.push(1);
1060 | more = true;
1061 | } else {
1062 | xL = xc.length;
1063 | yL = yc.length;
1064 | i = 0;
1065 | s += 2;
1066 |
1067 | // Normalise xc and yc so highest order digit of yc is >= base / 2.
1068 |
1069 | n = mathfloor(base / (yc[0] + 1));
1070 |
1071 | // Not necessary, but to handle odd bases where yc[0] == (base / 2) - 1.
1072 | // if (n > 1 || n++ == 1 && yc[0] < base / 2) {
1073 | if (n > 1) {
1074 | yc = multiply(yc, n, base);
1075 | xc = multiply(xc, n, base);
1076 | yL = yc.length;
1077 | xL = xc.length;
1078 | }
1079 |
1080 | xi = yL;
1081 | rem = xc.slice(0, yL);
1082 | remL = rem.length;
1083 |
1084 | // Add zeros to make remainder as long as divisor.
1085 | for (; remL < yL; rem[remL++] = 0);
1086 | yz = yc.slice();
1087 | yz = [0].concat(yz);
1088 | yc0 = yc[0];
1089 | if (yc[1] >= base / 2) yc0++;
1090 | // Not necessary, but to prevent trial digit n > base, when using base 3.
1091 | // else if (base == 3 && yc0 == 1) yc0 = 1 + 1e-15;
1092 |
1093 | do {
1094 | n = 0;
1095 |
1096 | // Compare divisor and remainder.
1097 | cmp = compare(yc, rem, yL, remL);
1098 |
1099 | // If divisor < remainder.
1100 | if (cmp < 0) {
1101 |
1102 | // Calculate trial digit, n.
1103 |
1104 | rem0 = rem[0];
1105 | if (yL != remL) rem0 = rem0 * base + (rem[1] || 0);
1106 |
1107 | // n is how many times the divisor goes into the current remainder.
1108 | n = mathfloor(rem0 / yc0);
1109 |
1110 | // Algorithm:
1111 | // product = divisor multiplied by trial digit (n).
1112 | // Compare product and remainder.
1113 | // If product is greater than remainder:
1114 | // Subtract divisor from product, decrement trial digit.
1115 | // Subtract product from remainder.
1116 | // If product was less than remainder at the last compare:
1117 | // Compare new remainder and divisor.
1118 | // If remainder is greater than divisor:
1119 | // Subtract divisor from remainder, increment trial digit.
1120 |
1121 | if (n > 1) {
1122 |
1123 | // n may be > base only when base is 3.
1124 | if (n >= base) n = base - 1;
1125 |
1126 | // product = divisor * trial digit.
1127 | prod = multiply(yc, n, base);
1128 | prodL = prod.length;
1129 | remL = rem.length;
1130 |
1131 | // Compare product and remainder.
1132 | // If product > remainder then trial digit n too high.
1133 | // n is 1 too high about 5% of the time, and is not known to have
1134 | // ever been more than 1 too high.
1135 | while (compare(prod, rem, prodL, remL) == 1) {
1136 | n--;
1137 |
1138 | // Subtract divisor from product.
1139 | subtract(prod, yL < prodL ? yz : yc, prodL, base);
1140 | prodL = prod.length;
1141 | cmp = 1;
1142 | }
1143 | } else {
1144 |
1145 | // n is 0 or 1, cmp is -1.
1146 | // If n is 0, there is no need to compare yc and rem again below,
1147 | // so change cmp to 1 to avoid it.
1148 | // If n is 1, leave cmp as -1, so yc and rem are compared again.
1149 | if (n == 0) {
1150 |
1151 | // divisor < remainder, so n must be at least 1.
1152 | cmp = n = 1;
1153 | }
1154 |
1155 | // product = divisor
1156 | prod = yc.slice();
1157 | prodL = prod.length;
1158 | }
1159 |
1160 | if (prodL < remL) prod = [0].concat(prod);
1161 |
1162 | // Subtract product from remainder.
1163 | subtract(rem, prod, remL, base);
1164 | remL = rem.length;
1165 |
1166 | // If product was < remainder.
1167 | if (cmp == -1) {
1168 |
1169 | // Compare divisor and new remainder.
1170 | // If divisor < new remainder, subtract divisor from remainder.
1171 | // Trial digit n too low.
1172 | // n is 1 too low about 5% of the time, and very rarely 2 too low.
1173 | while (compare(yc, rem, yL, remL) < 1) {
1174 | n++;
1175 |
1176 | // Subtract divisor from remainder.
1177 | subtract(rem, yL < remL ? yz : yc, remL, base);
1178 | remL = rem.length;
1179 | }
1180 | }
1181 | } else if (cmp === 0) {
1182 | n++;
1183 | rem = [0];
1184 | } // else cmp === 1 and n will be 0
1185 |
1186 | // Add the next digit, n, to the result array.
1187 | qc[i++] = n;
1188 |
1189 | // Update the remainder.
1190 | if (rem[0]) {
1191 | rem[remL++] = xc[xi] || 0;
1192 | } else {
1193 | rem = [xc[xi]];
1194 | remL = 1;
1195 | }
1196 | } while ((xi++ < xL || rem[0] != null) && s--);
1197 |
1198 | more = rem[0] != null;
1199 |
1200 | // Leading zero?
1201 | if (!qc[0]) qc.splice(0, 1);
1202 | }
1203 |
1204 | if (base == BASE) {
1205 |
1206 | // To calculate q.e, first get the number of digits of qc[0].
1207 | for (i = 1, s = qc[0]; s >= 10; s /= 10, i++);
1208 |
1209 | round(q, dp + (q.e = i + e * LOG_BASE - 1) + 1, rm, more);
1210 |
1211 | // Caller is convertBase.
1212 | } else {
1213 | q.e = e;
1214 | q.r = +more;
1215 | }
1216 |
1217 | return q;
1218 | };
1219 | })();
1220 |
1221 |
1222 | /*
1223 | * Return a string representing the value of BigNumber n in fixed-point or exponential
1224 | * notation rounded to the specified decimal places or significant digits.
1225 | *
1226 | * n: a BigNumber.
1227 | * i: the index of the last digit required (i.e. the digit that may be rounded up).
1228 | * rm: the rounding mode.
1229 | * id: 1 (toExponential) or 2 (toPrecision).
1230 | */
1231 | function format(n, i, rm, id) {
1232 | var c0, e, ne, len, str;
1233 |
1234 | if (rm == null) rm = ROUNDING_MODE;
1235 | else intCheck(rm, 0, 8);
1236 |
1237 | if (!n.c) return n.toString();
1238 |
1239 | c0 = n.c[0];
1240 | ne = n.e;
1241 |
1242 | if (i == null) {
1243 | str = coeffToString(n.c);
1244 | str = id == 1 || id == 2 && (ne <= TO_EXP_NEG || ne >= TO_EXP_POS)
1245 | ? toExponential(str, ne)
1246 | : toFixedPoint(str, ne, '0');
1247 | } else {
1248 | n = round(new BigNumber(n), i, rm);
1249 |
1250 | // n.e may have changed if the value was rounded up.
1251 | e = n.e;
1252 |
1253 | str = coeffToString(n.c);
1254 | len = str.length;
1255 |
1256 | // toPrecision returns exponential notation if the number of significant digits
1257 | // specified is less than the number of digits necessary to represent the integer
1258 | // part of the value in fixed-point notation.
1259 |
1260 | // Exponential notation.
1261 | if (id == 1 || id == 2 && (i <= e || e <= TO_EXP_NEG)) {
1262 |
1263 | // Append zeros?
1264 | for (; len < i; str += '0', len++);
1265 | str = toExponential(str, e);
1266 |
1267 | // Fixed-point notation.
1268 | } else {
1269 | i -= ne;
1270 | str = toFixedPoint(str, e, '0');
1271 |
1272 | // Append zeros?
1273 | if (e + 1 > len) {
1274 | if (--i > 0) for (str += '.'; i--; str += '0');
1275 | } else {
1276 | i += e - len;
1277 | if (i > 0) {
1278 | if (e + 1 == len) str += '.';
1279 | for (; i--; str += '0');
1280 | }
1281 | }
1282 | }
1283 | }
1284 |
1285 | return n.s < 0 && c0 ? '-' + str : str;
1286 | }
1287 |
1288 |
1289 | // Handle BigNumber.max and BigNumber.min.
1290 | function maxOrMin(args, method) {
1291 | var n,
1292 | i = 1,
1293 | m = new BigNumber(args[0]);
1294 |
1295 | for (; i < args.length; i++) {
1296 | n = new BigNumber(args[i]);
1297 |
1298 | // If any number is NaN, return NaN.
1299 | if (!n.s) {
1300 | m = n;
1301 | break;
1302 | } else if (method.call(m, n)) {
1303 | m = n;
1304 | }
1305 | }
1306 |
1307 | return m;
1308 | }
1309 |
1310 |
1311 | /*
1312 | * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP.
1313 | * Called by minus, plus and times.
1314 | */
1315 | function normalise(n, c, e) {
1316 | var i = 1,
1317 | j = c.length;
1318 |
1319 | // Remove trailing zeros.
1320 | for (; !c[--j]; c.pop());
1321 |
1322 | // Calculate the base 10 exponent. First get the number of digits of c[0].
1323 | for (j = c[0]; j >= 10; j /= 10, i++);
1324 |
1325 | // Overflow?
1326 | if ((e = i + e * LOG_BASE - 1) > MAX_EXP) {
1327 |
1328 | // Infinity.
1329 | n.c = n.e = null;
1330 |
1331 | // Underflow?
1332 | } else if (e < MIN_EXP) {
1333 |
1334 | // Zero.
1335 | n.c = [n.e = 0];
1336 | } else {
1337 | n.e = e;
1338 | n.c = c;
1339 | }
1340 |
1341 | return n;
1342 | }
1343 |
1344 |
1345 | // Handle values that fail the validity test in BigNumber.
1346 | parseNumeric = (function () {
1347 | var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i,
1348 | dotAfter = /^([^.]+)\.$/,
1349 | dotBefore = /^\.([^.]+)$/,
1350 | isInfinityOrNaN = /^-?(Infinity|NaN)$/,
1351 | whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g;
1352 |
1353 | return function (x, str, isNum, b) {
1354 | var base,
1355 | s = isNum ? str : str.replace(whitespaceOrPlus, '');
1356 |
1357 | // No exception on ±Infinity or NaN.
1358 | if (isInfinityOrNaN.test(s)) {
1359 | x.s = isNaN(s) ? null : s < 0 ? -1 : 1;
1360 | } else {
1361 | if (!isNum) {
1362 |
1363 | // basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i
1364 | s = s.replace(basePrefix, function (m, p1, p2) {
1365 | base = (p2 = p2.toLowerCase()) == 'x' ? 16 : p2 == 'b' ? 2 : 8;
1366 | return !b || b == base ? p1 : m;
1367 | });
1368 |
1369 | if (b) {
1370 | base = b;
1371 |
1372 | // E.g. '1.' to '1', '.1' to '0.1'
1373 | s = s.replace(dotAfter, '$1').replace(dotBefore, '0.$1');
1374 | }
1375 |
1376 | if (str != s) return new BigNumber(s, base);
1377 | }
1378 |
1379 | // '[BigNumber Error] Not a number: {n}'
1380 | // '[BigNumber Error] Not a base {b} number: {n}'
1381 | if (BigNumber.DEBUG) {
1382 | throw Error
1383 | (bignumberError + 'Not a' + (b ? ' base ' + b : '') + ' number: ' + str);
1384 | }
1385 |
1386 | // NaN
1387 | x.s = null;
1388 | }
1389 |
1390 | x.c = x.e = null;
1391 | }
1392 | })();
1393 |
1394 |
1395 | /*
1396 | * Round x to sd significant digits using rounding mode rm. Check for over/under-flow.
1397 | * If r is truthy, it is known that there are more digits after the rounding digit.
1398 | */
1399 | function round(x, sd, rm, r) {
1400 | var d, i, j, k, n, ni, rd,
1401 | xc = x.c,
1402 | pows10 = POWS_TEN;
1403 |
1404 | // if x is not Infinity or NaN...
1405 | if (xc) {
1406 |
1407 | // rd is the rounding digit, i.e. the digit after the digit that may be rounded up.
1408 | // n is a base 1e14 number, the value of the element of array x.c containing rd.
1409 | // ni is the index of n within x.c.
1410 | // d is the number of digits of n.
1411 | // i is the index of rd within n including leading zeros.
1412 | // j is the actual index of rd within n (if < 0, rd is a leading zero).
1413 | out: {
1414 |
1415 | // Get the number of digits of the first element of xc.
1416 | for (d = 1, k = xc[0]; k >= 10; k /= 10, d++);
1417 | i = sd - d;
1418 |
1419 | // If the rounding digit is in the first element of xc...
1420 | if (i < 0) {
1421 | i += LOG_BASE;
1422 | j = sd;
1423 | n = xc[ni = 0];
1424 |
1425 | // Get the rounding digit at index j of n.
1426 | rd = n / pows10[d - j - 1] % 10 | 0;
1427 | } else {
1428 | ni = mathceil((i + 1) / LOG_BASE);
1429 |
1430 | if (ni >= xc.length) {
1431 |
1432 | if (r) {
1433 |
1434 | // Needed by sqrt.
1435 | for (; xc.length <= ni; xc.push(0));
1436 | n = rd = 0;
1437 | d = 1;
1438 | i %= LOG_BASE;
1439 | j = i - LOG_BASE + 1;
1440 | } else {
1441 | break out;
1442 | }
1443 | } else {
1444 | n = k = xc[ni];
1445 |
1446 | // Get the number of digits of n.
1447 | for (d = 1; k >= 10; k /= 10, d++);
1448 |
1449 | // Get the index of rd within n.
1450 | i %= LOG_BASE;
1451 |
1452 | // Get the index of rd within n, adjusted for leading zeros.
1453 | // The number of leading zeros of n is given by LOG_BASE - d.
1454 | j = i - LOG_BASE + d;
1455 |
1456 | // Get the rounding digit at index j of n.
1457 | rd = j < 0 ? 0 : n / pows10[d - j - 1] % 10 | 0;
1458 | }
1459 | }
1460 |
1461 | r = r || sd < 0 ||
1462 |
1463 | // Are there any non-zero digits after the rounding digit?
1464 | // The expression n % pows10[d - j - 1] returns all digits of n to the right
1465 | // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714.
1466 | xc[ni + 1] != null || (j < 0 ? n : n % pows10[d - j - 1]);
1467 |
1468 | r = rm < 4
1469 | ? (rd || r) && (rm == 0 || rm == (x.s < 0 ? 3 : 2))
1470 | : rd > 5 || rd == 5 && (rm == 4 || r || rm == 6 &&
1471 |
1472 | // Check whether the digit to the left of the rounding digit is odd.
1473 | ((i > 0 ? j > 0 ? n / pows10[d - j] : 0 : xc[ni - 1]) % 10) & 1 ||
1474 | rm == (x.s < 0 ? 8 : 7));
1475 |
1476 | if (sd < 1 || !xc[0]) {
1477 | xc.length = 0;
1478 |
1479 | if (r) {
1480 |
1481 | // Convert sd to decimal places.
1482 | sd -= x.e + 1;
1483 |
1484 | // 1, 0.1, 0.01, 0.001, 0.0001 etc.
1485 | xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE];
1486 | x.e = -sd || 0;
1487 | } else {
1488 |
1489 | // Zero.
1490 | xc[0] = x.e = 0;
1491 | }
1492 |
1493 | return x;
1494 | }
1495 |
1496 | // Remove excess digits.
1497 | if (i == 0) {
1498 | xc.length = ni;
1499 | k = 1;
1500 | ni--;
1501 | } else {
1502 | xc.length = ni + 1;
1503 | k = pows10[LOG_BASE - i];
1504 |
1505 | // E.g. 56700 becomes 56000 if 7 is the rounding digit.
1506 | // j > 0 means i > number of leading zeros of n.
1507 | xc[ni] = j > 0 ? mathfloor(n / pows10[d - j] % pows10[j]) * k : 0;
1508 | }
1509 |
1510 | // Round up?
1511 | if (r) {
1512 |
1513 | for (; ;) {
1514 |
1515 | // If the digit to be rounded up is in the first element of xc...
1516 | if (ni == 0) {
1517 |
1518 | // i will be the length of xc[0] before k is added.
1519 | for (i = 1, j = xc[0]; j >= 10; j /= 10, i++);
1520 | j = xc[0] += k;
1521 | for (k = 1; j >= 10; j /= 10, k++);
1522 |
1523 | // if i != k the length has increased.
1524 | if (i != k) {
1525 | x.e++;
1526 | if (xc[0] == BASE) xc[0] = 1;
1527 | }
1528 |
1529 | break;
1530 | } else {
1531 | xc[ni] += k;
1532 | if (xc[ni] != BASE) break;
1533 | xc[ni--] = 0;
1534 | k = 1;
1535 | }
1536 | }
1537 | }
1538 |
1539 | // Remove trailing zeros.
1540 | for (i = xc.length; xc[--i] === 0; xc.pop());
1541 | }
1542 |
1543 | // Overflow? Infinity.
1544 | if (x.e > MAX_EXP) {
1545 | x.c = x.e = null;
1546 |
1547 | // Underflow? Zero.
1548 | } else if (x.e < MIN_EXP) {
1549 | x.c = [x.e = 0];
1550 | }
1551 | }
1552 |
1553 | return x;
1554 | }
1555 |
1556 |
1557 | function valueOf(n) {
1558 | var str,
1559 | e = n.e;
1560 |
1561 | if (e === null) return n.toString();
1562 |
1563 | str = coeffToString(n.c);
1564 |
1565 | str = e <= TO_EXP_NEG || e >= TO_EXP_POS
1566 | ? toExponential(str, e)
1567 | : toFixedPoint(str, e, '0');
1568 |
1569 | return n.s < 0 ? '-' + str : str;
1570 | }
1571 |
1572 |
1573 | // PROTOTYPE/INSTANCE METHODS
1574 |
1575 |
1576 | /*
1577 | * Return a new BigNumber whose value is the absolute value of this BigNumber.
1578 | */
1579 | P.absoluteValue = P.abs = function () {
1580 | var x = new BigNumber(this);
1581 | if (x.s < 0) x.s = 1;
1582 | return x;
1583 | };
1584 |
1585 |
1586 | /*
1587 | * Return
1588 | * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b),
1589 | * -1 if the value of this BigNumber is less than the value of BigNumber(y, b),
1590 | * 0 if they have the same value,
1591 | * or null if the value of either is NaN.
1592 | */
1593 | P.comparedTo = function (y, b) {
1594 | return compare(this, new BigNumber(y, b));
1595 | };
1596 |
1597 |
1598 | /*
1599 | * If dp is undefined or null or true or false, return the number of decimal places of the
1600 | * value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN.
1601 | *
1602 | * Otherwise, if dp is a number, return a new BigNumber whose value is the value of this
1603 | * BigNumber rounded to a maximum of dp decimal places using rounding mode rm, or
1604 | * ROUNDING_MODE if rm is omitted.
1605 | *
1606 | * [dp] {number} Decimal places: integer, 0 to MAX inclusive.
1607 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
1608 | *
1609 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
1610 | */
1611 | P.decimalPlaces = P.dp = function (dp, rm) {
1612 | var c, n, v,
1613 | x = this;
1614 |
1615 | if (dp != null) {
1616 | intCheck(dp, 0, MAX);
1617 | if (rm == null) rm = ROUNDING_MODE;
1618 | else intCheck(rm, 0, 8);
1619 |
1620 | return round(new BigNumber(x), dp + x.e + 1, rm);
1621 | }
1622 |
1623 | if (!(c = x.c)) return null;
1624 | n = ((v = c.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE;
1625 |
1626 | // Subtract the number of trailing zeros of the last number.
1627 | if (v = c[v]) for (; v % 10 == 0; v /= 10, n--);
1628 | if (n < 0) n = 0;
1629 |
1630 | return n;
1631 | };
1632 |
1633 |
1634 | /*
1635 | * n / 0 = I
1636 | * n / N = N
1637 | * n / I = 0
1638 | * 0 / n = 0
1639 | * 0 / 0 = N
1640 | * 0 / N = N
1641 | * 0 / I = 0
1642 | * N / n = N
1643 | * N / 0 = N
1644 | * N / N = N
1645 | * N / I = N
1646 | * I / n = I
1647 | * I / 0 = I
1648 | * I / N = N
1649 | * I / I = N
1650 | *
1651 | * Return a new BigNumber whose value is the value of this BigNumber divided by the value of
1652 | * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE.
1653 | */
1654 | P.dividedBy = P.div = function (y, b) {
1655 | return div(this, new BigNumber(y, b), DECIMAL_PLACES, ROUNDING_MODE);
1656 | };
1657 |
1658 |
1659 | /*
1660 | * Return a new BigNumber whose value is the integer part of dividing the value of this
1661 | * BigNumber by the value of BigNumber(y, b).
1662 | */
1663 | P.dividedToIntegerBy = P.idiv = function (y, b) {
1664 | return div(this, new BigNumber(y, b), 0, 1);
1665 | };
1666 |
1667 |
1668 | /*
1669 | * Return a BigNumber whose value is the value of this BigNumber exponentiated by n.
1670 | *
1671 | * If m is present, return the result modulo m.
1672 | * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.
1673 | * If POW_PRECISION is non-zero and m is not present, round to POW_PRECISION using ROUNDING_MODE.
1674 | *
1675 | * The modular power operation works efficiently when x, n, and m are integers, otherwise it
1676 | * is equivalent to calculating x.exponentiatedBy(n).modulo(m) with a POW_PRECISION of 0.
1677 | *
1678 | * n {number|string|BigNumber} The exponent. An integer.
1679 | * [m] {number|string|BigNumber} The modulus.
1680 | *
1681 | * '[BigNumber Error] Exponent not an integer: {n}'
1682 | */
1683 | P.exponentiatedBy = P.pow = function (n, m) {
1684 | var half, isModExp, i, k, more, nIsBig, nIsNeg, nIsOdd, y,
1685 | x = this;
1686 |
1687 | n = new BigNumber(n);
1688 |
1689 | // Allow NaN and ±Infinity, but not other non-integers.
1690 | if (n.c && !n.isInteger()) {
1691 | throw Error
1692 | (bignumberError + 'Exponent not an integer: ' + valueOf(n));
1693 | }
1694 |
1695 | if (m != null) m = new BigNumber(m);
1696 |
1697 | // Exponent of MAX_SAFE_INTEGER is 15.
1698 | nIsBig = n.e > 14;
1699 |
1700 | // If x is NaN, ±Infinity, ±0 or ±1, or n is ±Infinity, NaN or ±0.
1701 | if (!x.c || !x.c[0] || x.c[0] == 1 && !x.e && x.c.length == 1 || !n.c || !n.c[0]) {
1702 |
1703 | // The sign of the result of pow when x is negative depends on the evenness of n.
1704 | // If +n overflows to ±Infinity, the evenness of n would be not be known.
1705 | y = new BigNumber(Math.pow(+valueOf(x), nIsBig ? 2 - isOdd(n) : +valueOf(n)));
1706 | return m ? y.mod(m) : y;
1707 | }
1708 |
1709 | nIsNeg = n.s < 0;
1710 |
1711 | if (m) {
1712 |
1713 | // x % m returns NaN if abs(m) is zero, or m is NaN.
1714 | if (m.c ? !m.c[0] : !m.s) return new BigNumber(NaN);
1715 |
1716 | isModExp = !nIsNeg && x.isInteger() && m.isInteger();
1717 |
1718 | if (isModExp) x = x.mod(m);
1719 |
1720 | // Overflow to ±Infinity: >=2**1e10 or >=1.0000024**1e15.
1721 | // Underflow to ±0: <=0.79**1e10 or <=0.9999975**1e15.
1722 | } else if (n.e > 9 && (x.e > 0 || x.e < -1 || (x.e == 0
1723 | // [1, 240000000]
1724 | ? x.c[0] > 1 || nIsBig && x.c[1] >= 24e7
1725 | // [80000000000000] [99999750000000]
1726 | : x.c[0] < 8e13 || nIsBig && x.c[0] <= 9999975e7))) {
1727 |
1728 | // If x is negative and n is odd, k = -0, else k = 0.
1729 | k = x.s < 0 && isOdd(n) ? -0 : 0;
1730 |
1731 | // If x >= 1, k = ±Infinity.
1732 | if (x.e > -1) k = 1 / k;
1733 |
1734 | // If n is negative return ±0, else return ±Infinity.
1735 | return new BigNumber(nIsNeg ? 1 / k : k);
1736 |
1737 | } else if (POW_PRECISION) {
1738 |
1739 | // Truncating each coefficient array to a length of k after each multiplication
1740 | // equates to truncating significant digits to POW_PRECISION + [28, 41],
1741 | // i.e. there will be a minimum of 28 guard digits retained.
1742 | k = mathceil(POW_PRECISION / LOG_BASE + 2);
1743 | }
1744 |
1745 | if (nIsBig) {
1746 | half = new BigNumber(0.5);
1747 | if (nIsNeg) n.s = 1;
1748 | nIsOdd = isOdd(n);
1749 | } else {
1750 | i = Math.abs(+valueOf(n));
1751 | nIsOdd = i % 2;
1752 | }
1753 |
1754 | y = new BigNumber(ONE);
1755 |
1756 | // Performs 54 loop iterations for n of 9007199254740991.
1757 | for (; ;) {
1758 |
1759 | if (nIsOdd) {
1760 | y = y.times(x);
1761 | if (!y.c) break;
1762 |
1763 | if (k) {
1764 | if (y.c.length > k) y.c.length = k;
1765 | } else if (isModExp) {
1766 | y = y.mod(m); //y = y.minus(div(y, m, 0, MODULO_MODE).times(m));
1767 | }
1768 | }
1769 |
1770 | if (i) {
1771 | i = mathfloor(i / 2);
1772 | if (i === 0) break;
1773 | nIsOdd = i % 2;
1774 | } else {
1775 | n = n.times(half);
1776 | round(n, n.e + 1, 1);
1777 |
1778 | if (n.e > 14) {
1779 | nIsOdd = isOdd(n);
1780 | } else {
1781 | i = +valueOf(n);
1782 | if (i === 0) break;
1783 | nIsOdd = i % 2;
1784 | }
1785 | }
1786 |
1787 | x = x.times(x);
1788 |
1789 | if (k) {
1790 | if (x.c && x.c.length > k) x.c.length = k;
1791 | } else if (isModExp) {
1792 | x = x.mod(m); //x = x.minus(div(x, m, 0, MODULO_MODE).times(m));
1793 | }
1794 | }
1795 |
1796 | if (isModExp) return y;
1797 | if (nIsNeg) y = ONE.div(y);
1798 |
1799 | return m ? y.mod(m) : k ? round(y, POW_PRECISION, ROUNDING_MODE, more) : y;
1800 | };
1801 |
1802 |
1803 | /*
1804 | * Return a new BigNumber whose value is the value of this BigNumber rounded to an integer
1805 | * using rounding mode rm, or ROUNDING_MODE if rm is omitted.
1806 | *
1807 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
1808 | *
1809 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {rm}'
1810 | */
1811 | P.integerValue = function (rm) {
1812 | var n = new BigNumber(this);
1813 | if (rm == null) rm = ROUNDING_MODE;
1814 | else intCheck(rm, 0, 8);
1815 | return round(n, n.e + 1, rm);
1816 | };
1817 |
1818 |
1819 | /*
1820 | * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b),
1821 | * otherwise return false.
1822 | */
1823 | P.isEqualTo = P.eq = function (y, b) {
1824 | return compare(this, new BigNumber(y, b)) === 0;
1825 | };
1826 |
1827 |
1828 | /*
1829 | * Return true if the value of this BigNumber is a finite number, otherwise return false.
1830 | */
1831 | P.isFinite = function () {
1832 | return !!this.c;
1833 | };
1834 |
1835 |
1836 | /*
1837 | * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b),
1838 | * otherwise return false.
1839 | */
1840 | P.isGreaterThan = P.gt = function (y, b) {
1841 | return compare(this, new BigNumber(y, b)) > 0;
1842 | };
1843 |
1844 |
1845 | /*
1846 | * Return true if the value of this BigNumber is greater than or equal to the value of
1847 | * BigNumber(y, b), otherwise return false.
1848 | */
1849 | P.isGreaterThanOrEqualTo = P.gte = function (y, b) {
1850 | return (b = compare(this, new BigNumber(y, b))) === 1 || b === 0;
1851 |
1852 | };
1853 |
1854 |
1855 | /*
1856 | * Return true if the value of this BigNumber is an integer, otherwise return false.
1857 | */
1858 | P.isInteger = function () {
1859 | return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2;
1860 | };
1861 |
1862 |
1863 | /*
1864 | * Return true if the value of this BigNumber is less than the value of BigNumber(y, b),
1865 | * otherwise return false.
1866 | */
1867 | P.isLessThan = P.lt = function (y, b) {
1868 | return compare(this, new BigNumber(y, b)) < 0;
1869 | };
1870 |
1871 |
1872 | /*
1873 | * Return true if the value of this BigNumber is less than or equal to the value of
1874 | * BigNumber(y, b), otherwise return false.
1875 | */
1876 | P.isLessThanOrEqualTo = P.lte = function (y, b) {
1877 | return (b = compare(this, new BigNumber(y, b))) === -1 || b === 0;
1878 | };
1879 |
1880 |
1881 | /*
1882 | * Return true if the value of this BigNumber is NaN, otherwise return false.
1883 | */
1884 | P.isNaN = function () {
1885 | return !this.s;
1886 | };
1887 |
1888 |
1889 | /*
1890 | * Return true if the value of this BigNumber is negative, otherwise return false.
1891 | */
1892 | P.isNegative = function () {
1893 | return this.s < 0;
1894 | };
1895 |
1896 |
1897 | /*
1898 | * Return true if the value of this BigNumber is positive, otherwise return false.
1899 | */
1900 | P.isPositive = function () {
1901 | return this.s > 0;
1902 | };
1903 |
1904 |
1905 | /*
1906 | * Return true if the value of this BigNumber is 0 or -0, otherwise return false.
1907 | */
1908 | P.isZero = function () {
1909 | return !!this.c && this.c[0] == 0;
1910 | };
1911 |
1912 |
1913 | /*
1914 | * n - 0 = n
1915 | * n - N = N
1916 | * n - I = -I
1917 | * 0 - n = -n
1918 | * 0 - 0 = 0
1919 | * 0 - N = N
1920 | * 0 - I = -I
1921 | * N - n = N
1922 | * N - 0 = N
1923 | * N - N = N
1924 | * N - I = N
1925 | * I - n = I
1926 | * I - 0 = I
1927 | * I - N = N
1928 | * I - I = N
1929 | *
1930 | * Return a new BigNumber whose value is the value of this BigNumber minus the value of
1931 | * BigNumber(y, b).
1932 | */
1933 | P.minus = function (y, b) {
1934 | var i, j, t, xLTy,
1935 | x = this,
1936 | a = x.s;
1937 |
1938 | y = new BigNumber(y, b);
1939 | b = y.s;
1940 |
1941 | // Either NaN?
1942 | if (!a || !b) return new BigNumber(NaN);
1943 |
1944 | // Signs differ?
1945 | if (a != b) {
1946 | y.s = -b;
1947 | return x.plus(y);
1948 | }
1949 |
1950 | var xe = x.e / LOG_BASE,
1951 | ye = y.e / LOG_BASE,
1952 | xc = x.c,
1953 | yc = y.c;
1954 |
1955 | if (!xe || !ye) {
1956 |
1957 | // Either Infinity?
1958 | if (!xc || !yc) return xc ? (y.s = -b, y) : new BigNumber(yc ? x : NaN);
1959 |
1960 | // Either zero?
1961 | if (!xc[0] || !yc[0]) {
1962 |
1963 | // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
1964 | return yc[0] ? (y.s = -b, y) : new BigNumber(xc[0] ? x :
1965 |
1966 | // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
1967 | ROUNDING_MODE == 3 ? -0 : 0);
1968 | }
1969 | }
1970 |
1971 | xe = bitFloor(xe);
1972 | ye = bitFloor(ye);
1973 | xc = xc.slice();
1974 |
1975 | // Determine which is the bigger number.
1976 | if (a = xe - ye) {
1977 |
1978 | if (xLTy = a < 0) {
1979 | a = -a;
1980 | t = xc;
1981 | } else {
1982 | ye = xe;
1983 | t = yc;
1984 | }
1985 |
1986 | t.reverse();
1987 |
1988 | // Prepend zeros to equalise exponents.
1989 | for (b = a; b--; t.push(0));
1990 | t.reverse();
1991 | } else {
1992 |
1993 | // Exponents equal. Check digit by digit.
1994 | j = (xLTy = (a = xc.length) < (b = yc.length)) ? a : b;
1995 |
1996 | for (a = b = 0; b < j; b++) {
1997 |
1998 | if (xc[b] != yc[b]) {
1999 | xLTy = xc[b] < yc[b];
2000 | break;
2001 | }
2002 | }
2003 | }
2004 |
2005 | // x < y? Point xc to the array of the bigger number.
2006 | if (xLTy) t = xc, xc = yc, yc = t, y.s = -y.s;
2007 |
2008 | b = (j = yc.length) - (i = xc.length);
2009 |
2010 | // Append zeros to xc if shorter.
2011 | // No need to add zeros to yc if shorter as subtract only needs to start at yc.length.
2012 | if (b > 0) for (; b--; xc[i++] = 0);
2013 | b = BASE - 1;
2014 |
2015 | // Subtract yc from xc.
2016 | for (; j > a;) {
2017 |
2018 | if (xc[--j] < yc[j]) {
2019 | for (i = j; i && !xc[--i]; xc[i] = b);
2020 | --xc[i];
2021 | xc[j] += BASE;
2022 | }
2023 |
2024 | xc[j] -= yc[j];
2025 | }
2026 |
2027 | // Remove leading zeros and adjust exponent accordingly.
2028 | for (; xc[0] == 0; xc.splice(0, 1), --ye);
2029 |
2030 | // Zero?
2031 | if (!xc[0]) {
2032 |
2033 | // Following IEEE 754 (2008) 6.3,
2034 | // n - n = +0 but n - n = -0 when rounding towards -Infinity.
2035 | y.s = ROUNDING_MODE == 3 ? -1 : 1;
2036 | y.c = [y.e = 0];
2037 | return y;
2038 | }
2039 |
2040 | // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity
2041 | // for finite x and y.
2042 | return normalise(y, xc, ye);
2043 | };
2044 |
2045 |
2046 | /*
2047 | * n % 0 = N
2048 | * n % N = N
2049 | * n % I = n
2050 | * 0 % n = 0
2051 | * -0 % n = -0
2052 | * 0 % 0 = N
2053 | * 0 % N = N
2054 | * 0 % I = 0
2055 | * N % n = N
2056 | * N % 0 = N
2057 | * N % N = N
2058 | * N % I = N
2059 | * I % n = N
2060 | * I % 0 = N
2061 | * I % N = N
2062 | * I % I = N
2063 | *
2064 | * Return a new BigNumber whose value is the value of this BigNumber modulo the value of
2065 | * BigNumber(y, b). The result depends on the value of MODULO_MODE.
2066 | */
2067 | P.modulo = P.mod = function (y, b) {
2068 | var q, s,
2069 | x = this;
2070 |
2071 | y = new BigNumber(y, b);
2072 |
2073 | // Return NaN if x is Infinity or NaN, or y is NaN or zero.
2074 | if (!x.c || !y.s || y.c && !y.c[0]) {
2075 | return new BigNumber(NaN);
2076 |
2077 | // Return x if y is Infinity or x is zero.
2078 | } else if (!y.c || x.c && !x.c[0]) {
2079 | return new BigNumber(x);
2080 | }
2081 |
2082 | if (MODULO_MODE == 9) {
2083 |
2084 | // Euclidian division: q = sign(y) * floor(x / abs(y))
2085 | // r = x - qy where 0 <= r < abs(y)
2086 | s = y.s;
2087 | y.s = 1;
2088 | q = div(x, y, 0, 3);
2089 | y.s = s;
2090 | q.s *= s;
2091 | } else {
2092 | q = div(x, y, 0, MODULO_MODE);
2093 | }
2094 |
2095 | y = x.minus(q.times(y));
2096 |
2097 | // To match JavaScript %, ensure sign of zero is sign of dividend.
2098 | if (!y.c[0] && MODULO_MODE == 1) y.s = x.s;
2099 |
2100 | return y;
2101 | };
2102 |
2103 |
2104 | /*
2105 | * n * 0 = 0
2106 | * n * N = N
2107 | * n * I = I
2108 | * 0 * n = 0
2109 | * 0 * 0 = 0
2110 | * 0 * N = N
2111 | * 0 * I = N
2112 | * N * n = N
2113 | * N * 0 = N
2114 | * N * N = N
2115 | * N * I = N
2116 | * I * n = I
2117 | * I * 0 = N
2118 | * I * N = N
2119 | * I * I = I
2120 | *
2121 | * Return a new BigNumber whose value is the value of this BigNumber multiplied by the value
2122 | * of BigNumber(y, b).
2123 | */
2124 | P.multipliedBy = P.times = function (y, b) {
2125 | var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc,
2126 | base, sqrtBase,
2127 | x = this,
2128 | xc = x.c,
2129 | yc = (y = new BigNumber(y, b)).c;
2130 |
2131 | // Either NaN, ±Infinity or ±0?
2132 | if (!xc || !yc || !xc[0] || !yc[0]) {
2133 |
2134 | // Return NaN if either is NaN, or one is 0 and the other is Infinity.
2135 | if (!x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) {
2136 | y.c = y.e = y.s = null;
2137 | } else {
2138 | y.s *= x.s;
2139 |
2140 | // Return ±Infinity if either is ±Infinity.
2141 | if (!xc || !yc) {
2142 | y.c = y.e = null;
2143 |
2144 | // Return ±0 if either is ±0.
2145 | } else {
2146 | y.c = [0];
2147 | y.e = 0;
2148 | }
2149 | }
2150 |
2151 | return y;
2152 | }
2153 |
2154 | e = bitFloor(x.e / LOG_BASE) + bitFloor(y.e / LOG_BASE);
2155 | y.s *= x.s;
2156 | xcL = xc.length;
2157 | ycL = yc.length;
2158 |
2159 | // Ensure xc points to longer array and xcL to its length.
2160 | if (xcL < ycL) zc = xc, xc = yc, yc = zc, i = xcL, xcL = ycL, ycL = i;
2161 |
2162 | // Initialise the result array with zeros.
2163 | for (i = xcL + ycL, zc = []; i--; zc.push(0));
2164 |
2165 | base = BASE;
2166 | sqrtBase = SQRT_BASE;
2167 |
2168 | for (i = ycL; --i >= 0;) {
2169 | c = 0;
2170 | ylo = yc[i] % sqrtBase;
2171 | yhi = yc[i] / sqrtBase | 0;
2172 |
2173 | for (k = xcL, j = i + k; j > i;) {
2174 | xlo = xc[--k] % sqrtBase;
2175 | xhi = xc[k] / sqrtBase | 0;
2176 | m = yhi * xlo + xhi * ylo;
2177 | xlo = ylo * xlo + ((m % sqrtBase) * sqrtBase) + zc[j] + c;
2178 | c = (xlo / base | 0) + (m / sqrtBase | 0) + yhi * xhi;
2179 | zc[j--] = xlo % base;
2180 | }
2181 |
2182 | zc[j] = c;
2183 | }
2184 |
2185 | if (c) {
2186 | ++e;
2187 | } else {
2188 | zc.splice(0, 1);
2189 | }
2190 |
2191 | return normalise(y, zc, e);
2192 | };
2193 |
2194 |
2195 | /*
2196 | * Return a new BigNumber whose value is the value of this BigNumber negated,
2197 | * i.e. multiplied by -1.
2198 | */
2199 | P.negated = function () {
2200 | var x = new BigNumber(this);
2201 | x.s = -x.s || null;
2202 | return x;
2203 | };
2204 |
2205 |
2206 | /*
2207 | * n + 0 = n
2208 | * n + N = N
2209 | * n + I = I
2210 | * 0 + n = n
2211 | * 0 + 0 = 0
2212 | * 0 + N = N
2213 | * 0 + I = I
2214 | * N + n = N
2215 | * N + 0 = N
2216 | * N + N = N
2217 | * N + I = N
2218 | * I + n = I
2219 | * I + 0 = I
2220 | * I + N = N
2221 | * I + I = I
2222 | *
2223 | * Return a new BigNumber whose value is the value of this BigNumber plus the value of
2224 | * BigNumber(y, b).
2225 | */
2226 | P.plus = function (y, b) {
2227 | var t,
2228 | x = this,
2229 | a = x.s;
2230 |
2231 | y = new BigNumber(y, b);
2232 | b = y.s;
2233 |
2234 | // Either NaN?
2235 | if (!a || !b) return new BigNumber(NaN);
2236 |
2237 | // Signs differ?
2238 | if (a != b) {
2239 | y.s = -b;
2240 | return x.minus(y);
2241 | }
2242 |
2243 | var xe = x.e / LOG_BASE,
2244 | ye = y.e / LOG_BASE,
2245 | xc = x.c,
2246 | yc = y.c;
2247 |
2248 | if (!xe || !ye) {
2249 |
2250 | // Return ±Infinity if either ±Infinity.
2251 | if (!xc || !yc) return new BigNumber(a / 0);
2252 |
2253 | // Either zero?
2254 | // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.
2255 | if (!xc[0] || !yc[0]) return yc[0] ? y : new BigNumber(xc[0] ? x : a * 0);
2256 | }
2257 |
2258 | xe = bitFloor(xe);
2259 | ye = bitFloor(ye);
2260 | xc = xc.slice();
2261 |
2262 | // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts.
2263 | if (a = xe - ye) {
2264 | if (a > 0) {
2265 | ye = xe;
2266 | t = yc;
2267 | } else {
2268 | a = -a;
2269 | t = xc;
2270 | }
2271 |
2272 | t.reverse();
2273 | for (; a--; t.push(0));
2274 | t.reverse();
2275 | }
2276 |
2277 | a = xc.length;
2278 | b = yc.length;
2279 |
2280 | // Point xc to the longer array, and b to the shorter length.
2281 | if (a - b < 0) t = yc, yc = xc, xc = t, b = a;
2282 |
2283 | // Only start adding at yc.length - 1 as the further digits of xc can be ignored.
2284 | for (a = 0; b;) {
2285 | a = (xc[--b] = xc[b] + yc[b] + a) / BASE | 0;
2286 | xc[b] = BASE === xc[b] ? 0 : xc[b] % BASE;
2287 | }
2288 |
2289 | if (a) {
2290 | xc = [a].concat(xc);
2291 | ++ye;
2292 | }
2293 |
2294 | // No need to check for zero, as +x + +y != 0 && -x + -y != 0
2295 | // ye = MAX_EXP + 1 possible
2296 | return normalise(y, xc, ye);
2297 | };
2298 |
2299 |
2300 | /*
2301 | * If sd is undefined or null or true or false, return the number of significant digits of
2302 | * the value of this BigNumber, or null if the value of this BigNumber is ±Infinity or NaN.
2303 | * If sd is true include integer-part trailing zeros in the count.
2304 | *
2305 | * Otherwise, if sd is a number, return a new BigNumber whose value is the value of this
2306 | * BigNumber rounded to a maximum of sd significant digits using rounding mode rm, or
2307 | * ROUNDING_MODE if rm is omitted.
2308 | *
2309 | * sd {number|boolean} number: significant digits: integer, 1 to MAX inclusive.
2310 | * boolean: whether to count integer-part trailing zeros: true or false.
2311 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
2312 | *
2313 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}'
2314 | */
2315 | P.precision = P.sd = function (sd, rm) {
2316 | var c, n, v,
2317 | x = this;
2318 |
2319 | if (sd != null && sd !== !!sd) {
2320 | intCheck(sd, 1, MAX);
2321 | if (rm == null) rm = ROUNDING_MODE;
2322 | else intCheck(rm, 0, 8);
2323 |
2324 | return round(new BigNumber(x), sd, rm);
2325 | }
2326 |
2327 | if (!(c = x.c)) return null;
2328 | v = c.length - 1;
2329 | n = v * LOG_BASE + 1;
2330 |
2331 | if (v = c[v]) {
2332 |
2333 | // Subtract the number of trailing zeros of the last element.
2334 | for (; v % 10 == 0; v /= 10, n--);
2335 |
2336 | // Add the number of digits of the first element.
2337 | for (v = c[0]; v >= 10; v /= 10, n++);
2338 | }
2339 |
2340 | if (sd && x.e + 1 > n) n = x.e + 1;
2341 |
2342 | return n;
2343 | };
2344 |
2345 |
2346 | /*
2347 | * Return a new BigNumber whose value is the value of this BigNumber shifted by k places
2348 | * (powers of 10). Shift to the right if n > 0, and to the left if n < 0.
2349 | *
2350 | * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.
2351 | *
2352 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {k}'
2353 | */
2354 | P.shiftedBy = function (k) {
2355 | intCheck(k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
2356 | return this.times('1e' + k);
2357 | };
2358 |
2359 |
2360 | /*
2361 | * sqrt(-n) = N
2362 | * sqrt(N) = N
2363 | * sqrt(-I) = N
2364 | * sqrt(I) = I
2365 | * sqrt(0) = 0
2366 | * sqrt(-0) = -0
2367 | *
2368 | * Return a new BigNumber whose value is the square root of the value of this BigNumber,
2369 | * rounded according to DECIMAL_PLACES and ROUNDING_MODE.
2370 | */
2371 | P.squareRoot = P.sqrt = function () {
2372 | var m, n, r, rep, t,
2373 | x = this,
2374 | c = x.c,
2375 | s = x.s,
2376 | e = x.e,
2377 | dp = DECIMAL_PLACES + 4,
2378 | half = new BigNumber('0.5');
2379 |
2380 | // Negative/NaN/Infinity/zero?
2381 | if (s !== 1 || !c || !c[0]) {
2382 | return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0);
2383 | }
2384 |
2385 | // Initial estimate.
2386 | s = Math.sqrt(+valueOf(x));
2387 |
2388 | // Math.sqrt underflow/overflow?
2389 | // Pass x to Math.sqrt as integer, then adjust the exponent of the result.
2390 | if (s == 0 || s == 1 / 0) {
2391 | n = coeffToString(c);
2392 | if ((n.length + e) % 2 == 0) n += '0';
2393 | s = Math.sqrt(+n);
2394 | e = bitFloor((e + 1) / 2) - (e < 0 || e % 2);
2395 |
2396 | if (s == 1 / 0) {
2397 | n = '1e' + e;
2398 | } else {
2399 | n = s.toExponential();
2400 | n = n.slice(0, n.indexOf('e') + 1) + e;
2401 | }
2402 |
2403 | r = new BigNumber(n);
2404 | } else {
2405 | r = new BigNumber(s + '');
2406 | }
2407 |
2408 | // Check for zero.
2409 | // r could be zero if MIN_EXP is changed after the this value was created.
2410 | // This would cause a division by zero (x/t) and hence Infinity below, which would cause
2411 | // coeffToString to throw.
2412 | if (r.c[0]) {
2413 | e = r.e;
2414 | s = e + dp;
2415 | if (s < 3) s = 0;
2416 |
2417 | // Newton-Raphson iteration.
2418 | for (; ;) {
2419 | t = r;
2420 | r = half.times(t.plus(div(x, t, dp, 1)));
2421 |
2422 | if (coeffToString(t.c).slice(0, s) === (n = coeffToString(r.c)).slice(0, s)) {
2423 |
2424 | // The exponent of r may here be one less than the final result exponent,
2425 | // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits
2426 | // are indexed correctly.
2427 | if (r.e < e) --s;
2428 | n = n.slice(s - 3, s + 1);
2429 |
2430 | // The 4th rounding digit may be in error by -1 so if the 4 rounding digits
2431 | // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the
2432 | // iteration.
2433 | if (n == '9999' || !rep && n == '4999') {
2434 |
2435 | // On the first iteration only, check to see if rounding up gives the
2436 | // exact result as the nines may infinitely repeat.
2437 | if (!rep) {
2438 | round(t, t.e + DECIMAL_PLACES + 2, 0);
2439 |
2440 | if (t.times(t).eq(x)) {
2441 | r = t;
2442 | break;
2443 | }
2444 | }
2445 |
2446 | dp += 4;
2447 | s += 4;
2448 | rep = 1;
2449 | } else {
2450 |
2451 | // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact
2452 | // result. If not, then there are further digits and m will be truthy.
2453 | if (!+n || !+n.slice(1) && n.charAt(0) == '5') {
2454 |
2455 | // Truncate to the first rounding digit.
2456 | round(r, r.e + DECIMAL_PLACES + 2, 1);
2457 | m = !r.times(r).eq(x);
2458 | }
2459 |
2460 | break;
2461 | }
2462 | }
2463 | }
2464 | }
2465 |
2466 | return round(r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m);
2467 | };
2468 |
2469 |
2470 | /*
2471 | * Return a string representing the value of this BigNumber in exponential notation and
2472 | * rounded using ROUNDING_MODE to dp fixed decimal places.
2473 | *
2474 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
2475 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
2476 | *
2477 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
2478 | */
2479 | P.toExponential = function (dp, rm) {
2480 | if (dp != null) {
2481 | intCheck(dp, 0, MAX);
2482 | dp++;
2483 | }
2484 | return format(this, dp, rm, 1);
2485 | };
2486 |
2487 |
2488 | /*
2489 | * Return a string representing the value of this BigNumber in fixed-point notation rounding
2490 | * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted.
2491 | *
2492 | * Note: as with JavaScript's number type, (-0).toFixed(0) is '0',
2493 | * but e.g. (-0.00001).toFixed(0) is '-0'.
2494 | *
2495 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
2496 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
2497 | *
2498 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
2499 | */
2500 | P.toFixed = function (dp, rm) {
2501 | if (dp != null) {
2502 | intCheck(dp, 0, MAX);
2503 | dp = dp + this.e + 1;
2504 | }
2505 | return format(this, dp, rm);
2506 | };
2507 |
2508 |
2509 | /*
2510 | * Return a string representing the value of this BigNumber in fixed-point notation rounded
2511 | * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties
2512 | * of the format or FORMAT object (see BigNumber.set).
2513 | *
2514 | * The formatting object may contain some or all of the properties shown below.
2515 | *
2516 | * FORMAT = {
2517 | * prefix: '',
2518 | * groupSize: 3,
2519 | * secondaryGroupSize: 0,
2520 | * groupSeparator: ',',
2521 | * decimalSeparator: '.',
2522 | * fractionGroupSize: 0,
2523 | * fractionGroupSeparator: '\xA0', // non-breaking space
2524 | * suffix: ''
2525 | * };
2526 | *
2527 | * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.
2528 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
2529 | * [format] {object} Formatting options. See FORMAT pbject above.
2530 | *
2531 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {dp|rm}'
2532 | * '[BigNumber Error] Argument not an object: {format}'
2533 | */
2534 | P.toFormat = function (dp, rm, format) {
2535 | var str,
2536 | x = this;
2537 |
2538 | if (format == null) {
2539 | if (dp != null && rm && typeof rm == 'object') {
2540 | format = rm;
2541 | rm = null;
2542 | } else if (dp && typeof dp == 'object') {
2543 | format = dp;
2544 | dp = rm = null;
2545 | } else {
2546 | format = FORMAT;
2547 | }
2548 | } else if (typeof format != 'object') {
2549 | throw Error
2550 | (bignumberError + 'Argument not an object: ' + format);
2551 | }
2552 |
2553 | str = x.toFixed(dp, rm);
2554 |
2555 | if (x.c) {
2556 | var i,
2557 | arr = str.split('.'),
2558 | g1 = +format.groupSize,
2559 | g2 = +format.secondaryGroupSize,
2560 | groupSeparator = format.groupSeparator || '',
2561 | intPart = arr[0],
2562 | fractionPart = arr[1],
2563 | isNeg = x.s < 0,
2564 | intDigits = isNeg ? intPart.slice(1) : intPart,
2565 | len = intDigits.length;
2566 |
2567 | if (g2) i = g1, g1 = g2, g2 = i, len -= i;
2568 |
2569 | if (g1 > 0 && len > 0) {
2570 | i = len % g1 || g1;
2571 | intPart = intDigits.substr(0, i);
2572 | for (; i < len; i += g1) intPart += groupSeparator + intDigits.substr(i, g1);
2573 | if (g2 > 0) intPart += groupSeparator + intDigits.slice(i);
2574 | if (isNeg) intPart = '-' + intPart;
2575 | }
2576 |
2577 | str = fractionPart
2578 | ? intPart + (format.decimalSeparator || '') + ((g2 = +format.fractionGroupSize)
2579 | ? fractionPart.replace(new RegExp('\\d{' + g2 + '}\\B', 'g'),
2580 | '$&' + (format.fractionGroupSeparator || ''))
2581 | : fractionPart)
2582 | : intPart;
2583 | }
2584 |
2585 | return (format.prefix || '') + str + (format.suffix || '');
2586 | };
2587 |
2588 |
2589 | /*
2590 | * Return an array of two BigNumbers representing the value of this BigNumber as a simple
2591 | * fraction with an integer numerator and an integer denominator.
2592 | * The denominator will be a positive non-zero value less than or equal to the specified
2593 | * maximum denominator. If a maximum denominator is not specified, the denominator will be
2594 | * the lowest value necessary to represent the number exactly.
2595 | *
2596 | * [md] {number|string|BigNumber} Integer >= 1, or Infinity. The maximum denominator.
2597 | *
2598 | * '[BigNumber Error] Argument {not an integer|out of range} : {md}'
2599 | */
2600 | P.toFraction = function (md) {
2601 | var d, d0, d1, d2, e, exp, n, n0, n1, q, r, s,
2602 | x = this,
2603 | xc = x.c;
2604 |
2605 | if (md != null) {
2606 | n = new BigNumber(md);
2607 |
2608 | // Throw if md is less than one or is not an integer, unless it is Infinity.
2609 | if (!n.isInteger() && (n.c || n.s !== 1) || n.lt(ONE)) {
2610 | throw Error
2611 | (bignumberError + 'Argument ' +
2612 | (n.isInteger() ? 'out of range: ' : 'not an integer: ') + valueOf(n));
2613 | }
2614 | }
2615 |
2616 | if (!xc) return new BigNumber(x);
2617 |
2618 | d = new BigNumber(ONE);
2619 | n1 = d0 = new BigNumber(ONE);
2620 | d1 = n0 = new BigNumber(ONE);
2621 | s = coeffToString(xc);
2622 |
2623 | // Determine initial denominator.
2624 | // d is a power of 10 and the minimum max denominator that specifies the value exactly.
2625 | e = d.e = s.length - x.e - 1;
2626 | d.c[0] = POWS_TEN[(exp = e % LOG_BASE) < 0 ? LOG_BASE + exp : exp];
2627 | md = !md || n.comparedTo(d) > 0 ? (e > 0 ? d : n1) : n;
2628 |
2629 | exp = MAX_EXP;
2630 | MAX_EXP = 1 / 0;
2631 | n = new BigNumber(s);
2632 |
2633 | // n0 = d1 = 0
2634 | n0.c[0] = 0;
2635 |
2636 | for (; ;) {
2637 | q = div(n, d, 0, 1);
2638 | d2 = d0.plus(q.times(d1));
2639 | if (d2.comparedTo(md) == 1) break;
2640 | d0 = d1;
2641 | d1 = d2;
2642 | n1 = n0.plus(q.times(d2 = n1));
2643 | n0 = d2;
2644 | d = n.minus(q.times(d2 = d));
2645 | n = d2;
2646 | }
2647 |
2648 | d2 = div(md.minus(d0), d1, 0, 1);
2649 | n0 = n0.plus(d2.times(n1));
2650 | d0 = d0.plus(d2.times(d1));
2651 | n0.s = n1.s = x.s;
2652 | e = e * 2;
2653 |
2654 | // Determine which fraction is closer to x, n0/d0 or n1/d1
2655 | r = div(n1, d1, e, ROUNDING_MODE).minus(x).abs().comparedTo(
2656 | div(n0, d0, e, ROUNDING_MODE).minus(x).abs()) < 1 ? [n1, d1] : [n0, d0];
2657 |
2658 | MAX_EXP = exp;
2659 |
2660 | return r;
2661 | };
2662 |
2663 |
2664 | /*
2665 | * Return the value of this BigNumber converted to a number primitive.
2666 | */
2667 | P.toNumber = function () {
2668 | return +valueOf(this);
2669 | };
2670 |
2671 |
2672 | /*
2673 | * Return a string representing the value of this BigNumber rounded to sd significant digits
2674 | * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits
2675 | * necessary to represent the integer part of the value in fixed-point notation, then use
2676 | * exponential notation.
2677 | *
2678 | * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.
2679 | * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.
2680 | *
2681 | * '[BigNumber Error] Argument {not a primitive number|not an integer|out of range}: {sd|rm}'
2682 | */
2683 | P.toPrecision = function (sd, rm) {
2684 | if (sd != null) intCheck(sd, 1, MAX);
2685 | return format(this, sd, rm, 2);
2686 | };
2687 |
2688 |
2689 | /*
2690 | * Return a string representing the value of this BigNumber in base b, or base 10 if b is
2691 | * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and
2692 | * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent
2693 | * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than
2694 | * TO_EXP_NEG, return exponential notation.
2695 | *
2696 | * [b] {number} Integer, 2 to ALPHABET.length inclusive.
2697 | *
2698 | * '[BigNumber Error] Base {not a primitive number|not an integer|out of range}: {b}'
2699 | */
2700 | P.toString = function (b) {
2701 | var str,
2702 | n = this,
2703 | s = n.s,
2704 | e = n.e;
2705 |
2706 | // Infinity or NaN?
2707 | if (e === null) {
2708 | if (s) {
2709 | str = 'Infinity';
2710 | if (s < 0) str = '-' + str;
2711 | } else {
2712 | str = 'NaN';
2713 | }
2714 | } else {
2715 | if (b == null) {
2716 | str = e <= TO_EXP_NEG || e >= TO_EXP_POS
2717 | ? toExponential(coeffToString(n.c), e)
2718 | : toFixedPoint(coeffToString(n.c), e, '0');
2719 | } else if (b === 10) {
2720 | n = round(new BigNumber(n), DECIMAL_PLACES + e + 1, ROUNDING_MODE);
2721 | str = toFixedPoint(coeffToString(n.c), n.e, '0');
2722 | } else {
2723 | intCheck(b, 2, ALPHABET.length, 'Base');
2724 | str = convertBase(toFixedPoint(coeffToString(n.c), e, '0'), 10, b, s, true);
2725 | }
2726 |
2727 | if (s < 0 && n.c[0]) str = '-' + str;
2728 | }
2729 |
2730 | return str;
2731 | };
2732 |
2733 |
2734 | /*
2735 | * Return as toString, but do not accept a base argument, and include the minus sign for
2736 | * negative zero.
2737 | */
2738 | P.valueOf = P.toJSON = function () {
2739 | return valueOf(this);
2740 | };
2741 |
2742 |
2743 | P._isBigNumber = true;
2744 |
2745 | P[Symbol.toStringTag] = 'BigNumber';
2746 |
2747 | // Node.js v10.12.0+
2748 | P[Symbol.for('nodejs.util.inspect.custom')] = P.valueOf;
2749 |
2750 | if (configObject != null) BigNumber.set(configObject);
2751 |
2752 | return BigNumber;
2753 | }
2754 |
2755 |
2756 | // PRIVATE HELPER FUNCTIONS
2757 |
2758 | // These functions don't need access to variables,
2759 | // e.g. DECIMAL_PLACES, in the scope of the `clone` function above.
2760 |
2761 |
2762 | function bitFloor(n) {
2763 | var i = n | 0;
2764 | return n > 0 || n === i ? i : i - 1;
2765 | }
2766 |
2767 |
2768 | // Return a coefficient array as a string of base 10 digits.
2769 | function coeffToString(a) {
2770 | var s, z,
2771 | i = 1,
2772 | j = a.length,
2773 | r = a[0] + '';
2774 |
2775 | for (; i < j;) {
2776 | s = a[i++] + '';
2777 | z = LOG_BASE - s.length;
2778 | for (; z--; s = '0' + s);
2779 | r += s;
2780 | }
2781 |
2782 | // Determine trailing zeros.
2783 | for (j = r.length; r.charCodeAt(--j) === 48;);
2784 |
2785 | return r.slice(0, j + 1 || 1);
2786 | }
2787 |
2788 |
2789 | // Compare the value of BigNumbers x and y.
2790 | function compare(x, y) {
2791 | var a, b,
2792 | xc = x.c,
2793 | yc = y.c,
2794 | i = x.s,
2795 | j = y.s,
2796 | k = x.e,
2797 | l = y.e;
2798 |
2799 | // Either NaN?
2800 | if (!i || !j) return null;
2801 |
2802 | a = xc && !xc[0];
2803 | b = yc && !yc[0];
2804 |
2805 | // Either zero?
2806 | if (a || b) return a ? b ? 0 : -j : i;
2807 |
2808 | // Signs differ?
2809 | if (i != j) return i;
2810 |
2811 | a = i < 0;
2812 | b = k == l;
2813 |
2814 | // Either Infinity?
2815 | if (!xc || !yc) return b ? 0 : !xc ^ a ? 1 : -1;
2816 |
2817 | // Compare exponents.
2818 | if (!b) return k > l ^ a ? 1 : -1;
2819 |
2820 | j = (k = xc.length) < (l = yc.length) ? k : l;
2821 |
2822 | // Compare digit by digit.
2823 | for (i = 0; i < j; i++) if (xc[i] != yc[i]) return xc[i] > yc[i] ^ a ? 1 : -1;
2824 |
2825 | // Compare lengths.
2826 | return k == l ? 0 : k > l ^ a ? 1 : -1;
2827 | }
2828 |
2829 |
2830 | /*
2831 | * Check that n is a primitive number, an integer, and in range, otherwise throw.
2832 | */
2833 | function intCheck(n, min, max, name) {
2834 | if (n < min || n > max || n !== mathfloor(n)) {
2835 | throw Error
2836 | (bignumberError + (name || 'Argument') + (typeof n == 'number'
2837 | ? n < min || n > max ? ' out of range: ' : ' not an integer: '
2838 | : ' not a primitive number: ') + String(n));
2839 | }
2840 | }
2841 |
2842 |
2843 | // Assumes finite n.
2844 | function isOdd(n) {
2845 | var k = n.c.length - 1;
2846 | return bitFloor(n.e / LOG_BASE) == k && n.c[k] % 2 != 0;
2847 | }
2848 |
2849 |
2850 | function toExponential(str, e) {
2851 | return (str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str) +
2852 | (e < 0 ? 'e' : 'e+') + e;
2853 | }
2854 |
2855 |
2856 | function toFixedPoint(str, e, z) {
2857 | var len, zs;
2858 |
2859 | // Negative exponent?
2860 | if (e < 0) {
2861 |
2862 | // Prepend zeros.
2863 | for (zs = z + '.'; ++e; zs += z);
2864 | str = zs + str;
2865 |
2866 | // Positive exponent
2867 | } else {
2868 | len = str.length;
2869 |
2870 | // Append zeros.
2871 | if (++e > len) {
2872 | for (zs = z, e -= len; --e; zs += z);
2873 | str += zs;
2874 | } else if (e < len) {
2875 | str = str.slice(0, e) + '.' + str.slice(e);
2876 | }
2877 | }
2878 |
2879 | return str;
2880 | }
2881 |
2882 |
2883 | // EXPORT
2884 |
2885 |
2886 | export var BigNumber = clone();
2887 |
2888 | export default BigNumber;
2889 |
--------------------------------------------------------------------------------
/static/js/coinUnit.js:
--------------------------------------------------------------------------------
1 | import util from './util'
2 |
3 | class coin {
4 | constructor() {
5 | this.unit = "USD"
6 | this.webUnit = ["USD", "CNY", "KRW"]
7 | }
8 |
9 | setUnit(unit) {
10 | if (!this.webUnit.includes(unit)) { unit = "USD" }
11 | util.setCookie("coinUnit", unit, {
12 | expires: 30,
13 | path: '/'
14 | });
15 | this.unit = unit;
16 | return this.unit;
17 | }
18 |
19 | getUnit() {
20 | let unit = util.getCookie("coinUnit");
21 | if (!this.webUnit.includes(unit)) { unit = "USD" };
22 | this.unit = unit;
23 | return this.unit
24 | }
25 | }
26 |
27 |
28 | export default new coin;
--------------------------------------------------------------------------------
/static/js/common.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | export default new Vue()
--------------------------------------------------------------------------------
/static/js/config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | root: process.env.NODE_ENV === 'production' ? '/web' : '',
3 | harmony: {
4 | token: 'ONE',
5 | network: {
6 | blockchain: 'Harmony',
7 | chainId: ''
8 | },
9 | nodes:[
10 | {
11 | name:'Harmony',
12 | url:'https://api.s0.t.hmny.io/',
13 | chainId: 1
14 | },
15 | {
16 | name:'Pangaea',
17 | url:'https://api.s0.pga.hmny.io/',
18 | chainId: 3
19 | },
20 | {
21 | name:'Harmony Testnet',
22 | url:'https://api.s0.b.hmny.io/',
23 | chainId: 2
24 | },
25 | {
26 | name:'Localhost',
27 | url:'http://127.0.0.1:9500',
28 | chainId: 2
29 | }
30 | ]
31 | },
32 | domain: 'http://localhost/'
33 | }
34 |
--------------------------------------------------------------------------------
/static/js/i18n.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import vueI18n from 'vue-i18n'
3 | import util from './util'
4 | Vue.use(vueI18n)
5 |
6 | /*
7 | 设置一下网站支持的语言种类
8 | */
9 | var webLanguage = ['cn', 'en', 'ko'];
10 |
11 | /**
12 | * 获取浏览器语言类型
13 | */
14 | var getNavLanguage = function() {
15 | var navLanguage = (navigator.browserLanguage || navigator.language).toLowerCase();
16 | switch (navLanguage) {
17 | case 'zh-cn' || 'zh-tw' || 'zh-hk':
18 | navLanguage = 'cn';
19 | break;
20 | case 'ko':
21 | navLanguage = 'ko'
22 | break;
23 | default:
24 | navLanguage = 'en';
25 | }
26 | return navLanguage;
27 | }
28 |
29 | let i18n = new vueI18n({
30 | locale: 'en', // 语言标识
31 | //this.$i18n.locale // 通过切换locale的值来实现语言切换
32 | messages: {
33 | 'cn': require('static/lang/cn'),
34 | 'en': require('static/lang/en'),
35 | 'ko': require('static/lang/ko')
36 | }
37 | })
38 |
39 | function isJSON(str) {
40 | if (typeof str == 'string') {
41 | try {
42 | var obj = JSON.parse(str);
43 | if (typeof obj == 'object' && obj) {
44 | return true;
45 | } else {
46 | return false;
47 | }
48 | } catch (e) {
49 | return false;
50 | }
51 | }
52 | console.log('It is not a string!')
53 | }
54 |
55 | i18n.setUserLanguage = function(lang) {
56 | if (isJSON(lang)) {
57 | lang = JSON.parse(lang).language;
58 | }
59 | if (!webLanguage.includes(lang)) {
60 | lang = 'en'
61 | }
62 | util.setCookie("userLanguage", lang, {
63 | expires: 30,
64 | path: '/'
65 | });
66 | i18n.locale = lang;
67 | }
68 |
69 | var cookieLang = util.getCookie('userLanguage') ? util.getCookie('userLanguage') : getNavLanguage();
70 | i18n.setUserLanguage(cookieLang);
71 |
72 | export default i18n
--------------------------------------------------------------------------------
/static/js/util.js:
--------------------------------------------------------------------------------
1 | class Util {
2 | async initMathExtension() {
3 | var tries = 10;
4 | for (var i = 0; i < tries; i++) {
5 | var loaded = await new Promise((resolve, reject) => {
6 | setTimeout(function() {
7 | resolve(typeof window.mathExtension != 'undefined');
8 | }, 100);
9 | });
10 | if (loaded) return window.mathExtension;
11 | }
12 | return false;
13 | }
14 | // 时间戳转换日期 (秒)
15 | timestampToDate(timestamp) {
16 | var date = new Date(timestamp); //时间戳为10位需*1000
17 | var Y = date.getFullYear() + '-';
18 | var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
19 | var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
20 | var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
21 | var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
22 | var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
23 | return Y + M + D + h + m + s;
24 | }
25 |
26 | stringToCapitalize(str) {
27 | var arr = str.toLowerCase().split('_');
28 | arr = arr.map(function(val) {
29 | if (val == 'new') {
30 | val = 'place'
31 | }
32 | val = val.slice(0, 1).toUpperCase() + val.slice(1);
33 | return val
34 | })
35 | return arr.join(' ')
36 | }
37 |
38 | /**
39 | * cookie操作
40 | */
41 | setCookie(name, value, options) {
42 | options = options || {};
43 | if (value === null) {
44 | value = '';
45 | options.expires = -1;
46 | }
47 | var expires = '';
48 | if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
49 | var date;
50 | if (typeof options.expires == 'number') {
51 | date = new Date();
52 | date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
53 | } else {
54 | date = options.expires;
55 | }
56 | expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
57 | }
58 | var path = options.path ? '; path=' + options.path : '';
59 | var domain = options.domain ? '; domain=' + options.domain : '';
60 | var s = [cookie, expires, path, domain, secure].join('');
61 | var secure = options.secure ? '; secure' : '';
62 | var c = [name, '=', encodeURIComponent(value)].join('');
63 | var cookie = [c, expires, path, domain, secure].join('')
64 | document.cookie = cookie;
65 | }
66 |
67 | getCookie(name) {
68 | var cookieValue = null;
69 | if (document.cookie && document.cookie != '') {
70 | var cookies = document.cookie.split(';');
71 | for (var i = 0; i < cookies.length; i++) {
72 | var cookie = cookies[i].trim();
73 | // Does this cookie string begin with the name we want?
74 | if (cookie.substring(0, name.length + 1) == (name + '=')) {
75 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
76 | break;
77 | }
78 | }
79 | }
80 | return cookieValue;
81 | }
82 |
83 | // 数字千分位,保留n位小数格式化
84 | addCommas(nStr, n = 2) {
85 | if (typeof(nStr) == 'string') {
86 | nStr = parseFloat(nStr);
87 | }
88 | if (typeof(nStr) == 'number') {
89 | nStr = nStr.toFixed(n);
90 | }
91 | nStr += '';
92 | let x = nStr.split('.');
93 | let x1 = x[0];
94 | let x2 = x.length > 1 ? '.' + x[1] : '';
95 | let rgx = /(\d+)(\d{3})/;
96 | while (rgx.test(x1)) {
97 | x1 = x1.replace(rgx, '$1' + ',' + '$2');
98 | }
99 | return x1 + x2;
100 | }
101 |
102 | getFullNum(num) {
103 | //处理非数字
104 | if (isNaN(num)) { return num };
105 |
106 | //处理不需要转换的数字
107 | var str = '' + num;
108 | if (!/e/i.test(str)) { return num; };
109 |
110 | return (num).toFixed(18).replace(/\.?0+$/, "");
111 | }
112 |
113 | // 拉取代币价格
114 | async getTokenPrice(nodeUrl, alias, type){
115 |
116 | let response = {};
117 | let url = nodeUrl +'api/tokenListPub?type='+type;
118 | $.ajax({
119 | url : url,
120 | type : "get",
121 | data : {},
122 | async : false,
123 | success : function(res) {
124 | let result = JSON.parse(res);
125 | response = result.data;
126 | }
127 | });
128 | return Util.findToken(response, alias);
129 | }
130 | //查找 token返回
131 | static findToken(tokens, alias){
132 | for (let i=0; i{
154 | if (coin.alias == 'CNY'){
155 | coins.cny = coin.rmb;
156 | }
157 | if (coin.alias == 'USD'){
158 | coins.usd = coin.rmb;
159 | }
160 | if (coin.alias == 'KRW'){
161 | coins.krw = coin.rmb;
162 | }
163 | });
164 | }
165 | }
166 | });
167 | return coins;
168 | }
169 |
170 | setSession(key, value){
171 | value = JSON.stringify(value);
172 | sessionStorage.setItem(key, value);
173 | }
174 |
175 | getSession(key){
176 | if (key == "") return "";
177 | let value = sessionStorage.getItem(key);
178 | if (value == ""){
179 | return "";
180 | }
181 | return value;
182 | }
183 |
184 | delSession(key){
185 | if (key){
186 | sessionStorage.removeItem(key);
187 | }
188 | }
189 | }
190 |
191 | let util = new Util;
192 |
193 | export default util;
194 |
--------------------------------------------------------------------------------
/static/lang/cn.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lang: '中文',
3 | webwallet_mobile_app: 'APP',
4 | webwallet_your: '你的',
5 | webwallet_wallet: '钱包',
6 | webwallet_home_des1: '直接从区块链钱包发送,请求和交换',
7 | webwallet_home_des2: '',
8 | webwallet_login: '通过 Math Wallet 浏览器扩展程序登录',
9 | webwallet_copy_address: '复制地址',
10 | webwallet_qr_code: '二维码',
11 | webwallet_estimated_value: '估值',
12 | webwallet_total: '总计',
13 | webwallet_refresh: '刷新',
14 | webwallet_logout: '退出',
15 | webwallet_transactions: '交易记录',
16 | webwallet_erc20_transactions: 'Erc20代币交易',
17 | webwallet_to_address: '接收地址',
18 | webwallet_to_address_pl: '请填写钱包地址',
19 | webwallet_cheap: '慢',
20 | webwallet_fast: '快',
21 | webwallet_simple: '简单设置',
22 | webwallet_advanced: '高级设置',
23 | webwallet_memo_pl: '最多30个字符(可选)',
24 | webwallet_fee: '手续费',
25 | webwallet_txHash: '交易单号',
26 | webwallet_type: '类型',
27 | webwallet_value: '数量',
28 | webwallet_status: '交易状态',
29 | webwallet_block_height: '区块高度',
30 | webwallet_tx_time: '交易时间',
31 | webwallet_refresh_balance: '刷新余额',
32 | transaction_information: '交易详情',
33 | available: '可用',
34 | delegate: '已委托',
35 | undelegate: '解委托',
36 | transfer: '转账',
37 | transfer_amount: '转账金额',
38 | memo: '备注',
39 | noTransaction: '暂无任何交易记录',
40 | noMathExtension: '请先连接麦子钱包扩展程序',
41 | from: '发送方',
42 | to: '接收方',
43 | transfer_account_null: '请填写收款地址',
44 | transfer_amount_null: '请填写转账金额',
45 | copy_success: '复制成功',
46 | copy_fail: '请手动复制',
47 | transfer_success: '转账成功',
48 | transfer_fail: '转账失败',
49 | transfer_amount_min: '转账金额不能低于 ',
50 | back_transactions: '返回交易记录',
51 | gas_limit: 'Gas Limit',
52 | gas_used: 'Gas Used',
53 | gas_price: 'Gas Price',
54 | mathExtensionLock: '请解锁您的麦子钱包',
55 | contract: '合约',
56 | TRC20_transfer: 'TRC20 转账',
57 | check_account: '插件选择的账户和当前账户不一致',
58 | gas_price_min: 'Gas Price不能低于1Gwei',
59 | gas_limit_min: 'Gas Limit不能低于',
60 | prompt: '提示',
61 | input_data: '输入数据',
62 | transfer_input: '请输入十六进制数据(可选)',
63 | locked: '锁定',
64 | submit_success: '提交成功',
65 | gas_limit_null: 'Gas Limit不能为空',
66 | gas_Price_null: 'Gas Price不能为空',
67 | webwallet_harmony_amount_notenough: '可用余额不足',
68 | node_not_available: '当前节点不可用',
69 | webwallet_extrinsicID: '交易ID',
70 | webwallet_module: '模块',
71 | webwallet_signature: '签名',
72 | webwallet_address: '地址',
73 | webwallet_transfers: '转账记录',
74 | noTransfer: '暂无任何转账记录',
75 | Confirm: '确认'
76 | }
77 |
--------------------------------------------------------------------------------
/static/lang/en.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lang: 'English',
3 | webwallet_mobile_app: 'APP',
4 | webwallet_your: 'Your',
5 | webwallet_wallet: 'Wallet',
6 | webwallet_home_des1: 'Send, Request and Swap',
7 | webwallet_home_des2: 'directly from your Blockchain Wallet.',
8 | webwallet_login: 'Login via Math Wallet Browser Extension',
9 | webwallet_copy_address: 'Copy Address',
10 | webwallet_qr_code: 'QR Code',
11 | webwallet_estimated_value: 'Estimated Value',
12 | webwallet_total: 'Total',
13 | webwallet_refresh: 'Refresh',
14 | webwallet_logout: 'Logout',
15 | webwallet_transactions: 'Transactions',
16 | webwallet_erc20_transactions: 'Erc20 Token Txns',
17 | webwallet_to_address: 'To Address',
18 | webwallet_to_address_pl: 'Recipient Address',
19 | webwallet_cheap: 'Cheap',
20 | webwallet_fast: 'Fast',
21 | webwallet_simple: 'Simple',
22 | webwallet_advanced: 'Advanced',
23 | webwallet_memo_pl: 'Maximum 30 characters (optional)',
24 | webwallet_fee: 'Fee',
25 | webwallet_txHash: 'TxHash',
26 | webwallet_type: 'Type',
27 | webwallet_value: 'Value',
28 | webwallet_status: 'Status',
29 | webwallet_block_height: 'Block Height',
30 | webwallet_tx_time: 'Tx Time',
31 | webwallet_refresh_balance: 'Refresh Balance',
32 | transaction_information: 'Transaction Information',
33 | available: 'Available',
34 | delegate: 'Delegated',
35 | undelegate: 'Undelegating',
36 | transfer: 'Transfer',
37 | transfer_amount: 'Transfer Amount',
38 | memo: 'Memo',
39 | noTransaction: 'No transaction',
40 | noMathExtension: 'Please connect Math Wallet first',
41 | from: 'From',
42 | to: 'To',
43 | transfer_account_null: 'Please enter receive address',
44 | transfer_amount_null: 'Please set transfer amount',
45 | copy_success: 'Copied',
46 | copy_fail: 'Please copy manually',
47 | transfer_success: 'Transferred',
48 | transfer_fail: 'Transfer failed',
49 | transfer_amount_min: 'The transfer amount cannot be lower than ',
50 | back_transactions: 'Back to Transaction Record',
51 | gas_limit: 'Gas Limit',
52 | gas_used: 'Gas Used',
53 | gas_price: 'Gas Price',
54 | mathExtensionLock: 'Please unlock your Math Wallet',
55 | contract: 'Contract',
56 | TRC20_transfer: 'TRC20 Transfers',
57 | check_account: 'The current account is not the account selected by extension',
58 | gas_price_min: 'Gas Price cannot be lower than 1Gwei',
59 | gas_limit_min: 'Gas Limit cannot be lower than ',
60 | prompt: 'Prompt',
61 | input_data: 'Input Data',
62 | transfer_input: 'Please enter hexadecimal data (optional)',
63 | locked: 'Locked',
64 | submit_success: 'Submit success',
65 | gas_limit_null: 'Gas Limit is null',
66 | gas_Price_null: 'Gas Price is null',
67 | webwallet_harmony_amount_notenough: 'Have no enough available balance',
68 | node_not_available: 'Current node is not available',
69 | webwallet_extrinsicID: 'Extrinsic ID',
70 | webwallet_module: 'Module',
71 | webwallet_signature: 'Signature',
72 | webwallet_address: 'Address',
73 | webwallet_transfers: 'Transfers',
74 | noTransfer: 'No transfer',
75 | Confirm: 'Confirm'
76 | }
77 |
--------------------------------------------------------------------------------
/static/lang/ko.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | lang: '한국어',
3 | webwallet_mobile_app: 'APP',
4 | webwallet_your: '당신의',
5 | webwallet_wallet: '지갑',
6 | webwallet_home_des1: '블록체인 지갑에서 직접 발송, 요청 및 교환',
7 | webwallet_home_des2: '',
8 | webwallet_login: 'Math Wallet 브라우저를 통해 로그인',
9 | webwallet_copy_address: '주소 복사',
10 | webwallet_qr_code: 'QR코드',
11 | webwallet_estimated_value: 'Estimated Value',
12 | webwallet_total: 'Total',
13 | webwallet_refresh: 'Refresh',
14 | webwallet_logout: 'Logout',
15 | webwallet_transactions: '거래 기록',
16 | webwallet_erc20_transactions: 'Erc20 토큰 거래',
17 | webwallet_to_address: '접수 주소',
18 | webwallet_to_address_pl: '지갑 주소 입력',
19 | webwallet_cheap: 'Cheap',
20 | webwallet_fast: 'Fast',
21 | webwallet_simple: '기분 설치',
22 | webwallet_advanced: '고급 설치',
23 | webwallet_memo_pl: '최대한 30개자(필수 아님)',
24 | webwallet_fee: '수수료',
25 | webwallet_txHash: '거래 번호',
26 | webwallet_type: '종류',
27 | webwallet_value: '수량',
28 | webwallet_status: '거래 상태',
29 | webwallet_block_height: 'Block Height',
30 | webwallet_tx_time: '거래 시간',
31 | webwallet_refresh_balance: '잔액을 새로 고침 하다',
32 | transaction_information: '거래 내역',
33 | available: 'Available',
34 | delegate: 'Delegated',
35 | undelegate: 'Undelegating',
36 | transfer: '이체',
37 | transfer_amount: '이체 금액',
38 | memo: '비고',
39 | noTransaction: '거래 기록이 없습니다',
40 | noMathExtension: 'Math Wallet 브라우저를 접속하세요',
41 | from: '발송자',
42 | to: '접수자',
43 | transfer_account_null: '입금 주소를 입력하세요',
44 | transfer_amount_null: '금액을 입력하세요',
45 | copy_success: '복사 완료',
46 | copy_fail: '복사하세요',
47 | transfer_success: '이체 완료',
48 | transfer_fail: '이체 실패',
49 | transfer_amount_min: '이체 금액이 최소한 ',
50 | back_transactions: '거래 기록으로 돌아가기',
51 | gas_limit: 'Gas Limit',
52 | gas_used: 'Gas Used',
53 | gas_price: 'Gas Price',
54 | contract: '컨트랙트',
55 | mathExtensionLock: 'Math Wallet unlock',
56 | TRC20_transfer: 'TRC20 이체',
57 | check_account: '선택된 계정과 현재 계정이 일치하지 않음',
58 | gas_price_min: 'Gas Price 최소한 1Gwei',
59 | gas_limit_min: 'Gas Limit 최소한',
60 | prompt: 'Prompt',
61 | input_data: '데이터 입력',
62 | transfer_input: '16진수 데이터 입력(필수 아님)',
63 | locked: 'Locked',
64 | submit_success: '제출 완료',
65 | gas_limit_null: 'Gas Limit is null',
66 | gas_Price_null: 'Gas Price is null',
67 | webwallet_harmony_amount_notenough: ' 잔액이 부족합니다',
68 | node_not_available: '유효하지 않은 노드',
69 | webwallet_extrinsicID: '거래ID',
70 | webwallet_module: '모듈',
71 | webwallet_signature: '사인',
72 | webwallet_address: '주소',
73 | webwallet_transfers: '이체 기록',
74 | noTransfer: '이체 기록이 없습니다',
75 | Confirm: 'Confirm'
76 | }
77 |
--------------------------------------------------------------------------------